temporary removal of tokenizer for performance
[lhc/web/wiklou.git] / includes / Image.php
1 <?php
2 # Class to represent an image
3 # Provides methods to retrieve paths (physical, logical, URL),
4 # to generate thumbnails or for uploading.
5
6 class Image
7 {
8 /* private */
9 var $name, # name of the image
10 $imagePath, # Path of the image
11 $url, # Image URL
12 $title, # Title object for this image. Initialized when needed.
13 $fileExists, # does the image file exist on disk?
14 $historyLine, # Number of line to return by nextHistoryLine()
15 $historyRes, # result of the query for the image's history
16 $width, # \
17 $height, # |
18 $bits, # --- returned by getimagesize, see http://de3.php.net/manual/en/function.getimagesize.php
19 $type, # |
20 $attr; # /
21
22
23
24 function Image( $name )
25 {
26 global $wgUploadDirectory;
27
28 $this->name = $name;
29 $this->title = Title::makeTitle( Namespace::getImage(), $this->name );
30 //$this->imagePath = wfImagePath( $name );
31 $hash = md5( $this->title->getDBkey() );
32 $this->imagePath = $wgUploadDirectory . "/" . $hash{0} . "/" .substr( $hash, 0, 2 ) . "/{$name}";
33
34 $this->url = $this->wfImageUrl( $name );
35
36 if ( $this->fileExists = file_exists( $this->imagePath ) ) // Sic!, "=" is intended
37 {
38 $gis = getimagesize( $this->imagePath );
39 $this->width = $gis[0];
40 $this->height = $gis[1];
41 $this->type = $gis[2];
42 $this->attr = $gis[3];
43 if ( isset( $gis["bits"] ) )
44 {
45 $this->bits = $gis["bits"];
46 } else {
47 $this->bits = 0;
48 }
49 }
50 $this->historyLine = 0;
51 }
52
53 function newFromTitle( $nt )
54 {
55 $img = new Image( $nt->getDBKey() );
56 $img->title = $nt;
57 return $img;
58 }
59
60 function getName()
61 {
62 return $this->name;
63 }
64
65 function getURL()
66 {
67 return $this->url;
68 }
69
70 function getImagePath()
71 {
72 return $this->imagePath;
73 }
74
75 function getWidth()
76 {
77 return $this->width;
78 }
79
80 function getHeight()
81 {
82 return $this->height;
83 }
84
85 function getType()
86 {
87 return $this->type;
88 }
89
90 function getEscapeLocalURL()
91 {
92 return $this->title->escapeLocalURL();
93 }
94
95 function wfImageUrl( $name )
96 {
97 global $wgUploadPath;
98 $hash = md5( $name );
99
100 $url = "{$wgUploadPath}/" . $hash{0} . "/" .
101 substr( $hash, 0, 2 ) . "/{$name}";
102 return wfUrlencode( $url );
103 }
104
105
106 function exists()
107 {
108 return $this->fileExists;
109 }
110
111 function thumbUrl( $width, $subdir="thumb" ) {
112 global $wgUploadPath;
113
114 $name = $this->thumbName( $width );
115 $hash = md5( $name );
116 $url = "{$wgUploadPath}/{$subdir}/" . $hash{0} . "/" . substr( $hash, 0, 2 ) . "/{$name}";
117
118 return wfUrlencode($url);
119 }
120
121 function thumbName( $width ) {
122 return $width."px-".$this->name;
123 }
124
125 //**********************************************************************
126 // Create a thumbnail of the image having the specified width.
127 // The thumbnail will not be created if the width is larger than the
128 // image's width. Let the browser do the scaling in this case.
129 // The thumbnail is stored on disk and is only computed if the thumbnail
130 // file does not exist OR if it is older than the image.
131 function createThumb( $width ) {
132 global $wgUploadDirectory;
133 global $wgImageMagickConvertCommand;
134 global $wgUseImageMagick;
135 global $wgUseSquid, $wgInternalServer;
136
137 $width = IntVal( $width );
138
139 $thumbName = $this->thumbName( $width );
140 $thumbPath = wfImageThumbDir( $thumbName )."/".$thumbName;
141 $thumbUrl = $this->thumbUrl( $width );
142
143 if ( ! $this->exists() )
144 {
145 # If there is no image, there will be no thumbnail
146 return "";
147 }
148
149 # Sanity check $width
150 if( $width <= 0 ) {
151 # BZZZT
152 return "";
153 }
154
155 if( $width > $this->width ) {
156 # Don't make an image bigger than the source
157 return $this->getURL();
158 }
159
160 if ( (! file_exists( $thumbPath ) )
161 || ( filemtime($thumbPath) < filemtime($this->imagePath) ) ) {
162 # Squid purging
163 if ( $wgUseSquid ) {
164 $urlArr = Array(
165 $wgInternalServer.$thumbUrl
166 );
167 wfPurgeSquidServers($urlArr);
168 }
169
170 if ( $wgUseImageMagick ) {
171 # use ImageMagick
172 $cmd = $wgImageMagickConvertCommand .
173 " -quality 85 -geometry {$width} ".
174 escapeshellarg($this->imagePath) . " " .
175 escapeshellarg($thumbPath);
176 $conv = shell_exec( $cmd );
177 } else {
178 # Use PHP's builtin GD library functions.
179 #
180 # First find out what kind of file this is, and select the correct
181 # input routine for this.
182
183 $truecolor = false;
184
185 switch( $this->type ) {
186 case 1: # GIF
187 $src_image = imagecreatefromgif( $this->imagePath );
188 break;
189 case 2: # JPG
190 $src_image = imagecreatefromjpeg( $this->imagePath );
191 $truecolor = true;
192 break;
193 case 3: # PNG
194 $src_image = imagecreatefrompng( $this->imagePath );
195 $truecolor = ( $this->bits > 8 );
196 break;
197 case 15: # WBMP for WML
198 $src_image = imagecreatefromwbmp( $this->imagePath );
199 break;
200 case 16: # XBM
201 $src_image = imagecreatefromxbm( $this->imagePath );
202 break;
203 default:
204 return "Image type not supported";
205 break;
206 }
207 $height = floor( $this->height * ( $width/$this->width ) );
208 if ( $truecolor ) {
209 $dst_image = imagecreatetruecolor( $width, $height );
210 } else {
211 $dst_image = imagecreate( $width, $height );
212 }
213 imagecopyresampled( $dst_image, $src_image,
214 0,0,0,0,
215 $width, $height, $this->width, $this->height );
216 switch( $this->type ) {
217 case 1: # GIF
218 case 3: # PNG
219 case 15: # WBMP
220 case 16: # XBM
221 #$thumbUrl .= ".png";
222 #$thumbPath .= ".png";
223 imagepng( $dst_image, $thumbPath );
224 break;
225 case 2: # JPEG
226 #$thumbUrl .= ".jpg";
227 #$thumbPath .= ".jpg";
228 imageinterlace( $dst_image );
229 imagejpeg( $dst_image, $thumbPath, 95 );
230 break;
231 default:
232 break;
233 }
234 imagedestroy( $dst_image );
235 imagedestroy( $src_image );
236
237
238 }
239 #
240 # Check for zero-sized thumbnails. Those can be generated when
241 # no disk space is available or some other error occurs
242 #
243 $thumbstat = stat( $thumbPath );
244 if( $thumbstat["size"] == 0 )
245 {
246 unlink( $thumbPath );
247 }
248
249 }
250 return $thumbUrl;
251 } // END OF function createThumb
252
253 //**********************************************************************
254 // Return the image history of this image, line by line.
255 // start with current version, than old versions.
256 // use $this->historyLine to check which line to return:
257 // 0 return line for current version
258 // 1 query for old versions, return first one
259 // 2, ... return next old version from above query
260 function nextHistoryLine()
261 {
262 $fname = "Image::nextHistoryLine()";
263
264 if ( $this->historyLine == 0 ) // called for the first time, return line from cur
265 {
266 $sql = "SELECT img_size,img_description,img_user," .
267 "img_user_text,img_timestamp, '' AS oi_archive_name FROM image WHERE " .
268 "img_name='" . wfStrencode( $this->title->getDBkey() ) . "'";
269 $this->historyRes = wfQuery( $sql, DB_READ, $fname );
270
271 if ( 0 == wfNumRows( $this->historyRes ) ) { return FALSE; }
272
273 } else if ( $this->historyLine == 1 )
274 {
275 $sql = "SELECT oi_size AS img_size, oi_description AS img_description," .
276 "oi_user AS img_user," .
277 "oi_user_text AS img_user_text, oi_timestamp AS img_timestamp , oi_archive_name FROM oldimage WHERE " .
278 "oi_name='" . wfStrencode( $this->title->getDBkey() ) . "' " .
279 "ORDER BY oi_timestamp DESC";
280 $this->historyRes = wfQuery( $sql, DB_READ, $fname );
281 }
282 $this->historyLine ++;
283
284 return wfFetchObject( $this->historyRes );
285 }
286
287 function resetHistory()
288 {
289 $this->historyLine = 0;
290 }
291
292
293 } //class
294