diff options
author | Thomas Citharel <tcit@tcit.fr> | 2016-06-26 10:27:31 +0200 |
---|---|---|
committer | Jeremy Benoist <jeremy.benoist@gmail.com> | 2016-10-29 16:25:45 +0200 |
commit | 4dface66707688ea440a6a7569795a85631d1ff0 (patch) | |
tree | 1d07ba6cda3ca0467eb053b5a300f404e5c6a7db /src | |
parent | 5feef9f7a4e6852415feb388190b7ca141f116d1 (diff) | |
download | wallabag-4dface66707688ea440a6a7569795a85631d1ff0.tar.gz wallabag-4dface66707688ea440a6a7569795a85631d1ff0.tar.zst wallabag-4dface66707688ea440a6a7569795a85631d1ff0.zip |
first draft (from v1)
Diffstat (limited to 'src')
-rw-r--r-- | src/Wallabag/CoreBundle/Helper/ContentProxy.php | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/Wallabag/CoreBundle/Helper/ContentProxy.php b/src/Wallabag/CoreBundle/Helper/ContentProxy.php index 8019df42..ddeffa77 100644 --- a/src/Wallabag/CoreBundle/Helper/ContentProxy.php +++ b/src/Wallabag/CoreBundle/Helper/ContentProxy.php | |||
@@ -151,4 +151,172 @@ class ContentProxy | |||
151 | { | 151 | { |
152 | return isset($content['title']) && isset($content['html']) && isset($content['url']) && isset($content['language']) && isset($content['content_type']); | 152 | return isset($content['title']) && isset($content['html']) && isset($content['url']) && isset($content['language']) && isset($content['content_type']); |
153 | } | 153 | } |
154 | |||
155 | /** | ||
156 | * Changing pictures URL in article content. | ||
157 | */ | ||
158 | public static function filterPicture($content, $url, $id) | ||
159 | { | ||
160 | $matches = array(); | ||
161 | $processing_pictures = array(); // list of processing image to avoid processing the same pictures twice | ||
162 | preg_match_all('#<\s*(img)[^>]+src="([^"]*)"[^>]*>#Si', $content, $matches, PREG_SET_ORDER); | ||
163 | foreach ($matches as $i => $link) { | ||
164 | $link[1] = trim($link[1]); | ||
165 | if (!preg_match('#^(([a-z]+://)|(\#))#', $link[1])) { | ||
166 | $absolute_path = self::_getAbsoluteLink($link[2], $url); | ||
167 | $filename = basename(parse_url($absolute_path, PHP_URL_PATH)); | ||
168 | $directory = self::_createAssetsDirectory($id); | ||
169 | $fullpath = $directory.'/'.$filename; | ||
170 | |||
171 | if (in_array($absolute_path, $processing_pictures) === true) { | ||
172 | // replace picture's URL only if processing is OK : already processing -> go to next picture | ||
173 | continue; | ||
174 | } | ||
175 | |||
176 | if (self::_downloadPictures($absolute_path, $fullpath) === true) { | ||
177 | $content = str_replace($matches[$i][2], Tools::getPocheUrl().$fullpath, $content); | ||
178 | } | ||
179 | |||
180 | $processing_pictures[] = $absolute_path; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | return $content; | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * Get absolute URL. | ||
189 | */ | ||
190 | private static function _getAbsoluteLink($relativeLink, $url) | ||
191 | { | ||
192 | /* return if already absolute URL */ | ||
193 | if (parse_url($relativeLink, PHP_URL_SCHEME) != '') { | ||
194 | return $relativeLink; | ||
195 | } | ||
196 | |||
197 | /* queries and anchors */ | ||
198 | if ($relativeLink[0] == '#' || $relativeLink[0] == '?') { | ||
199 | return $url.$relativeLink; | ||
200 | } | ||
201 | |||
202 | /* parse base URL and convert to local variables: | ||
203 | $scheme, $host, $path */ | ||
204 | extract(parse_url($url)); | ||
205 | |||
206 | /* remove non-directory element from path */ | ||
207 | $path = preg_replace('#/[^/]*$#', '', $path); | ||
208 | |||
209 | /* destroy path if relative url points to root */ | ||
210 | if ($relativeLink[0] == '/') { | ||
211 | $path = ''; | ||
212 | } | ||
213 | |||
214 | /* dirty absolute URL */ | ||
215 | $abs = $host.$path.'/'.$relativeLink; | ||
216 | |||
217 | /* replace '//' or '/./' or '/foo/../' with '/' */ | ||
218 | $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#'); | ||
219 | for ($n = 1; $n > 0; $abs = preg_replace($re, '/', $abs, -1, $n)) { | ||
220 | } | ||
221 | |||
222 | /* absolute URL is ready! */ | ||
223 | return $scheme.'://'.$abs; | ||
224 | } | ||
225 | |||
226 | /** | ||
227 | * Downloading pictures. | ||
228 | * | ||
229 | * @return bool true if the download and processing is OK, false else | ||
230 | */ | ||
231 | private static function _downloadPictures($absolute_path, $fullpath) | ||
232 | { | ||
233 | $rawdata = Tools::getFile($absolute_path); | ||
234 | $fullpath = urldecode($fullpath); | ||
235 | |||
236 | if (file_exists($fullpath)) { | ||
237 | unlink($fullpath); | ||
238 | } | ||
239 | |||
240 | // check extension | ||
241 | $file_ext = strrchr($fullpath, '.'); | ||
242 | $whitelist = array('.jpg', '.jpeg', '.gif', '.png'); | ||
243 | if (!(in_array($file_ext, $whitelist))) { | ||
244 | Tools::logm('processed image with not allowed extension. Skipping '.$fullpath); | ||
245 | |||
246 | return false; | ||
247 | } | ||
248 | |||
249 | // check headers | ||
250 | $imageinfo = getimagesize($absolute_path); | ||
251 | if ($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg' && $imageinfo['mime'] != 'image/jpg' && $imageinfo['mime'] != 'image/png') { | ||
252 | Tools::logm('processed image with bad header. Skipping '.$fullpath); | ||
253 | |||
254 | return false; | ||
255 | } | ||
256 | |||
257 | // regenerate image | ||
258 | $im = imagecreatefromstring($rawdata); | ||
259 | if ($im === false) { | ||
260 | Tools::logm('error while regenerating image '.$fullpath); | ||
261 | |||
262 | return false; | ||
263 | } | ||
264 | |||
265 | switch ($imageinfo['mime']) { | ||
266 | case 'image/gif': | ||
267 | $result = imagegif($im, $fullpath); | ||
268 | break; | ||
269 | case 'image/jpeg': | ||
270 | case 'image/jpg': | ||
271 | $result = imagejpeg($im, $fullpath, REGENERATE_PICTURES_QUALITY); | ||
272 | break; | ||
273 | case 'image/png': | ||
274 | $result = imagepng($im, $fullpath, ceil(REGENERATE_PICTURES_QUALITY / 100 * 9)); | ||
275 | break; | ||
276 | } | ||
277 | imagedestroy($im); | ||
278 | |||
279 | return $result; | ||
280 | } | ||
281 | |||
282 | /** | ||
283 | * Create a directory for an article. | ||
284 | * | ||
285 | * @param $id ID of the article | ||
286 | * | ||
287 | * @return string | ||
288 | */ | ||
289 | private static function _createAssetsDirectory($id) | ||
290 | { | ||
291 | $assets_path = ABS_PATH; | ||
292 | if (!is_dir($assets_path)) { | ||
293 | mkdir($assets_path, 0715); | ||
294 | } | ||
295 | |||
296 | $article_directory = $assets_path.$id; | ||
297 | if (!is_dir($article_directory)) { | ||
298 | mkdir($article_directory, 0715); | ||
299 | } | ||
300 | |||
301 | return $article_directory; | ||
302 | } | ||
303 | |||
304 | /** | ||
305 | * Remove the directory. | ||
306 | * | ||
307 | * @param $directory | ||
308 | * | ||
309 | * @return bool | ||
310 | */ | ||
311 | public static function removeDirectory($directory) | ||
312 | { | ||
313 | if (is_dir($directory)) { | ||
314 | $files = array_diff(scandir($directory), array('.', '..')); | ||
315 | foreach ($files as $file) { | ||
316 | (is_dir("$directory/$file")) ? self::removeDirectory("$directory/$file") : unlink("$directory/$file"); | ||
317 | } | ||
318 | |||
319 | return rmdir($directory); | ||
320 | } | ||
321 | } | ||
154 | } | 322 | } |