]> git.immae.eu Git - github/wallabag/wallabag.git/blob - src/Wallabag/ImportBundle/Import/BrowserImport.php
e3457196e4e0f8b837ea0c98c3decc514ffdb006
[github/wallabag/wallabag.git] / src / Wallabag / ImportBundle / Import / BrowserImport.php
1 <?php
2
3 namespace Wallabag\ImportBundle\Import;
4
5 use Psr\Log\LoggerInterface;
6 use Psr\Log\NullLogger;
7 use Doctrine\ORM\EntityManager;
8 use Wallabag\CoreBundle\Entity\Entry;
9 use Wallabag\UserBundle\Entity\User;
10 use Wallabag\CoreBundle\Helper\ContentProxy;
11
12 class BrowserImport implements ImportInterface
13 {
14 protected $user;
15 protected $em;
16 protected $logger;
17 protected $contentProxy;
18 protected $skippedEntries = 0;
19 protected $importedEntries = 0;
20 protected $totalEntries = 0;
21 protected $filepath;
22 protected $markAsRead;
23 private $nbEntries;
24
25 public function __construct(EntityManager $em, ContentProxy $contentProxy)
26 {
27 $this->em = $em;
28 $this->logger = new NullLogger();
29 $this->contentProxy = $contentProxy;
30 }
31
32 public function setLogger(LoggerInterface $logger)
33 {
34 $this->logger = $logger;
35 }
36
37 /**
38 * We define the user in a custom call because on the import command there is no logged in user.
39 * So we can't retrieve user from the `security.token_storage` service.
40 *
41 * @param User $user
42 *
43 * @return $this
44 */
45 public function setUser(User $user)
46 {
47 $this->user = $user;
48
49 return $this;
50 }
51
52 /**
53 * {@inheritdoc}
54 */
55 public function getName()
56 {
57 return 'Firefox & Google Chrome';
58 }
59
60 /**
61 * {@inheritdoc}
62 */
63 public function getUrl()
64 {
65 return 'import_browser';
66 }
67
68 /**
69 * {@inheritdoc}
70 */
71 public function getDescription()
72 {
73 return 'import.browser.description';
74 }
75
76 /**
77 * {@inheritdoc}
78 */
79 public function import()
80 {
81 if (!$this->user) {
82 $this->logger->error('WallabagImport: user is not defined');
83
84 return false;
85 }
86
87 if (!file_exists($this->filepath) || !is_readable($this->filepath)) {
88 $this->logger->error('WallabagImport: unable to read file', ['filepath' => $this->filepath]);
89
90 return false;
91 }
92
93 $data = json_decode(file_get_contents($this->filepath), true);
94
95 if (empty($data)) {
96 return false;
97 }
98
99 $this->nbEntries = 1;
100 $this->parseEntries($data);
101 $this->em->flush();
102
103 return true;
104 }
105
106 private function parseEntries($data)
107 {
108 foreach ($data as $importedEntry) {
109 $this->parseEntry($importedEntry);
110 }
111 $this->totalEntries += count($data);
112 }
113
114 private function parseEntry($importedEntry)
115 {
116 if (!is_array($importedEntry)) {
117 return;
118 }
119
120 /* Firefox uses guid while Chrome uses id */
121
122 if ((!key_exists('guid', $importedEntry) || (!key_exists('id', $importedEntry))) && is_array(reset($importedEntry))) {
123 $this->parseEntries($importedEntry);
124
125 return;
126 }
127 if (key_exists('children', $importedEntry)) {
128 $this->parseEntries($importedEntry['children']);
129
130 return;
131 }
132 if (key_exists('uri', $importedEntry) || key_exists('url', $importedEntry)) {
133
134 /* Firefox uses uri while Chrome uses url */
135
136 $firefox = key_exists('uri', $importedEntry);
137
138 $existingEntry = $this->em
139 ->getRepository('WallabagCoreBundle:Entry')
140 ->findByUrlAndUserId(($firefox) ? $importedEntry['uri'] : $importedEntry['url'], $this->user->getId());
141
142 if (false !== $existingEntry) {
143 ++$this->skippedEntries;
144
145 return;
146 }
147
148 if (false === parse_url(($firefox) ? $importedEntry['uri'] : $importedEntry['url']) || false === filter_var(($firefox) ? $importedEntry['uri'] : $importedEntry['url'], FILTER_VALIDATE_URL)) {
149 $this->logger->warning('Imported URL '.($firefox) ? $importedEntry['uri'] : $importedEntry['url'].' is not valid');
150 ++$this->skippedEntries;
151
152 return;
153 }
154
155 try {
156 $entry = $this->contentProxy->updateEntry(
157 new Entry($this->user),
158 ($firefox) ? $importedEntry['uri'] : $importedEntry['url']
159 );
160 } catch (\Exception $e) {
161 $this->logger->warning('Error while saving '.($firefox) ? $importedEntry['uri'] : $importedEntry['url']);
162 ++$this->skippedEntries;
163
164 return;
165 }
166
167 $entry->setArchived($this->markAsRead);
168
169 $this->em->persist($entry);
170 ++$this->importedEntries;
171
172 // flush every 20 entries
173 if (($this->nbEntries % 20) === 0) {
174 $this->em->flush();
175 $this->em->clear($entry);
176 }
177 ++$this->nbEntries;
178 }
179 }
180
181 /**
182 * Set whether articles must be all marked as read.
183 *
184 * @param bool $markAsRead
185 *
186 * @return $this
187 */
188 public function setMarkAsRead($markAsRead)
189 {
190 $this->markAsRead = $markAsRead;
191
192 return $this;
193 }
194
195 /**
196 * Set file path to the json file.
197 *
198 * @param string $filepath
199 *
200 * @return $this
201 */
202 public function setFilepath($filepath)
203 {
204 $this->filepath = $filepath;
205
206 return $this;
207 }
208
209 /**
210 * {@inheritdoc}
211 */
212 public function getSummary()
213 {
214 return [
215 'skipped' => $this->skippedEntries,
216 'imported' => $this->importedEntries,
217 ];
218 }
219 }