diff options
Diffstat (limited to 'src/Wallabag/CoreBundle/Event')
7 files changed, 375 insertions, 0 deletions
diff --git a/src/Wallabag/CoreBundle/Event/EntryDeletedEvent.php b/src/Wallabag/CoreBundle/Event/EntryDeletedEvent.php new file mode 100644 index 00000000..e9061d04 --- /dev/null +++ b/src/Wallabag/CoreBundle/Event/EntryDeletedEvent.php | |||
@@ -0,0 +1,26 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Event; | ||
4 | |||
5 | use Symfony\Component\EventDispatcher\Event; | ||
6 | use Wallabag\CoreBundle\Entity\Entry; | ||
7 | |||
8 | /** | ||
9 | * This event is fired as soon as an entry is deleted. | ||
10 | */ | ||
11 | class EntryDeletedEvent extends Event | ||
12 | { | ||
13 | const NAME = 'entry.deleted'; | ||
14 | |||
15 | protected $entry; | ||
16 | |||
17 | public function __construct(Entry $entry) | ||
18 | { | ||
19 | $this->entry = $entry; | ||
20 | } | ||
21 | |||
22 | public function getEntry() | ||
23 | { | ||
24 | return $this->entry; | ||
25 | } | ||
26 | } | ||
diff --git a/src/Wallabag/CoreBundle/Event/EntrySavedEvent.php b/src/Wallabag/CoreBundle/Event/EntrySavedEvent.php new file mode 100644 index 00000000..5fdb5221 --- /dev/null +++ b/src/Wallabag/CoreBundle/Event/EntrySavedEvent.php | |||
@@ -0,0 +1,26 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Event; | ||
4 | |||
5 | use Symfony\Component\EventDispatcher\Event; | ||
6 | use Wallabag\CoreBundle\Entity\Entry; | ||
7 | |||
8 | /** | ||
9 | * This event is fired as soon as an entry was saved. | ||
10 | */ | ||
11 | class EntrySavedEvent extends Event | ||
12 | { | ||
13 | const NAME = 'entry.saved'; | ||
14 | |||
15 | protected $entry; | ||
16 | |||
17 | public function __construct(Entry $entry) | ||
18 | { | ||
19 | $this->entry = $entry; | ||
20 | } | ||
21 | |||
22 | public function getEntry() | ||
23 | { | ||
24 | return $this->entry; | ||
25 | } | ||
26 | } | ||
diff --git a/src/Wallabag/CoreBundle/Event/Listener/LocaleListener.php b/src/Wallabag/CoreBundle/Event/Listener/LocaleListener.php new file mode 100644 index 00000000..b435d99e --- /dev/null +++ b/src/Wallabag/CoreBundle/Event/Listener/LocaleListener.php | |||
@@ -0,0 +1,44 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Event\Listener; | ||
4 | |||
5 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||
6 | use Symfony\Component\HttpKernel\Event\GetResponseEvent; | ||
7 | use Symfony\Component\HttpKernel\KernelEvents; | ||
8 | |||
9 | /** | ||
10 | * @see http://symfony.com/doc/current/cookbook/session/locale_sticky_session.html | ||
11 | */ | ||
12 | class LocaleListener implements EventSubscriberInterface | ||
13 | { | ||
14 | private $defaultLocale; | ||
15 | |||
16 | public function __construct($defaultLocale = 'en') | ||
17 | { | ||
18 | $this->defaultLocale = $defaultLocale; | ||
19 | } | ||
20 | |||
21 | public function onKernelRequest(GetResponseEvent $event) | ||
22 | { | ||
23 | $request = $event->getRequest(); | ||
24 | if (!$request->hasPreviousSession()) { | ||
25 | return; | ||
26 | } | ||
27 | |||
28 | // try to see if the locale has been set as a _locale routing parameter | ||
29 | if ($locale = $request->attributes->get('_locale')) { | ||
30 | $request->getSession()->set('_locale', $locale); | ||
31 | } else { | ||
32 | // if no explicit locale has been set on this request, use one from the session | ||
33 | $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale)); | ||
34 | } | ||
35 | } | ||
36 | |||
37 | public static function getSubscribedEvents() | ||
38 | { | ||
39 | return [ | ||
40 | // must be registered before the default Locale listener | ||
41 | KernelEvents::REQUEST => [['onKernelRequest', 17]], | ||
42 | ]; | ||
43 | } | ||
44 | } | ||
diff --git a/src/Wallabag/CoreBundle/Event/Listener/UserLocaleListener.php b/src/Wallabag/CoreBundle/Event/Listener/UserLocaleListener.php new file mode 100644 index 00000000..367cdfb0 --- /dev/null +++ b/src/Wallabag/CoreBundle/Event/Listener/UserLocaleListener.php | |||
@@ -0,0 +1,37 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Event\Listener; | ||
4 | |||
5 | use Symfony\Component\HttpFoundation\Session\Session; | ||
6 | use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; | ||
7 | |||
8 | /** | ||
9 | * Stores the locale of the user in the session after the | ||
10 | * login. This can be used by the LocaleListener afterwards. | ||
11 | * | ||
12 | * @see http://symfony.com/doc/master/cookbook/session/locale_sticky_session.html | ||
13 | */ | ||
14 | class UserLocaleListener | ||
15 | { | ||
16 | /** | ||
17 | * @var Session | ||
18 | */ | ||
19 | private $session; | ||
20 | |||
21 | public function __construct(Session $session) | ||
22 | { | ||
23 | $this->session = $session; | ||
24 | } | ||
25 | |||
26 | /** | ||
27 | * @param InteractiveLoginEvent $event | ||
28 | */ | ||
29 | public function onInteractiveLogin(InteractiveLoginEvent $event) | ||
30 | { | ||
31 | $user = $event->getAuthenticationToken()->getUser(); | ||
32 | |||
33 | if (null !== $user->getConfig()->getLanguage()) { | ||
34 | $this->session->set('_locale', $user->getConfig()->getLanguage()); | ||
35 | } | ||
36 | } | ||
37 | } | ||
diff --git a/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php new file mode 100644 index 00000000..4ebe837b --- /dev/null +++ b/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php | |||
@@ -0,0 +1,121 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Event\Subscriber; | ||
4 | |||
5 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||
6 | use Psr\Log\LoggerInterface; | ||
7 | use Wallabag\CoreBundle\Helper\DownloadImages; | ||
8 | use Wallabag\CoreBundle\Entity\Entry; | ||
9 | use Wallabag\CoreBundle\Event\EntrySavedEvent; | ||
10 | use Wallabag\CoreBundle\Event\EntryDeletedEvent; | ||
11 | use Doctrine\ORM\EntityManager; | ||
12 | |||
13 | class DownloadImagesSubscriber implements EventSubscriberInterface | ||
14 | { | ||
15 | private $em; | ||
16 | private $downloadImages; | ||
17 | private $enabled; | ||
18 | private $logger; | ||
19 | |||
20 | public function __construct(EntityManager $em, DownloadImages $downloadImages, $enabled, LoggerInterface $logger) | ||
21 | { | ||
22 | $this->em = $em; | ||
23 | $this->downloadImages = $downloadImages; | ||
24 | $this->enabled = $enabled; | ||
25 | $this->logger = $logger; | ||
26 | } | ||
27 | |||
28 | public static function getSubscribedEvents() | ||
29 | { | ||
30 | return [ | ||
31 | EntrySavedEvent::NAME => 'onEntrySaved', | ||
32 | EntryDeletedEvent::NAME => 'onEntryDeleted', | ||
33 | ]; | ||
34 | } | ||
35 | |||
36 | /** | ||
37 | * Download images and updated the data into the entry. | ||
38 | * | ||
39 | * @param EntrySavedEvent $event | ||
40 | */ | ||
41 | public function onEntrySaved(EntrySavedEvent $event) | ||
42 | { | ||
43 | if (!$this->enabled) { | ||
44 | $this->logger->debug('DownloadImagesSubscriber: disabled.'); | ||
45 | |||
46 | return; | ||
47 | } | ||
48 | |||
49 | $entry = $event->getEntry(); | ||
50 | |||
51 | $html = $this->downloadImages($entry); | ||
52 | if (false !== $html) { | ||
53 | $this->logger->debug('DownloadImagesSubscriber: updated html.'); | ||
54 | |||
55 | $entry->setContent($html); | ||
56 | } | ||
57 | |||
58 | // update preview picture | ||
59 | $previewPicture = $this->downloadPreviewImage($entry); | ||
60 | if (false !== $previewPicture) { | ||
61 | $this->logger->debug('DownloadImagesSubscriber: update preview picture.'); | ||
62 | |||
63 | $entry->setPreviewPicture($previewPicture); | ||
64 | } | ||
65 | |||
66 | $this->em->persist($entry); | ||
67 | $this->em->flush(); | ||
68 | } | ||
69 | |||
70 | /** | ||
71 | * Remove images related to the entry. | ||
72 | * | ||
73 | * @param EntryDeletedEvent $event | ||
74 | */ | ||
75 | public function onEntryDeleted(EntryDeletedEvent $event) | ||
76 | { | ||
77 | if (!$this->enabled) { | ||
78 | $this->logger->debug('DownloadImagesSubscriber: disabled.'); | ||
79 | |||
80 | return; | ||
81 | } | ||
82 | |||
83 | $this->downloadImages->removeImages($event->getEntry()->getId()); | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * Download all images from the html. | ||
88 | * | ||
89 | * @todo If we want to add async download, it should be done in that method | ||
90 | * | ||
91 | * @param Entry $entry | ||
92 | * | ||
93 | * @return string|false False in case of async | ||
94 | */ | ||
95 | private function downloadImages(Entry $entry) | ||
96 | { | ||
97 | return $this->downloadImages->processHtml( | ||
98 | $entry->getId(), | ||
99 | $entry->getContent(), | ||
100 | $entry->getUrl() | ||
101 | ); | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * Download the preview picture. | ||
106 | * | ||
107 | * @todo If we want to add async download, it should be done in that method | ||
108 | * | ||
109 | * @param Entry $entry | ||
110 | * | ||
111 | * @return string|false False in case of async | ||
112 | */ | ||
113 | private function downloadPreviewImage(Entry $entry) | ||
114 | { | ||
115 | return $this->downloadImages->processSingleImage( | ||
116 | $entry->getId(), | ||
117 | $entry->getPreviewPicture(), | ||
118 | $entry->getUrl() | ||
119 | ); | ||
120 | } | ||
121 | } | ||
diff --git a/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php new file mode 100644 index 00000000..3b4c4cf9 --- /dev/null +++ b/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php | |||
@@ -0,0 +1,70 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Event\Subscriber; | ||
4 | |||
5 | use Doctrine\Common\EventSubscriber; | ||
6 | use Doctrine\ORM\Event\LifecycleEventArgs; | ||
7 | use Wallabag\CoreBundle\Entity\Entry; | ||
8 | use 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 | */ | ||
17 | class 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 | } | ||
diff --git a/src/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriber.php new file mode 100644 index 00000000..711c3bf8 --- /dev/null +++ b/src/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriber.php | |||
@@ -0,0 +1,51 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Event\Subscriber; | ||
4 | |||
5 | use Doctrine\Common\EventSubscriber; | ||
6 | use Doctrine\ORM\Event\LoadClassMetadataEventArgs; | ||
7 | use Doctrine\ORM\Mapping\ClassMetadataInfo; | ||
8 | |||
9 | /** | ||
10 | * Puts a prefix to each table. | ||
11 | * This way were used instead of using the built-in strategy from Doctrine, using `naming_strategy` | ||
12 | * Because it conflicts with the DefaultQuoteStrategy (that espace table name, like user for Postgres) | ||
13 | * see #1498 for more detail. | ||
14 | * | ||
15 | * Solution from : | ||
16 | * - http://stackoverflow.com/a/23860613/569101 | ||
17 | * - http://doctrine-orm.readthedocs.org/en/latest/reference/namingstrategy.html | ||
18 | */ | ||
19 | class TablePrefixSubscriber implements EventSubscriber | ||
20 | { | ||
21 | protected $prefix = ''; | ||
22 | |||
23 | public function __construct($prefix) | ||
24 | { | ||
25 | $this->prefix = (string) $prefix; | ||
26 | } | ||
27 | |||
28 | public function getSubscribedEvents() | ||
29 | { | ||
30 | return ['loadClassMetadata']; | ||
31 | } | ||
32 | |||
33 | public function loadClassMetadata(LoadClassMetadataEventArgs $args) | ||
34 | { | ||
35 | $classMetadata = $args->getClassMetadata(); | ||
36 | |||
37 | // if we are in an inheritance hierarchy, only apply this once | ||
38 | if ($classMetadata->isInheritanceTypeSingleTable() && !$classMetadata->isRootEntity()) { | ||
39 | return; | ||
40 | } | ||
41 | |||
42 | $classMetadata->setPrimaryTable(['name' => $this->prefix.$classMetadata->getTableName()]); | ||
43 | |||
44 | foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) { | ||
45 | if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && isset($classMetadata->associationMappings[$fieldName]['joinTable']['name'])) { | ||
46 | $mappedTableName = $classMetadata->associationMappings[$fieldName]['joinTable']['name']; | ||
47 | $classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix.$mappedTableName; | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | } | ||