aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag')
-rw-r--r--src/Wallabag/ApiBundle/Controller/EntryRestController.php35
-rw-r--r--src/Wallabag/CoreBundle/Controller/EntryController.php10
-rw-r--r--src/Wallabag/CoreBundle/Controller/TagController.php7
-rw-r--r--src/Wallabag/CoreBundle/Entity/Change.php86
-rw-r--r--src/Wallabag/CoreBundle/Entity/Entry.php6
-rw-r--r--src/Wallabag/CoreBundle/Event/EntryTaggedEvent.php42
-rw-r--r--src/Wallabag/CoreBundle/Event/EntryUpdatedEvent.php26
-rw-r--r--src/Wallabag/CoreBundle/Event/Subscriber/ChangesSubscriber.php59
-rw-r--r--src/Wallabag/CoreBundle/Repository/ChangeRepository.php26
-rw-r--r--src/Wallabag/CoreBundle/Resources/config/services.yml8
10 files changed, 298 insertions, 7 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
index 31bb67fd..2cf562bc 100644
--- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
@@ -12,7 +12,8 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
12use Wallabag\CoreBundle\Entity\Entry; 12use Wallabag\CoreBundle\Entity\Entry;
13use Wallabag\CoreBundle\Entity\Tag; 13use Wallabag\CoreBundle\Entity\Tag;
14use Wallabag\CoreBundle\Event\EntrySavedEvent; 14use Wallabag\CoreBundle\Event\EntrySavedEvent;
15use Wallabag\CoreBundle\Event\EntryDeletedEvent; 15use Wallabag\CoreBundle\Event\EntryTaggedEvent;
16use Wallabag\CoreBundle\Event\EntryUpdatedEvent;
16 17
17class EntryRestController extends WallabagRestController 18class EntryRestController extends WallabagRestController
18{ 19{
@@ -385,6 +386,8 @@ class EntryRestController extends WallabagRestController
385 $em = $this->getDoctrine()->getManager(); 386 $em = $this->getDoctrine()->getManager();
386 $em->flush(); 387 $em->flush();
387 388
389 $this->get('event_dispatcher')->dispatch(EntryUpdatedEvent::NAME, new EntryUpdatedEvent($entry));
390
388 return $this->sendResponse($entry); 391 return $this->sendResponse($entry);
389 } 392 }
390 393
@@ -426,6 +429,7 @@ class EntryRestController extends WallabagRestController
426 $em->flush(); 429 $em->flush();
427 430
428 // entry saved, dispatch event about it! 431 // entry saved, dispatch event about it!
432 $this->get('event_dispatcher')->dispatch(EntryUpdatedEvent::NAME, new EntryUpdatedEvent($entry));
429 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); 433 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
430 434
431 return $this->sendResponse($entry); 435 return $this->sendResponse($entry);
@@ -496,14 +500,17 @@ class EntryRestController extends WallabagRestController
496 $this->validateUserAccess($entry->getUser()->getId()); 500 $this->validateUserAccess($entry->getUser()->getId());
497 501
498 $tags = $request->request->get('tags', ''); 502 $tags = $request->request->get('tags', '');
503 $tagsEntries = [];
499 if (!empty($tags)) { 504 if (!empty($tags)) {
500 $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags); 505 $tagsEntries = $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags);
501 } 506 }
502 507
503 $em = $this->getDoctrine()->getManager(); 508 $em = $this->getDoctrine()->getManager();
504 $em->persist($entry); 509 $em->persist($entry);
505 $em->flush(); 510 $em->flush();
506 511
512 $this->get('event_dispatcher')->dispatch(EntryTaggedEvent::NAME, new EntryTaggedEvent($entry, $tagsEntries));
513
507 return $this->sendResponse($entry); 514 return $this->sendResponse($entry);
508 } 515 }
509 516
@@ -650,4 +657,28 @@ class EntryRestController extends WallabagRestController
650 657
651 return (new JsonResponse())->setJson($json); 658 return (new JsonResponse())->setJson($json);
652 } 659 }
660
661 /**
662 * Gets history since a date.
663 *
664 * @ApiDoc(
665 * parameters={
666 * {"name"="since", "dataType"="integer", "required"=true, "format"="A timestamp", "description"="Timestamp of the history's start"},
667 * }
668 * )
669 *
670 * @return JsonResponse
671 */
672 public function getEntriesHistoryAction(Request $request)
673 {
674 $this->validateAuthentication();
675
676 $res = $this->getDoctrine()
677 ->getRepository('WallabagCoreBundle:Change')
678 ->findChangesSinceDate($request->query->get('since'));
679
680 $json = $this->get('serializer')->serialize($res, 'json');
681
682 return (new JsonResponse())->setJson($json);
683 }
653} 684}
diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php
index 8d2ac6d4..2a287825 100644
--- a/src/Wallabag/CoreBundle/Controller/EntryController.php
+++ b/src/Wallabag/CoreBundle/Controller/EntryController.php
@@ -9,12 +9,12 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
9use Symfony\Component\HttpFoundation\Request; 9use Symfony\Component\HttpFoundation\Request;
10use Symfony\Component\Routing\Generator\UrlGeneratorInterface; 10use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
11use Wallabag\CoreBundle\Entity\Entry; 11use Wallabag\CoreBundle\Entity\Entry;
12use Wallabag\CoreBundle\Event\EntryUpdatedEvent;
12use Wallabag\CoreBundle\Form\Type\EntryFilterType; 13use Wallabag\CoreBundle\Form\Type\EntryFilterType;
13use Wallabag\CoreBundle\Form\Type\EditEntryType; 14use Wallabag\CoreBundle\Form\Type\EditEntryType;
14use Wallabag\CoreBundle\Form\Type\NewEntryType; 15use Wallabag\CoreBundle\Form\Type\NewEntryType;
15use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; 16use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
16use Wallabag\CoreBundle\Event\EntrySavedEvent; 17use Wallabag\CoreBundle\Event\EntrySavedEvent;
17use Wallabag\CoreBundle\Event\EntryDeletedEvent;
18use Wallabag\CoreBundle\Form\Type\SearchEntryType; 18use Wallabag\CoreBundle\Form\Type\SearchEntryType;
19 19
20class EntryController extends Controller 20class EntryController extends Controller
@@ -391,6 +391,7 @@ class EntryController extends Controller
391 $em->flush(); 391 $em->flush();
392 392
393 // entry saved, dispatch event about it! 393 // entry saved, dispatch event about it!
394 $this->get('event_dispatcher')->dispatch(EntryUpdatedEvent::NAME, new EntryUpdatedEvent($entry));
394 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); 395 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
395 396
396 return $this->redirect($this->generateUrl('view', ['id' => $entry->getId()])); 397 return $this->redirect($this->generateUrl('view', ['id' => $entry->getId()]));
@@ -413,6 +414,8 @@ class EntryController extends Controller
413 $entry->toggleArchive(); 414 $entry->toggleArchive();
414 $this->getDoctrine()->getManager()->flush(); 415 $this->getDoctrine()->getManager()->flush();
415 416
417 $this->get('event_dispatcher')->dispatch(EntryUpdatedEvent::NAME, new EntryUpdatedEvent($entry));
418
416 $message = 'flashes.entry.notice.entry_unarchived'; 419 $message = 'flashes.entry.notice.entry_unarchived';
417 if ($entry->isArchived()) { 420 if ($entry->isArchived()) {
418 $message = 'flashes.entry.notice.entry_archived'; 421 $message = 'flashes.entry.notice.entry_archived';
@@ -445,6 +448,8 @@ class EntryController extends Controller
445 $entry->toggleStar(); 448 $entry->toggleStar();
446 $this->getDoctrine()->getManager()->flush(); 449 $this->getDoctrine()->getManager()->flush();
447 450
451 $this->get('event_dispatcher')->dispatch(EntryUpdatedEvent::NAME, new EntryUpdatedEvent($entry));
452
448 $message = 'flashes.entry.notice.entry_unstarred'; 453 $message = 'flashes.entry.notice.entry_unstarred';
449 if ($entry->isStarred()) { 454 if ($entry->isStarred()) {
450 $message = 'flashes.entry.notice.entry_starred'; 455 $message = 'flashes.entry.notice.entry_starred';
@@ -481,9 +486,6 @@ class EntryController extends Controller
481 UrlGeneratorInterface::ABSOLUTE_PATH 486 UrlGeneratorInterface::ABSOLUTE_PATH
482 ); 487 );
483 488
484 // entry deleted, dispatch event about it!
485 $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry));
486
487 $em = $this->getDoctrine()->getManager(); 489 $em = $this->getDoctrine()->getManager();
488 $em->remove($entry); 490 $em->remove($entry);
489 $em->flush(); 491 $em->flush();
diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php
index fb6a720b..e6d55931 100644
--- a/src/Wallabag/CoreBundle/Controller/TagController.php
+++ b/src/Wallabag/CoreBundle/Controller/TagController.php
@@ -9,6 +9,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
9use Symfony\Component\HttpFoundation\Request; 9use Symfony\Component\HttpFoundation\Request;
10use Wallabag\CoreBundle\Entity\Entry; 10use Wallabag\CoreBundle\Entity\Entry;
11use Wallabag\CoreBundle\Entity\Tag; 11use Wallabag\CoreBundle\Entity\Tag;
12use Wallabag\CoreBundle\Event\EntryTaggedEvent;
12use Wallabag\CoreBundle\Form\Type\NewTagType; 13use Wallabag\CoreBundle\Form\Type\NewTagType;
13use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; 14use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
14 15
@@ -28,7 +29,7 @@ class TagController extends Controller
28 $form->handleRequest($request); 29 $form->handleRequest($request);
29 30
30 if ($form->isSubmitted() && $form->isValid()) { 31 if ($form->isSubmitted() && $form->isValid()) {
31 $this->get('wallabag_core.tags_assigner')->assignTagsToEntry( 32 $tags = $this->get('wallabag_core.tags_assigner')->assignTagsToEntry(
32 $entry, 33 $entry,
33 $form->get('label')->getData() 34 $form->get('label')->getData()
34 ); 35 );
@@ -37,6 +38,8 @@ class TagController extends Controller
37 $em->persist($entry); 38 $em->persist($entry);
38 $em->flush(); 39 $em->flush();
39 40
41 $this->get('event_dispatcher')->dispatch(EntryTaggedEvent::NAME, new EntryTaggedEvent($entry, $tags));
42
40 $this->get('session')->getFlashBag()->add( 43 $this->get('session')->getFlashBag()->add(
41 'notice', 44 'notice',
42 'flashes.tag.notice.tag_added' 45 'flashes.tag.notice.tag_added'
@@ -64,6 +67,8 @@ class TagController extends Controller
64 $em = $this->getDoctrine()->getManager(); 67 $em = $this->getDoctrine()->getManager();
65 $em->flush(); 68 $em->flush();
66 69
70 $this->get('event_dispatcher')->dispatch(EntryTaggedEvent::NAME, new EntryTaggedEvent($entry, $tag));
71
67 // remove orphan tag in case no entries are associated to it 72 // remove orphan tag in case no entries are associated to it
68 if (count($tag->getEntries()) === 0) { 73 if (count($tag->getEntries()) === 0) {
69 $em->remove($tag); 74 $em->remove($tag);
diff --git a/src/Wallabag/CoreBundle/Entity/Change.php b/src/Wallabag/CoreBundle/Entity/Change.php
new file mode 100644
index 00000000..203a2d31
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Entity/Change.php
@@ -0,0 +1,86 @@
1<?php
2
3namespace Wallabag\CoreBundle\Entity;
4
5use Doctrine\ORM\Mapping as ORM;
6
7/**
8 * Change.
9 *
10 * This entity stores a datetime for each event (updated or tagged) done on an entry.
11 *
12 * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\ChangeRepository")
13 * @ORM\Table(name="`change`")
14 */
15class Change
16{
17 const MODIFIED_TYPE = 1;
18 const CHANGED_TAG_TYPE = 2;
19
20 /**
21 * @var int
22 *
23 * @ORM\Column(type="integer")
24 * @ORM\Id
25 * @ORM\GeneratedValue(strategy="AUTO")
26 */
27 private $id;
28
29 /**
30 * @var int
31 *
32 * @ORM\Column(type="integer")
33 */
34 private $type;
35
36 /**
37 * @ORM\ManyToOne(targetEntity="Wallabag\CoreBundle\Entity\Entry", inversedBy="changes")
38 */
39 private $entry;
40
41 /**
42 * @var \DateTime
43 *
44 * @ORM\Column(name="created_at", type="datetime")
45 */
46 private $createdAt;
47
48 public function __construct($type, Entry $entry)
49 {
50 $this->type = $type;
51 $this->entry = $entry;
52 $this->createdAt = new \DateTime();
53 }
54
55 /**
56 * @return int
57 */
58 public function getId()
59 {
60 return $this->id;
61 }
62
63 /**
64 * @return int
65 */
66 public function getType()
67 {
68 return $this->type;
69 }
70
71 /**
72 * @return DateTime
73 */
74 public function getCreatedAt()
75 {
76 return $this->createdAt;
77 }
78
79 /**
80 * @return Entry
81 */
82 public function getEntry()
83 {
84 return $this->entry;
85 }
86}
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php
index 08a67c34..a24409b9 100644
--- a/src/Wallabag/CoreBundle/Entity/Entry.php
+++ b/src/Wallabag/CoreBundle/Entity/Entry.php
@@ -233,6 +233,11 @@ class Entry
233 */ 233 */
234 private $tags; 234 private $tags;
235 235
236 /**
237 * @ORM\OneToMany(targetEntity="Wallabag\CoreBundle\Entity\Change", mappedBy="entry", cascade={"remove"})
238 */
239 private $changes;
240
236 /* 241 /*
237 * @param User $user 242 * @param User $user
238 */ 243 */
@@ -240,6 +245,7 @@ class Entry
240 { 245 {
241 $this->user = $user; 246 $this->user = $user;
242 $this->tags = new ArrayCollection(); 247 $this->tags = new ArrayCollection();
248 $this->changes = new ArrayCollection();
243 } 249 }
244 250
245 /** 251 /**
diff --git a/src/Wallabag/CoreBundle/Event/EntryTaggedEvent.php b/src/Wallabag/CoreBundle/Event/EntryTaggedEvent.php
new file mode 100644
index 00000000..88856fb1
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Event/EntryTaggedEvent.php
@@ -0,0 +1,42 @@
1<?php
2
3namespace Wallabag\CoreBundle\Event;
4
5use Symfony\Component\EventDispatcher\Event;
6use Wallabag\CoreBundle\Entity\Entry;
7use Wallabag\CoreBundle\Entity\Tag;
8
9/**
10 * This event is fired as soon as a tag is added on an entry.
11 */
12class EntryTaggedEvent extends Event
13{
14 const NAME = 'entry.tagged';
15
16 /** @var Entry */
17 protected $entry;
18
19 /** @var Tag[] */
20 protected $tags;
21
22 public function __construct(Entry $entry, $tags)
23 {
24 $this->entry = $entry;
25
26 if (false === is_array($tags)) {
27 $tags = [$tags];
28 }
29
30 $this->tags = $tags;
31 }
32
33 public function getEntry()
34 {
35 return $this->entry;
36 }
37
38 public function getTags()
39 {
40 return $this->tags;
41 }
42}
diff --git a/src/Wallabag/CoreBundle/Event/EntryUpdatedEvent.php b/src/Wallabag/CoreBundle/Event/EntryUpdatedEvent.php
new file mode 100644
index 00000000..7282835e
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Event/EntryUpdatedEvent.php
@@ -0,0 +1,26 @@
1<?php
2
3namespace Wallabag\CoreBundle\Event;
4
5use Symfony\Component\EventDispatcher\Event;
6use Wallabag\CoreBundle\Entity\Entry;
7
8/**
9 * This event is fired as soon as an entry was updated.
10 */
11class EntryUpdatedEvent extends Event
12{
13 const NAME = 'entry.updated';
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/Subscriber/ChangesSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/ChangesSubscriber.php
new file mode 100644
index 00000000..1ba18a4f
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Event/Subscriber/ChangesSubscriber.php
@@ -0,0 +1,59 @@
1<?php
2
3namespace Wallabag\CoreBundle\Event\Subscriber;
4
5use Symfony\Component\EventDispatcher\EventSubscriberInterface;
6use Doctrine\ORM\EntityManager;
7use Psr\Log\LoggerInterface;
8use Wallabag\CoreBundle\Entity\Change;
9use Wallabag\CoreBundle\Event\EntryTaggedEvent;
10use Wallabag\CoreBundle\Event\EntryUpdatedEvent;
11
12class ChangesSubscriber implements EventSubscriberInterface
13{
14 /** @var LoggerInterface $logger */
15 private $logger;
16
17 /** @var EntityManager $em */
18 private $em;
19
20 public function __construct(EntityManager $em, LoggerInterface $logger)
21 {
22 $this->logger = $logger;
23 $this->em = $em;
24 }
25
26 public static function getSubscribedEvents()
27 {
28 return [
29 EntryUpdatedEvent::NAME => 'onEntryUpdated',
30 EntryTaggedEvent::NAME => 'onEntryTagged',
31 ];
32 }
33
34 /**
35 * @param EntryUpdatedEvent $event
36 */
37 public function onEntryUpdated(EntryUpdatedEvent $event)
38 {
39 $change = new Change(Change::MODIFIED_TYPE, $event->getEntry());
40
41 $this->em->persist($change);
42 $this->em->flush();
43
44 $this->logger->debug('saved updated entry '.$event->getEntry()->getId().' event ');
45 }
46
47 /**
48 * @param EntryTaggedEvent $event
49 */
50 public function onEntryTagged(EntryTaggedEvent $event)
51 {
52 $change = new Change(Change::CHANGED_TAG_TYPE, $event->getEntry());
53
54 $this->em->persist($change);
55 $this->em->flush();
56
57 $this->logger->debug('saved (un)tagged entry '.$event->getEntry()->getId().' event ');
58 }
59}
diff --git a/src/Wallabag/CoreBundle/Repository/ChangeRepository.php b/src/Wallabag/CoreBundle/Repository/ChangeRepository.php
new file mode 100644
index 00000000..18d015a7
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Repository/ChangeRepository.php
@@ -0,0 +1,26 @@
1<?php
2
3namespace Wallabag\CoreBundle\Repository;
4
5use Doctrine\ORM\EntityRepository;
6
7class ChangeRepository extends EntityRepository
8{
9 /**
10 * Used only in test case to get a tag for our entry.
11 *
12 * @param int $timestamp
13 *
14 * @return Tag
15 */
16 public function findChangesSinceDate($timestamp)
17 {
18 $date = new \DateTime();
19 $date->setTimestamp($timestamp);
20
21 return $this->createQueryBuilder('c')
22 ->where('c.createdAt >= :timestamp')->setParameter('timestamp', $date)
23 ->getQuery()
24 ->getResult();
25 }
26}
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
index a68b2fdc..0def87f3 100644
--- a/src/Wallabag/CoreBundle/Resources/config/services.yml
+++ b/src/Wallabag/CoreBundle/Resources/config/services.yml
@@ -199,3 +199,11 @@ services:
199 199
200 wallabag_core.entry.download_images.client: 200 wallabag_core.entry.download_images.client:
201 class: GuzzleHttp\Client 201 class: GuzzleHttp\Client
202
203 wallabag_core.subscriber.changes:
204 class: Wallabag\CoreBundle\Event\Subscriber\ChangesSubscriber
205 arguments:
206 - "@doctrine.orm.default_entity_manager"
207 - "@logger"
208 tags:
209 - { name: kernel.event_subscriber }