]> git.immae.eu Git - github/wallabag/wallabag.git/blame - src/Wallabag/Wallabag/Picture.php
new folders
[github/wallabag/wallabag.git] / src / Wallabag / Wallabag / Picture.php
CommitLineData
a4565e88
NL
1<?php
2/**
c95b78a8 3 * wallabag, self hostable application allowing you to not miss any content anymore
a4565e88 4 *
c95b78a8
NL
5 * @category wallabag
6 * @author Nicolas Lœuillet <nicolas@loeuillet.org>
a4565e88 7 * @copyright 2013
3602405e 8 * @license http://opensource.org/licenses/MIT see COPYING file
a4565e88
NL
9 */
10
6ad93dff 11namespace Wallabag\Wallabag;
3602405e
NL
12
13final class Picture
a4565e88 14{
3602405e
NL
15 /**
16 * Changing pictures URL in article content
17 */
18 public static function filterPicture($content, $url, $id)
19 {
20 $matches = array();
21 $processing_pictures = array(); // list of processing image to avoid processing the same pictures twice
22 preg_match_all('#<\s*(img)[^>]+src="([^"]*)"[^>]*>#Si', $content, $matches, PREG_SET_ORDER);
23 foreach($matches as $i => $link) {
24 $link[1] = trim($link[1]);
25 if (!preg_match('#^(([a-z]+://)|(\#))#', $link[1])) {
26 $absolute_path = self::_getAbsoluteLink($link[2], $url);
27 $filename = basename(parse_url($absolute_path, PHP_URL_PATH));
28 $directory = self::_createAssetsDirectory($id);
29 $fullpath = $directory . '/' . $filename;
30
31 if (in_array($absolute_path, $processing_pictures) === true) {
32 // replace picture's URL only if processing is OK : already processing -> go to next picture
33 continue;
34 }
35
36 if (self::_downloadPictures($absolute_path, $fullpath) === true) {
aa1083bd 37 $content = str_replace($matches[$i][2], Tools::getPocheUrl() . $fullpath, $content);
3602405e
NL
38 }
39
40 $processing_pictures[] = $absolute_path;
0bf0dfe1 41 }
a4565e88
NL
42 }
43
3602405e 44 return $content;
a4565e88
NL
45 }
46
3602405e
NL
47 /**
48 * Get absolute URL
49 */
50 private static function _getAbsoluteLink($relativeLink, $url)
51 {
52 /* return if already absolute URL */
53 if (parse_url($relativeLink, PHP_URL_SCHEME) != '') return $relativeLink;
a4565e88 54
3602405e
NL
55 /* queries and anchors */
56 if ($relativeLink[0]=='#' || $relativeLink[0]=='?') return $url . $relativeLink;
a4565e88 57
3602405e
NL
58 /* parse base URL and convert to local variables:
59 $scheme, $host, $path */
60 extract(parse_url($url));
a4565e88 61
3602405e
NL
62 /* remove non-directory element from path */
63 $path = preg_replace('#/[^/]*$#', '', $path);
a4565e88 64
3602405e
NL
65 /* destroy path if relative url points to root */
66 if ($relativeLink[0] == '/') $path = '';
a4565e88 67
3602405e
NL
68 /* dirty absolute URL */
69 $abs = $host . $path . '/' . $relativeLink;
a4565e88 70
3602405e
NL
71 /* replace '//' or '/./' or '/foo/../' with '/' */
72 $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
73 for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {}
a4565e88 74
3602405e
NL
75 /* absolute URL is ready! */
76 return $scheme.'://'.$abs;
77 }
a4565e88 78
3602405e
NL
79 /**
80 * Downloading pictures
81 *
82 * @return bool true if the download and processing is OK, false else
83 */
84 private static function _downloadPictures($absolute_path, $fullpath)
85 {
86 $rawdata = Tools::getFile($absolute_path);
87 $fullpath = urldecode($fullpath);
88
89 if(file_exists($fullpath)) {
90 unlink($fullpath);
91 }
a4565e88 92
3602405e
NL
93 // check extension
94 $file_ext = strrchr($fullpath, '.');
95 $whitelist = array(".jpg",".jpeg",".gif",".png");
96 if (!(in_array($file_ext, $whitelist))) {
97 Tools::logm('processed image with not allowed extension. Skipping ' . $fullpath);
98 return false;
99 }
a4565e88 100
3602405e
NL
101 // check headers
102 $imageinfo = getimagesize($absolute_path);
103 if ($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg'&& $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
104 Tools::logm('processed image with bad header. Skipping ' . $fullpath);
105 return false;
106 }
a4565e88 107
3602405e
NL
108 // regenerate image
109 $im = imagecreatefromstring($rawdata);
110 if ($im === false) {
111 Tools::logm('error while regenerating image ' . $fullpath);
112 return false;
113 }
114
115 switch ($imageinfo['mime']) {
116 case 'image/gif':
117 $result = imagegif($im, $fullpath);
118 break;
119 case 'image/jpeg':
120 case 'image/jpg':
121 $result = imagejpeg($im, $fullpath, REGENERATE_PICTURES_QUALITY);
122 break;
123 case 'image/png':
124 $result = imagepng($im, $fullpath, ceil(REGENERATE_PICTURES_QUALITY / 100 * 9));
125 break;
126 }
127 imagedestroy($im);
a4565e88 128
3602405e 129 return $result;
a4565e88
NL
130 }
131
3602405e
NL
132 /**
133 * Create a directory for an article
134 *
135 * @param $id ID of the article
136 * @return string
137 */
138 private static function _createAssetsDirectory($id)
139 {
140 $assets_path = ABS_PATH;
141 if (!is_dir($assets_path)) {
142 mkdir($assets_path, 0715);
143 }
a4565e88 144
3602405e
NL
145 $article_directory = $assets_path . $id;
146 if (!is_dir($article_directory)) {
147 mkdir($article_directory, 0715);
148 }
149
150 return $article_directory;
151 }
152
153 /**
154 * Remove the directory
155 *
156 * @param $directory
157 * @return bool
158 */
159 public static function removeDirectory($directory)
160 {
161 if (is_dir($directory)) {
162 $files = array_diff(scandir($directory), array('.','..'));
163 foreach ($files as $file) {
164 (is_dir("$directory/$file")) ? self::removeDirectory("$directory/$file") : unlink("$directory/$file");
165 }
166 return rmdir($directory);
a4565e88 167 }
a4565e88 168 }
3602405e 169}