diff options
Diffstat (limited to 'src/Wallabag/CoreBundle')
-rw-r--r-- | src/Wallabag/CoreBundle/Entity/Entry.php | 16 | ||||
-rw-r--r-- | src/Wallabag/CoreBundle/Helper/ContentProxy.php | 182 |
2 files changed, 113 insertions, 85 deletions
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php index 581e8906..cba72d31 100644 --- a/src/Wallabag/CoreBundle/Entity/Entry.php +++ b/src/Wallabag/CoreBundle/Entity/Entry.php | |||
@@ -593,6 +593,11 @@ class Entry | |||
593 | $tag->addEntry($this); | 593 | $tag->addEntry($this); |
594 | } | 594 | } |
595 | 595 | ||
596 | /** | ||
597 | * Remove the given tag from the entry (if the tag is associated). | ||
598 | * | ||
599 | * @param Tag $tag | ||
600 | */ | ||
596 | public function removeTag(Tag $tag) | 601 | public function removeTag(Tag $tag) |
597 | { | 602 | { |
598 | if (!$this->tags->contains($tag)) { | 603 | if (!$this->tags->contains($tag)) { |
@@ -604,6 +609,17 @@ class Entry | |||
604 | } | 609 | } |
605 | 610 | ||
606 | /** | 611 | /** |
612 | * Remove all assigned tags from the entry. | ||
613 | */ | ||
614 | public function removeAllTags() | ||
615 | { | ||
616 | foreach ($this->tags as $tag) { | ||
617 | $this->tags->removeElement($tag); | ||
618 | $tag->removeEntry($this); | ||
619 | } | ||
620 | } | ||
621 | |||
622 | /** | ||
607 | * Set previewPicture. | 623 | * Set previewPicture. |
608 | * | 624 | * |
609 | * @param string $previewPicture | 625 | * @param string $previewPicture |
diff --git a/src/Wallabag/CoreBundle/Helper/ContentProxy.php b/src/Wallabag/CoreBundle/Helper/ContentProxy.php index ddecd6f4..656ac6ee 100644 --- a/src/Wallabag/CoreBundle/Helper/ContentProxy.php +++ b/src/Wallabag/CoreBundle/Helper/ContentProxy.php | |||
@@ -67,6 +67,76 @@ class ContentProxy | |||
67 | } | 67 | } |
68 | 68 | ||
69 | /** | 69 | /** |
70 | * Use a Symfony validator to ensure the language is well formatted. | ||
71 | * | ||
72 | * @param Entry $entry | ||
73 | * @param string $value Language to validate and save | ||
74 | */ | ||
75 | public function updateLanguage(Entry $entry, $value) | ||
76 | { | ||
77 | // some lang are defined as fr-FR, es-ES. | ||
78 | // replacing - by _ might increase language support | ||
79 | $value = str_replace('-', '_', $value); | ||
80 | |||
81 | $errors = $this->validator->validate( | ||
82 | $value, | ||
83 | (new LocaleConstraint()) | ||
84 | ); | ||
85 | |||
86 | if (0 === count($errors)) { | ||
87 | $entry->setLanguage($value); | ||
88 | |||
89 | return; | ||
90 | } | ||
91 | |||
92 | $this->logger->warning('Language validation failed. ' . (string) $errors); | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * Use a Symfony validator to ensure the preview picture is a real url. | ||
97 | * | ||
98 | * @param Entry $entry | ||
99 | * @param string $value URL to validate and save | ||
100 | */ | ||
101 | public function updatePreviewPicture(Entry $entry, $value) | ||
102 | { | ||
103 | $errors = $this->validator->validate( | ||
104 | $value, | ||
105 | (new UrlConstraint()) | ||
106 | ); | ||
107 | |||
108 | if (0 === count($errors)) { | ||
109 | $entry->setPreviewPicture($value); | ||
110 | |||
111 | return; | ||
112 | } | ||
113 | |||
114 | $this->logger->warning('PreviewPicture validation failed. ' . (string) $errors); | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * Update date. | ||
119 | * | ||
120 | * @param Entry $entry | ||
121 | * @param string $value Date to validate and save | ||
122 | */ | ||
123 | public function updatePublishedAt(Entry $entry, $value) | ||
124 | { | ||
125 | $date = $value; | ||
126 | |||
127 | // is it a timestamp? | ||
128 | if (filter_var($date, FILTER_VALIDATE_INT) !== false) { | ||
129 | $date = '@' . $value; | ||
130 | } | ||
131 | |||
132 | try { | ||
133 | $entry->setPublishedAt(new \DateTime($date)); | ||
134 | } catch (\Exception $e) { | ||
135 | $this->logger->warning('Error while defining date', ['e' => $e, 'url' => $entry->getUrl(), 'date' => $value]); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | /** | ||
70 | * Stock entry with fetched or imported content. | 140 | * Stock entry with fetched or imported content. |
71 | * Will fall back to OpenGraph data if available. | 141 | * Will fall back to OpenGraph data if available. |
72 | * | 142 | * |
@@ -75,9 +145,17 @@ class ContentProxy | |||
75 | */ | 145 | */ |
76 | private function stockEntry(Entry $entry, array $content) | 146 | private function stockEntry(Entry $entry, array $content) |
77 | { | 147 | { |
78 | $title = $content['title']; | 148 | $entry->setUrl($content['url']); |
79 | if (!$title && !empty($content['open_graph']['og_title'])) { | 149 | |
80 | $title = $content['open_graph']['og_title']; | 150 | $domainName = parse_url($entry->getUrl(), PHP_URL_HOST); |
151 | if (false !== $domainName) { | ||
152 | $entry->setDomainName($domainName); | ||
153 | } | ||
154 | |||
155 | if (!empty($content['title'])) { | ||
156 | $entry->setTitle($content['title']); | ||
157 | } elseif (!empty($content['open_graph']['og_title'])) { | ||
158 | $entry->setTitle($content['open_graph']['og_title']); | ||
81 | } | 159 | } |
82 | 160 | ||
83 | $html = $content['html']; | 161 | $html = $content['html']; |
@@ -90,24 +168,11 @@ class ContentProxy | |||
90 | } | 168 | } |
91 | } | 169 | } |
92 | 170 | ||
93 | $entry->setUrl($content['url']); | ||
94 | $entry->setTitle($title); | ||
95 | $entry->setContent($html); | 171 | $entry->setContent($html); |
96 | $entry->setHttpStatus(isset($content['status']) ? $content['status'] : ''); | 172 | $entry->setReadingTime(Utils::getReadingTime($html)); |
97 | |||
98 | if (!empty($content['date'])) { | ||
99 | $date = $content['date']; | ||
100 | |||
101 | // is it a timestamp? | ||
102 | if (filter_var($date, FILTER_VALIDATE_INT) !== false) { | ||
103 | $date = '@' . $content['date']; | ||
104 | } | ||
105 | 173 | ||
106 | try { | 174 | if (!empty($content['status'])) { |
107 | $entry->setPublishedAt(new \DateTime($date)); | 175 | $entry->setHttpStatus($content['status']); |
108 | } catch (\Exception $e) { | ||
109 | $this->logger->warning('Error while defining date', ['e' => $e, 'url' => $content['url'], 'date' => $content['date']]); | ||
110 | } | ||
111 | } | 176 | } |
112 | 177 | ||
113 | if (!empty($content['authors']) && is_array($content['authors'])) { | 178 | if (!empty($content['authors']) && is_array($content['authors'])) { |
@@ -118,30 +183,25 @@ class ContentProxy | |||
118 | $entry->setHeaders($content['all_headers']); | 183 | $entry->setHeaders($content['all_headers']); |
119 | } | 184 | } |
120 | 185 | ||
121 | $this->validateAndSetLanguage( | 186 | if (!empty($content['date'])) { |
122 | $entry, | 187 | $this->updatePublishedAt($entry, $content['date']); |
123 | isset($content['language']) ? $content['language'] : null | 188 | } |
124 | ); | ||
125 | 189 | ||
126 | $this->validateAndSetPreviewPicture( | 190 | if (!empty($content['language'])) { |
127 | $entry, | 191 | $this->updateLanguage($entry, $content['language']); |
128 | isset($content['open_graph']['og_image']) ? $content['open_graph']['og_image'] : null | 192 | } |
129 | ); | 193 | |
194 | if (!empty($content['open_graph']['og_image'])) { | ||
195 | $this->updatePreviewPicture($entry, $content['open_graph']['og_image']); | ||
196 | } | ||
130 | 197 | ||
131 | // if content is an image, define it as a preview too | 198 | // if content is an image, define it as a preview too |
132 | if (!empty($content['content_type']) && in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) { | 199 | if (!empty($content['content_type']) && in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) { |
133 | $this->validateAndSetPreviewPicture( | 200 | $this->updatePreviewPicture($entry, $content['url']); |
134 | $entry, | ||
135 | $content['url'] | ||
136 | ); | ||
137 | } | 201 | } |
138 | 202 | ||
139 | $entry->setMimetype(isset($content['content_type']) ? $content['content_type'] : ''); | 203 | if (!empty($content['content_type'])) { |
140 | $entry->setReadingTime(Utils::getReadingTime($html)); | 204 | $entry->setMimetype($content['content_type']); |
141 | |||
142 | $domainName = parse_url($entry->getUrl(), PHP_URL_HOST); | ||
143 | if (false !== $domainName) { | ||
144 | $entry->setDomainName($domainName); | ||
145 | } | 205 | } |
146 | 206 | ||
147 | try { | 207 | try { |
@@ -165,52 +225,4 @@ class ContentProxy | |||
165 | { | 225 | { |
166 | return !empty($content['title']) && !empty($content['html']) && !empty($content['url']); | 226 | return !empty($content['title']) && !empty($content['html']) && !empty($content['url']); |
167 | } | 227 | } |
168 | |||
169 | /** | ||
170 | * Use a Symfony validator to ensure the language is well formatted. | ||
171 | * | ||
172 | * @param Entry $entry | ||
173 | * @param string $value Language to validate | ||
174 | */ | ||
175 | private function validateAndSetLanguage($entry, $value) | ||
176 | { | ||
177 | // some lang are defined as fr-FR, es-ES. | ||
178 | // replacing - by _ might increase language support | ||
179 | $value = str_replace('-', '_', $value); | ||
180 | |||
181 | $errors = $this->validator->validate( | ||
182 | $value, | ||
183 | (new LocaleConstraint()) | ||
184 | ); | ||
185 | |||
186 | if (0 === count($errors)) { | ||
187 | $entry->setLanguage($value); | ||
188 | |||
189 | return; | ||
190 | } | ||
191 | |||
192 | $this->logger->warning('Language validation failed. ' . (string) $errors); | ||
193 | } | ||
194 | |||
195 | /** | ||
196 | * Use a Symfony validator to ensure the preview picture is a real url. | ||
197 | * | ||
198 | * @param Entry $entry | ||
199 | * @param string $value URL to validate | ||
200 | */ | ||
201 | private function validateAndSetPreviewPicture($entry, $value) | ||
202 | { | ||
203 | $errors = $this->validator->validate( | ||
204 | $value, | ||
205 | (new UrlConstraint()) | ||
206 | ); | ||
207 | |||
208 | if (0 === count($errors)) { | ||
209 | $entry->setPreviewPicture($value); | ||
210 | |||
211 | return; | ||
212 | } | ||
213 | |||
214 | $this->logger->warning('PreviewPicture validation failed. ' . (string) $errors); | ||
215 | } | ||
216 | } | 228 | } |