]> git.immae.eu Git - github/wallabag/wallabag.git/blame - src/Wallabag/ImportBundle/Import/AbstractImport.php
Move Tags assigner to a separate file
[github/wallabag/wallabag.git] / src / Wallabag / ImportBundle / Import / AbstractImport.php
CommitLineData
19d9efab
JB
1<?php
2
3namespace Wallabag\ImportBundle\Import;
4
5use Psr\Log\LoggerInterface;
6use Psr\Log\NullLogger;
7use Doctrine\ORM\EntityManager;
8use Wallabag\CoreBundle\Helper\ContentProxy;
9use Wallabag\CoreBundle\Entity\Entry;
8664069e 10use Wallabag\CoreBundle\Entity\Tag;
6bc6fb1f 11use Wallabag\CoreBundle\Helper\TagsAssigner;
3849a9f3 12use Wallabag\UserBundle\Entity\User;
b3437d58 13use OldSound\RabbitMqBundle\RabbitMq\ProducerInterface;
7816eb62
JB
14use Symfony\Component\EventDispatcher\EventDispatcherInterface;
15use Wallabag\CoreBundle\Event\EntrySavedEvent;
19d9efab
JB
16
17abstract class AbstractImport implements ImportInterface
18{
19 protected $em;
20 protected $logger;
21 protected $contentProxy;
6bc6fb1f 22 protected $tagsAssigner;
7816eb62 23 protected $eventDispatcher;
c98db1b6
JB
24 protected $producer;
25 protected $user;
26 protected $markAsRead;
3aca0a9f
JB
27 protected $skippedEntries = 0;
28 protected $importedEntries = 0;
c80cc01a 29 protected $queuedEntries = 0;
19d9efab 30
6bc6fb1f 31 public function __construct(EntityManager $em, ContentProxy $contentProxy, TagsAssigner $tagsAssigner, EventDispatcherInterface $eventDispatcher)
19d9efab
JB
32 {
33 $this->em = $em;
34 $this->logger = new NullLogger();
35 $this->contentProxy = $contentProxy;
6bc6fb1f 36 $this->tagsAssigner = $tagsAssigner;
7816eb62 37 $this->eventDispatcher = $eventDispatcher;
19d9efab
JB
38 }
39
40 public function setLogger(LoggerInterface $logger)
41 {
42 $this->logger = $logger;
43 }
44
c98db1b6 45 /**
b3437d58 46 * Set RabbitMQ/Redis Producer to send each entry to a queue.
c98db1b6
JB
47 * This method should be called when user has enabled RabbitMQ.
48 *
b3437d58 49 * @param ProducerInterface $producer
c98db1b6 50 */
b3437d58 51 public function setProducer(ProducerInterface $producer)
c98db1b6
JB
52 {
53 $this->producer = $producer;
54 }
55
56 /**
57 * Set current user.
58 * Could the current *connected* user or one retrieve by the consumer.
59 *
3849a9f3 60 * @param User $user
c98db1b6 61 */
3849a9f3 62 public function setUser(User $user)
c98db1b6
JB
63 {
64 $this->user = $user;
65 }
66
67 /**
68 * Set whether articles must be all marked as read.
69 *
70 * @param bool $markAsRead
71 */
72 public function setMarkAsRead($markAsRead)
73 {
74 $this->markAsRead = $markAsRead;
75
76 return $this;
77 }
78
79 /**
80 * Get whether articles must be all marked as read.
81 */
82 public function getMarkAsRead()
83 {
84 return $this->markAsRead;
85 }
86
19d9efab
JB
87 /**
88 * Fetch content from the ContentProxy (using graby).
59b97fae 89 * If it fails return the given entry to be saved in all case (to avoid user to loose the content).
19d9efab
JB
90 *
91 * @param Entry $entry Entry to update
92 * @param string $url Url to grab content for
93 * @param array $content An array with AT LEAST keys title, html, url, language & content_type to skip the fetchContent from the url
94 *
59b97fae 95 * @return Entry
19d9efab
JB
96 */
97 protected function fetchContent(Entry $entry, $url, array $content = [])
98 {
99 try {
100 return $this->contentProxy->updateEntry($entry, $url, $content);
101 } catch (\Exception $e) {
59b97fae 102 return $entry;
19d9efab
JB
103 }
104 }
c98db1b6
JB
105
106 /**
107 * Parse and insert all given entries.
108 *
109 * @param $entries
110 */
111 protected function parseEntries($entries)
112 {
113 $i = 1;
7816eb62 114 $entryToBeFlushed = [];
c98db1b6
JB
115
116 foreach ($entries as $importedEntry) {
ff1a5362
JB
117 if ($this->markAsRead) {
118 $importedEntry = $this->setEntryAsRead($importedEntry);
119 }
120
c98db1b6
JB
121 $entry = $this->parseEntry($importedEntry);
122
123 if (null === $entry) {
124 continue;
125 }
126
7816eb62
JB
127 // store each entry to be flushed so we can trigger the entry.saved event for each of them
128 // entry.saved needs the entry to be persisted in db because it needs it id to generate
129 // images (at least)
130 $entryToBeFlushed[] = $entry;
131
c98db1b6
JB
132 // flush every 20 entries
133 if (($i % 20) === 0) {
134 $this->em->flush();
8664069e 135
7816eb62
JB
136 foreach ($entryToBeFlushed as $entry) {
137 $this->eventDispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
138 }
139
140 $entryToBeFlushed = [];
141
8664069e
JB
142 // clear only affected entities
143 $this->em->clear(Entry::class);
144 $this->em->clear(Tag::class);
c98db1b6
JB
145 }
146 ++$i;
147 }
148
149 $this->em->flush();
7816eb62
JB
150
151 if (!empty($entryToBeFlushed)) {
152 foreach ($entryToBeFlushed as $entry) {
153 $this->eventDispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
154 }
155 }
c98db1b6
JB
156 }
157
3849a9f3
JB
158 /**
159 * Parse entries and send them to the queue.
160 * It should just be a simple loop on all item, no call to the database should be done
161 * to speedup queuing.
162 *
163 * Faster parse entries for Producer.
164 * We don't care to make check at this time. They'll be done by the consumer.
165 *
166 * @param array $entries
167 */
168 protected function parseEntriesForProducer(array $entries)
169 {
170 foreach ($entries as $importedEntry) {
171 // set userId for the producer (it won't know which user is connected)
172 $importedEntry['userId'] = $this->user->getId();
173
174 if ($this->markAsRead) {
175 $importedEntry = $this->setEntryAsRead($importedEntry);
176 }
177
c80cc01a 178 ++$this->queuedEntries;
3849a9f3
JB
179
180 $this->producer->publish(json_encode($importedEntry));
181 }
182 }
183
c80cc01a
JB
184 /**
185 * {@inheritdoc}
186 */
187 public function getSummary()
188 {
189 return [
190 'skipped' => $this->skippedEntries,
191 'imported' => $this->importedEntries,
192 'queued' => $this->queuedEntries,
193 ];
194 }
195
c98db1b6
JB
196 /**
197 * Parse one entry.
198 *
199 * @param array $importedEntry
200 *
201 * @return Entry
202 */
203 abstract public function parseEntry(array $importedEntry);
3849a9f3
JB
204
205 /**
206 * Set current imported entry to archived / read.
207 * Implementation is different accross all imports.
208 *
209 * @param array $importedEntry
210 *
211 * @return array
212 */
213 abstract protected function setEntryAsRead(array $importedEntry);
19d9efab 214}