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