Minor changes and code cleanup (see rtehtmlarea ChangeLog and indexed_search ChangeLog)
[Packages/TYPO3.CMS.git] / t3lib / thumbs.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Generates a thumbnail and returns an image stream, either GIF/PNG or JPG
29 *
30 * $Id$
31 * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
32 *
33 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
34 */
35 /**
36 * [CLASS/FUNCTION INDEX of SCRIPT]
37 *
38 *
39 *
40 * 113: class SC_t3lib_thumbs
41 * 134: function init()
42 * 164: function main()
43 *
44 * SECTION: OTHER FUNCTIONS:
45 * 267: function errorGif($l1,$l2,$l3)
46 * 319: function fontGif($font)
47 * 366: function wrapFileName($inputName)
48 *
49 * TOTAL FUNCTIONS: 5
50 * (This index is automatically created/updated by the extension "extdeveval")
51 *
52 */
53
54
55 // *******************************
56 // Set error reporting
57 // *******************************
58 error_reporting (E_ALL ^ E_NOTICE);
59
60
61
62 // ******************
63 // Constants defined
64 // ******************
65 define('TYPO3_OS', stristr(PHP_OS,'win')&&!stristr(PHP_OS,'darwin')?'WIN':'');
66 define('TYPO3_MODE','BE');
67 if(!defined('PATH_thisScript')) define('PATH_thisScript',str_replace('//','/', str_replace('\\','/', (php_sapi_name()=='cgi'||php_sapi_name()=='isapi' ||php_sapi_name()=='cgi-fcgi')&&($_SERVER['ORIG_PATH_TRANSLATED']?$_SERVER['ORIG_PATH_TRANSLATED']:$_SERVER['PATH_TRANSLATED'])? ($_SERVER['ORIG_PATH_TRANSLATED']?$_SERVER['ORIG_PATH_TRANSLATED']:$_SERVER['PATH_TRANSLATED']):($_SERVER['ORIG_SCRIPT_FILENAME']?$_SERVER['ORIG_SCRIPT_FILENAME']:$_SERVER['SCRIPT_FILENAME']))));
68 if(!defined('PATH_site')) define('PATH_site', ereg_replace('[^/]*.[^/]*$','',PATH_thisScript)); // the path to the website folder (see init.php)
69 if(!defined('PATH_t3lib')) define('PATH_t3lib', PATH_site.'t3lib/');
70 define('PATH_typo3conf', PATH_site.'typo3conf/');
71 define('TYPO3_mainDir', 'typo3/'); // This is the directory of the backend administration for the sites of this TYPO3 installation.
72 define('PATH_typo3', PATH_site.TYPO3_mainDir);
73
74
75 // ******************
76 // Including config
77 // ******************
78 require_once(PATH_t3lib.'class.t3lib_div.php');
79 require_once(PATH_t3lib.'class.t3lib_extmgm.php');
80
81 require(PATH_t3lib.'config_default.php');
82 if (!defined ('TYPO3_db')) die ('The configuration file was not included.');
83 if (!$TYPO3_CONF_VARS['GFX']['image_processing']) die ('ImageProcessing was disabled!');
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 /**
102 * Class for generating a thumbnail from the input parameters given to the script
103 *
104 * Input GET var, &file: relative or absolute reference to an imagefile. WILL be validated against PATH_site / lockRootPath
105 * Input GET var, &size: integer-values defining size of thumbnail, format '[int]' or '[int]x[int]'
106 *
107 * Relative paths MUST BE the first two characters ONLY: eg: '../dir/file.gif', otherwise it is expect to be absolute
108 *
109 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
110 * @package TYPO3
111 * @subpackage t3lib
112 */
113 class SC_t3lib_thumbs {
114 var $include_once = array();
115
116 var $outdir = 'typo3temp/'; // The output directory of temporary files in PATH_site
117 var $output = '';
118 var $sizeDefault='56x56';
119
120 var $imageList; // Coming from $TYPO3_CONF_VARS['GFX']['imagefile_ext']
121 var $input; // Contains the absolute path to the file for which to make a thumbnail (after init())
122
123 // Internal, static: GPvar:
124 var $file; // Holds the input filename (GET: file)
125 var $size; // Holds the input size (GET: size)
126 var $mtime = 0; // Last modification time of the supplied file
127
128
129 /**
130 * Initialize; reading parameters with GPvar and checking file path
131 * Results in internal var, $this->input, being set to the absolute path of the file for which to make the thumbnail.
132 *
133 * @return void
134 */
135 function init() {
136 global $TYPO3_CONF_VARS;
137
138 // Setting GPvars:
139 $file = t3lib_div::_GP('file');
140 $size = t3lib_div::_GP('size');
141 $md5sum = t3lib_div::_GP('md5sum');
142
143 // Image extension list is set:
144 $this->imageList = $TYPO3_CONF_VARS['GFX']['imagefile_ext']; // valid extensions. OBS: No spaces in the list, all lowercase...
145
146 // If the filereference $this->file is relative, we correct the path
147 if (substr($file,0,3)=='../') {
148 $file = PATH_site.substr($file,3);
149 }
150
151 // Now the path is absolute.
152 // Checking for backpath and double slashes + the thumbnail can be made from files which are in the PATH_site OR the lockRootPath only!
153 if (t3lib_div::isAllowedAbsPath($file)) {
154 $mtime = filemtime($file);
155 }
156
157 // Do an MD5 check to prevent viewing of images without permission
158 $OK = FALSE;
159 if ($mtime) {
160 // Always use the absolute path for this check!
161 $check = basename($file).':'.$mtime.':'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
162 $md5_real = t3lib_div::shortMD5($check);
163 if (!strcmp($md5_real,$md5sum)) {
164 $OK = TRUE;
165 }
166 }
167
168 if ($OK) {
169 $this->input = $file;
170 $this->size = $size;
171 $this->mtime = $mtime;
172 } else {
173 die('Error: Image does not exist and/or MD5 checksum did not match.');
174 }
175 }
176
177 /**
178 * Create the thumbnail
179 * Will exit before return if all is well.
180 *
181 * @return void
182 */
183 function main() {
184 global $TYPO3_CONF_VARS;
185
186 // If file exists, we make a thumbsnail of the file.
187 if ($this->input && @file_exists($this->input)) {
188
189 // Check file extension:
190 $reg = array();
191 if (ereg('(.*)\.([^\.]*$)',$this->input,$reg)) {
192 $ext=strtolower($reg[2]);
193 $ext=($ext=='jpeg')?'jpg':$ext;
194 if ($ext=='ttf') {
195 $this->fontGif($this->input); // Make font preview... (will not return)
196 } elseif (!t3lib_div::inList($this->imageList, $ext)) {
197 $this->errorGif('Not imagefile!',$ext,basename($this->input));
198 }
199 } else {
200 $this->errorGif('Not imagefile!','No ext!',basename($this->input));
201 }
202
203 // ... so we passed the extension test meaning that we are going to make a thumbnail here:
204 if (!$this->size) $this->size = $this->sizeDefault; // default
205
206 // I added extra check, so that the size input option could not be fooled to pass other values. That means the value is exploded, evaluated to an integer and the imploded to [value]x[value]. Furthermore you can specify: size=340 and it'll be translated to 340x340.
207 $sizeParts = explode('x', $this->size.'x'.$this->size); // explodes the input size (and if no "x" is found this will add size again so it is the same for both dimensions)
208 $sizeParts = array(t3lib_div::intInRange($sizeParts[0],1,1000),t3lib_div::intInRange($sizeParts[1],1,1000)); // Cleaning it up, only two parameters now.
209 $this->size = implode('x',$sizeParts); // Imploding the cleaned size-value back to the internal variable
210 $sizeMax = max($sizeParts); // Getting max value
211
212 // Init
213 $outpath = PATH_site.$this->outdir;
214
215 // Should be - ? 'png' : 'gif' - , but doesn't work (ImageMagick prob.?)
216 // René: png work for me
217 $thmMode = t3lib_div::intInRange($TYPO3_CONF_VARS['GFX']['thumbnails_png'],0);
218 $outext = ($ext!='jpg' || ($thmMode & 2)) ? ($thmMode & 1 ? 'png' : 'gif') : 'jpg';
219
220 $outfile = 'tmb_'.substr(md5($this->input.$this->mtime.$this->size),0,10).'.'.$outext;
221 $this->output = $outpath.$outfile;
222
223 if ($TYPO3_CONF_VARS['GFX']['im']) {
224 // If thumbnail does not exist, we generate it
225 if (!@file_exists($this->output)) {
226 /* if (strstr($this->input,' ') || strstr($this->output,' ')) {
227 $this->errorGif('Spaces in','filepath',basename($this->input));
228 }
229 */ // 16 colors for small (56) thumbs, 64 for bigger and all for jpegs
230 if ($outext=='jpg') {
231 $colors = '';
232 } else {
233 $colors = ($sizeMax>56)?'-colors 64':'-colors 16';
234 }
235 $parameters = '-sample '.$this->size.' '.$colors.' '.$this->wrapFileName($this->input.'[0]').' '.$this->wrapFileName($this->output);
236 $cmd = t3lib_div::imageMagickCommand('convert', $parameters);
237 exec($cmd);
238 if (!@file_exists($this->output)) {
239 $this->errorGif('No thumb','generated!',basename($this->input));
240 }
241 }
242 // The thumbnail is read and output to the browser
243 if($fd = @fopen($this->output,'rb')) {
244 header('Content-type: image/'.$outext);
245 while (!feof($fd)) {
246 echo fread($fd, 10000);
247 }
248 fclose( $fd );
249 } else {
250 $this->errorGif('Read problem!','',$this->output);
251 }
252 } else exit;
253 } else {
254 $this->errorGif('No valid','inputfile!',basename($this->input));
255 }
256 }
257
258
259
260
261
262
263
264
265
266
267
268 /***************************
269 *
270 * OTHER FUNCTIONS:
271 *
272 ***************************/
273
274 /**
275 * Creates error image based on gfx/notfound_thumb.png
276 * Requires GD lib enabled, otherwise it will exit with the three textstrings outputted as text.
277 * Outputs the image stream to browser and exits!
278 *
279 * @param string Text line 1
280 * @param string Text line 2
281 * @param string Text line 3
282 * @return void
283 */
284 function errorGif($l1,$l2,$l3) {
285 global $TYPO3_CONF_VARS;
286
287 if (!$TYPO3_CONF_VARS['GFX']['gdlib']) die($l1.' '.$l2.' '.$l3);
288
289 // Creates the basis for the error image
290 if ($TYPO3_CONF_VARS['GFX']['gdlib_png']) {
291 header('Content-type: image/png');
292 $im = imagecreatefrompng(PATH_typo3.'gfx/notfound_thumb.png');
293 } else {
294 header('Content-type: image/gif');
295 $im = imagecreatefromgif(PATH_typo3.'gfx/notfound_thumb.gif');
296 }
297 // Sets background color and print color.
298 $white = imageColorAllocate($im, 0,0,0);
299 $black = imageColorAllocate($im, 255,255,0);
300
301 // Prints the text strings with the build-in font functions of GD
302 $x=0;
303 $font=0;
304 if ($l1) {
305 imagefilledrectangle($im, $x, 9, 56, 16, $black);
306 imageString($im,$font,$x,9,$l1,$white);
307 }
308 if ($l2) {
309 imagefilledrectangle($im, $x, 19, 56, 26, $black);
310 imageString($im,$font,$x,19,$l2,$white);
311 }
312 if ($l3) {
313 imagefilledrectangle($im, $x, 29, 56, 36, $black);
314 imageString($im,$font,$x,29,substr($l3,-14),$white);
315 }
316
317 // Outputting the image stream and exit
318 if ($TYPO3_CONF_VARS['GFX']['gdlib_png']) {
319 imagePng($im);
320 } else {
321 imageGif($im);
322 }
323 imagedestroy($im);
324 exit;
325 }
326
327 /**
328 * Creates a font-preview thumbnail.
329 * This means a PNG/GIF file with the text "AaBbCc...." set with the font-file given as input and in various sizes to show how the font looks
330 * Requires GD lib enabled.
331 * Outputs the image stream to browser and exits!
332 *
333 * @param string The filepath to the font file (absolute, probably)
334 * @return void
335 */
336 function fontGif($font) {
337 global $TYPO3_CONF_VARS;
338
339 if (!$TYPO3_CONF_VARS['GFX']['gdlib']) die('');
340
341 // Create image and set background color to white.
342 $im = imageCreate(250,76);
343 $white = imageColorAllocate($im, 255,255,255);
344 $col = imageColorAllocate($im, 0,0,0);
345
346 // The test string and offset in x-axis.
347 $string = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZzÆæØøÅåÄäÖöÜüß';
348 $x=13;
349
350 // Print (with non-ttf font) the size displayed
351 imagestring ($im, 1, 0, 2, '10', $col);
352 imagestring ($im, 1, 0, 15, '12', $col);
353 imagestring ($im, 1, 0, 30, '14', $col);
354 imagestring ($im, 1, 0, 47, '18', $col);
355 imagestring ($im, 1, 0, 68, '24', $col);
356
357 // Print with ttf-font the test string
358 imagettftext ($im, t3lib_div::freetypeDpiComp(10), 0, $x, 8, $col, $font, $string);
359 imagettftext ($im, t3lib_div::freetypeDpiComp(12), 0, $x, 21, $col, $font, $string);
360 imagettftext ($im, t3lib_div::freetypeDpiComp(14), 0, $x, 36, $col, $font, $string);
361 imagettftext ($im, t3lib_div::freetypeDpiComp(18), 0, $x, 53, $col, $font, $string);
362 imagettftext ($im, t3lib_div::freetypeDpiComp(24), 0, $x, 74, $col, $font, $string);
363
364 // Output PNG or GIF based on $TYPO3_CONF_VARS['GFX']['gdlib_png']
365 if ($TYPO3_CONF_VARS['GFX']['gdlib_png']) {
366 header('Content-type: image/png');
367 imagePng($im);
368 } else {
369 header('Content-type: image/gif');
370 imageGif($im);
371 }
372 imagedestroy($im);
373 exit;
374 }
375
376 /**
377 * Wrapping the input filename in double-quotes
378 *
379 * @param string Input filename
380 * @return string The output wrapped in "" (if there are spaces in the filepath)
381 * @access private
382 */
383 function wrapFileName($inputName) {
384 if (strstr($inputName,' ')) {
385 $inputName='"'.$inputName.'"';
386 }
387 return $inputName;
388 }
389 }
390
391 // Include extension class?
392 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/thumbs.php']) {
393 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/thumbs.php']);
394 }
395
396
397
398
399 // Make instance:
400 $SOBE = t3lib_div::makeInstance('SC_t3lib_thumbs');
401 $SOBE->init();
402 $SOBE->main();
403 ?>