web/wp-content/themes/aparatus/scripts/timthumb.php
changeset 1 0d28b7c10758
equal deleted inserted replaced
0:0d9a58d2c515 1:0d28b7c10758
       
     1 <?php
       
     2 /*
       
     3 	TimThumb script created by Tim McDaniels and Darren Hoyt with tweaks by Ben Gillbanks
       
     4 	http://code.google.com/p/timthumb/
       
     5 
       
     6 	MIT License: http://www.opensource.org/licenses/mit-license.php
       
     7 
       
     8 	Paramters
       
     9 	---------
       
    10 	w: width
       
    11 	h: height
       
    12 	zc: zoom crop (0 or 1)
       
    13 	q: quality (default is 75 and max is 100)
       
    14 	
       
    15 	HTML example: <img src="/scripts/timthumb.php?src=/images/whatever.jpg&w=150&h=200&zc=1" alt="" />
       
    16 */
       
    17 
       
    18 /*
       
    19 $sizeLimits = array(
       
    20 	"100x100",
       
    21 	"150x150",
       
    22 );
       
    23 */
       
    24 
       
    25 define("CACHE_SIZE", 200);		// number of files to store before clearing cache
       
    26 define("CACHE_CLEAR", 5);		// maximum number of files to delete on each cache clear
       
    27 define("VERSION", "1.08");		// version number (to force a cache refresh
       
    28 
       
    29 $imageFilters = array(
       
    30 	"1" => array(IMG_FILTER_NEGATE, 0),
       
    31 	"2" => array(IMG_FILTER_GRAYSCALE, 0),
       
    32 	"3" => array(IMG_FILTER_BRIGHTNESS, 1),
       
    33 	"4" => array(IMG_FILTER_CONTRAST, 1),
       
    34 	"5" => array(IMG_FILTER_COLORIZE, 4),
       
    35 	"6" => array(IMG_FILTER_EDGEDETECT, 0),
       
    36 	"7" => array(IMG_FILTER_EMBOSS, 0),
       
    37 	"8" => array(IMG_FILTER_GAUSSIAN_BLUR, 0),
       
    38 	"9" => array(IMG_FILTER_SELECTIVE_BLUR, 0),
       
    39 	"10" => array(IMG_FILTER_MEAN_REMOVAL, 0),
       
    40 	"11" => array(IMG_FILTER_SMOOTH, 0),
       
    41 );
       
    42 
       
    43 // sort out image source
       
    44 $src = get_request("src", "");
       
    45 if($src == "" || strlen($src) <= 3) {
       
    46 	displayError("no image specified");
       
    47 }
       
    48 
       
    49 // clean params before use
       
    50 $src = cleanSource($src);
       
    51 // last modified time (for caching)
       
    52 $lastModified = filemtime($src);
       
    53 
       
    54 // get properties
       
    55 $new_width 		= preg_replace("/[^0-9]+/", "", get_request("w", 0));
       
    56 $new_height 	= preg_replace("/[^0-9]+/", "", get_request("h", 0));
       
    57 $zoom_crop 		= preg_replace("/[^0-9]+/", "", get_request("zc", 1));
       
    58 $quality 		= preg_replace("/[^0-9]+/", "", get_request("q", 80));
       
    59 $filters		= get_request("f", "");
       
    60 
       
    61 if ($new_width == 0 && $new_height == 0) {
       
    62 	$new_width = 100;
       
    63 	$new_height = 100;
       
    64 }
       
    65 
       
    66 // set path to cache directory (default is ./cache)
       
    67 // this can be changed to a different location
       
    68 $cache_dir = './cache';
       
    69 
       
    70 // get mime type of src
       
    71 $mime_type = mime_type($src);
       
    72 
       
    73 // check to see if this image is in the cache already
       
    74 check_cache( $cache_dir, $mime_type );
       
    75 
       
    76 // if not in cache then clear some space and generate a new file
       
    77 cleanCache();
       
    78 
       
    79 ini_set('memory_limit', "30M");
       
    80 
       
    81 // make sure that the src is gif/jpg/png
       
    82 if(!valid_src_mime_type($mime_type)) {
       
    83 	displayError("Invalid src mime type: " .$mime_type);
       
    84 }
       
    85 
       
    86 // check to see if GD function exist
       
    87 if(!function_exists('imagecreatetruecolor')) {
       
    88 	displayError("GD Library Error: imagecreatetruecolor does not exist");
       
    89 }
       
    90 
       
    91 if(strlen($src) && file_exists($src)) {
       
    92 
       
    93 	// open the existing image
       
    94 	$image = open_image($mime_type, $src);
       
    95 	if($image === false) {
       
    96 		displayError('Unable to open image : ' . $src);
       
    97 	}
       
    98 
       
    99 	// Get original width and height
       
   100 	$width = imagesx($image);
       
   101 	$height = imagesy($image);
       
   102 	
       
   103 	// don't allow new width or height to be greater than the original
       
   104 	if( $new_width > $width ) {
       
   105 		$new_width = $width;
       
   106 	}
       
   107 	if( $new_height > $height ) {
       
   108 		$new_height = $height;
       
   109 	}
       
   110 
       
   111 	// generate new w/h if not provided
       
   112 	if( $new_width && !$new_height ) {
       
   113 		
       
   114 		$new_height = $height * ( $new_width / $width );
       
   115 		
       
   116 	} elseif($new_height && !$new_width) {
       
   117 		
       
   118 		$new_width = $width * ( $new_height / $height );
       
   119 		
       
   120 	} elseif(!$new_width && !$new_height) {
       
   121 		
       
   122 		$new_width = $width;
       
   123 		$new_height = $height;
       
   124 		
       
   125 	}
       
   126 	
       
   127 	// create a new true color image
       
   128 	$canvas = imagecreatetruecolor( $new_width, $new_height );
       
   129 	imagealphablending($canvas, false);
       
   130 	// Create a new transparent color for image
       
   131 	$color = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
       
   132 	// Completely fill the background of the new image with allocated color.
       
   133 	imagefill($canvas, 0, 0, $color);
       
   134 	// Restore transparency blending
       
   135 	imagesavealpha($canvas, true);
       
   136 
       
   137 	if( $zoom_crop ) {
       
   138 
       
   139 		$src_x = $src_y = 0;
       
   140 		$src_w = $width;
       
   141 		$src_h = $height;
       
   142 
       
   143 		$cmp_x = $width  / $new_width;
       
   144 		$cmp_y = $height / $new_height;
       
   145 
       
   146 		// calculate x or y coordinate and width or height of source
       
   147 
       
   148 		if ( $cmp_x > $cmp_y ) {
       
   149 
       
   150 			$src_w = round( ( $width / $cmp_x * $cmp_y ) );
       
   151 			$src_x = round( ( $width - ( $width / $cmp_x * $cmp_y ) ) / 2 );
       
   152 
       
   153 		} elseif ( $cmp_y > $cmp_x ) {
       
   154 
       
   155 			$src_h = round( ( $height / $cmp_y * $cmp_x ) );
       
   156 			$src_y = round( ( $height - ( $height / $cmp_y * $cmp_x ) ) / 2 );
       
   157 
       
   158 		}
       
   159 		
       
   160 		imagecopyresampled( $canvas, $image, 0, 0, $src_x, $src_y, $new_width, $new_height, $src_w, $src_h );
       
   161 
       
   162 	} else {
       
   163 
       
   164 		// copy and resize part of an image with resampling
       
   165 		imagecopyresampled( $canvas, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
       
   166 
       
   167 	}
       
   168 	
       
   169 	if ($filters != "") {
       
   170 		// apply filters to image
       
   171 		$filterList = explode("|", $filters);
       
   172 		foreach($filterList as $fl) {
       
   173 			$filterSettings = explode(",", $fl);
       
   174 			if(isset($imageFilters[$filterSettings[0]])) {
       
   175 			
       
   176 				for($i = 0; $i < 4; $i ++) {
       
   177 					if(!isset($filterSettings[$i])) {
       
   178 						$filterSettings[$i] = null;
       
   179 					}
       
   180 				}
       
   181 				
       
   182 				switch($imageFilters[$filterSettings[0]][1]) {
       
   183 				
       
   184 					case 1:
       
   185 					
       
   186 						imagefilter($canvas, $imageFilters[$filterSettings[0]][0], $filterSettings[1]);
       
   187 						break;
       
   188 					
       
   189 					case 2:
       
   190 					
       
   191 						imagefilter($canvas, $imageFilters[$filterSettings[0]][0], $filterSettings[1], $filterSettings[2]);
       
   192 						break;
       
   193 					
       
   194 					case 3:
       
   195 					
       
   196 						imagefilter($canvas, $imageFilters[$filterSettings[0]][0], $filterSettings[1], $filterSettings[2], $filterSettings[3]);
       
   197 						break;
       
   198 					
       
   199 					default:
       
   200 					
       
   201 						imagefilter($canvas, $imageFilters[$filterSettings[0]][0]);
       
   202 						break;
       
   203 						
       
   204 				}
       
   205 			}
       
   206 		}
       
   207 	}
       
   208 	
       
   209 	// output image to browser based on mime type
       
   210 	show_image($mime_type, $canvas, $cache_dir);
       
   211 	
       
   212 	// remove image from memory
       
   213 	imagedestroy($canvas);
       
   214 	
       
   215 } else {
       
   216 
       
   217 	if(strlen($src)) {
       
   218 		displayError("image " . $src . " not found");
       
   219 	} else {
       
   220 		displayError("no source specified");
       
   221 	}
       
   222 	
       
   223 }
       
   224 
       
   225 /**
       
   226  * 
       
   227  */
       
   228 function show_image($mime_type, $image_resized, $cache_dir) {
       
   229 
       
   230 	global $quality;
       
   231 
       
   232 	// check to see if we can write to the cache directory
       
   233 	$is_writable = 0;
       
   234 	$cache_file_name = $cache_dir . '/' . get_cache_file();
       
   235 
       
   236 	if(touch($cache_file_name)) {
       
   237 		
       
   238 		// give 666 permissions so that the developer 
       
   239 		// can overwrite web server user
       
   240 		chmod($cache_file_name, 0666);
       
   241 		$is_writable = 1;
       
   242 		
       
   243 	} else {
       
   244 		
       
   245 		$cache_file_name = NULL;
       
   246 		header('Content-type: ' . $mime_type);
       
   247 		
       
   248 	}
       
   249 
       
   250 	$quality = floor($quality * 0.09);
       
   251 
       
   252 	imagepng($image_resized, $cache_file_name, $quality);
       
   253 	
       
   254 	if($is_writable) {
       
   255 		show_cache_file($cache_dir, $mime_type);
       
   256 	}
       
   257 
       
   258 	imagedestroy($image_resized);
       
   259 	
       
   260 	displayError("error showing image");
       
   261 
       
   262 }
       
   263 
       
   264 /**
       
   265  * 
       
   266  */
       
   267 function get_request( $property, $default = 0 ) {
       
   268 	
       
   269 	if( isset($_REQUEST[$property]) ) {
       
   270 	
       
   271 		return $_REQUEST[$property];
       
   272 		
       
   273 	} else {
       
   274 	
       
   275 		return $default;
       
   276 		
       
   277 	}
       
   278 	
       
   279 }
       
   280 
       
   281 /**
       
   282  * 
       
   283  */
       
   284 function open_image($mime_type, $src) {
       
   285 
       
   286 	if(stristr($mime_type, 'gif')) {
       
   287 	
       
   288 		$image = imagecreatefromgif($src);
       
   289 		
       
   290 	} elseif(stristr($mime_type, 'jpeg')) {
       
   291 	
       
   292 		@ini_set('gd.jpeg_ignore_warning', 1);
       
   293 		$image = imagecreatefromjpeg($src);
       
   294 		
       
   295 	} elseif( stristr($mime_type, 'png')) {
       
   296 	
       
   297 		$image = imagecreatefrompng($src);
       
   298 		
       
   299 	}
       
   300 	
       
   301 	return $image;
       
   302 
       
   303 }
       
   304 
       
   305 /**
       
   306  * clean out old files from the cache
       
   307  * you can change the number of files to store and to delete per loop in the defines at the top of the code
       
   308  */
       
   309 function cleanCache() {
       
   310 
       
   311 	$files = glob("cache/*", GLOB_BRACE);
       
   312 	
       
   313 	$yesterday = time() - (24 * 60 * 60);
       
   314 	
       
   315 	if (count($files) > 0) {
       
   316 		
       
   317 		usort($files, "filemtime_compare");
       
   318 		$i = 0;
       
   319 		
       
   320 		if (count($files) > CACHE_SIZE) {
       
   321 			
       
   322 			foreach ($files as $file) {
       
   323 				
       
   324 				$i ++;
       
   325 				
       
   326 				if ($i >= CACHE_CLEAR) {
       
   327 					return;
       
   328 				}
       
   329 				
       
   330 				if (filemtime($file) > $yesterday) {
       
   331 					return;
       
   332 				}
       
   333 				
       
   334 				unlink($file);
       
   335 				
       
   336 			}
       
   337 			
       
   338 		}
       
   339 		
       
   340 	}
       
   341 
       
   342 }
       
   343 
       
   344 /**
       
   345  * compare the file time of two files
       
   346  */
       
   347 function filemtime_compare($a, $b) {
       
   348 
       
   349 	return filemtime($a) - filemtime($b);
       
   350 	
       
   351 }
       
   352 
       
   353 /**
       
   354  * determine the file mime type
       
   355  */
       
   356 function mime_type($file) {
       
   357 
       
   358 	if (stristr(PHP_OS, 'WIN')) { 
       
   359 		$os = 'WIN';
       
   360 	} else { 
       
   361 		$os = PHP_OS;
       
   362 	}
       
   363 
       
   364 	$mime_type = '';
       
   365 
       
   366 	if (function_exists('mime_content_type')) {
       
   367 		$mime_type = mime_content_type($file);
       
   368 	}
       
   369 	
       
   370 	// use PECL fileinfo to determine mime type
       
   371 	if (!valid_src_mime_type($mime_type)) {
       
   372 		if (function_exists('finfo_open')) {
       
   373 			$finfo = finfo_open(FILEINFO_MIME);
       
   374 			$mime_type = finfo_file($finfo, $file);
       
   375 			finfo_close($finfo);
       
   376 		}
       
   377 	}
       
   378 
       
   379 	// try to determine mime type by using unix file command
       
   380 	// this should not be executed on windows
       
   381     if (!valid_src_mime_type($mime_type) && $os != "WIN") {
       
   382 		if (preg_match("/FREEBSD|LINUX/", $os)) {
       
   383 			$mime_type = trim(@shell_exec('file -bi "' . $file . '"'));
       
   384 		}
       
   385 	}
       
   386 
       
   387 	// use file's extension to determine mime type
       
   388 	if (!valid_src_mime_type($mime_type)) {
       
   389 
       
   390 		// set defaults
       
   391 		$mime_type = 'image/png';
       
   392 		// file details
       
   393 		$fileDetails = pathinfo($file);
       
   394 		$ext = strtolower($fileDetails["extension"]);
       
   395 		// mime types
       
   396 		$types = array(
       
   397  			'jpg'  => 'image/jpeg',
       
   398  			'jpeg' => 'image/jpeg',
       
   399  			'png'  => 'image/png',
       
   400  			'gif'  => 'image/gif'
       
   401  		);
       
   402 		
       
   403 		if (strlen($ext) && strlen($types[$ext])) {
       
   404 			$mime_type = $types[$ext];
       
   405 		}
       
   406 		
       
   407 	}
       
   408 	
       
   409 	return $mime_type;
       
   410 
       
   411 }
       
   412 
       
   413 /**
       
   414  * 
       
   415  */
       
   416 function valid_src_mime_type($mime_type) {
       
   417 
       
   418 	if (preg_match("/jpg|jpeg|gif|png/i", $mime_type)) {
       
   419 		return true;
       
   420 	}
       
   421 	
       
   422 	return false;
       
   423 
       
   424 }
       
   425 
       
   426 /**
       
   427  * 
       
   428  */
       
   429 function check_cache($cache_dir, $mime_type) {
       
   430 
       
   431 	// make sure cache dir exists
       
   432 	if (!file_exists($cache_dir)) {
       
   433 		// give 777 permissions so that developer can overwrite
       
   434 		// files created by web server user
       
   435 		mkdir($cache_dir);
       
   436 		chmod($cache_dir, 0777);
       
   437 	}
       
   438 
       
   439 	show_cache_file($cache_dir, $mime_type);
       
   440 
       
   441 }
       
   442 
       
   443 /**
       
   444  * 
       
   445  */
       
   446 function show_cache_file($cache_dir) {
       
   447 
       
   448 	$cache_file = $cache_dir . '/' . get_cache_file();
       
   449 
       
   450 	if (file_exists($cache_file)) {
       
   451     	
       
   452 		$gmdate_mod = gmdate("D, d M Y H:i:s", filemtime($cache_file));
       
   453 		
       
   454 		if(! strstr($gmdate_mod, "GMT")) {
       
   455 			$gmdate_mod .= " GMT";
       
   456 		}
       
   457 		
       
   458 		if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
       
   459 		
       
   460 			// check for updates
       
   461 			$if_modified_since = preg_replace("/;.*$/", "", $_SERVER["HTTP_IF_MODIFIED_SINCE"]);
       
   462 			
       
   463 			if ($if_modified_since == $gmdate_mod) {
       
   464 				header("HTTP/1.1 304 Not Modified");
       
   465 				exit;
       
   466 			}
       
   467 
       
   468 		}
       
   469 		
       
   470 		$fileSize = filesize($cache_file);
       
   471 		
       
   472 		// send headers then display image
       
   473 		header("Content-Type: image/png");
       
   474 		header("Accept-Ranges: bytes");
       
   475 		header("Last-Modified: " . $gmdate_mod);
       
   476 		header("Content-Length: " . $fileSize);
       
   477 		header("Cache-Control: max-age=9999, must-revalidate");
       
   478 		header("Expires: " . $gmdate_mod);
       
   479 		
       
   480 		readfile($cache_file);
       
   481 		
       
   482 		exit;
       
   483 
       
   484 	}
       
   485 	
       
   486 }
       
   487 
       
   488 /**
       
   489  * 
       
   490  */
       
   491 function get_cache_file() {
       
   492 
       
   493 	global $lastModified;
       
   494 	static $cache_file;
       
   495 	
       
   496 	if(!$cache_file) {
       
   497 		$cachename = $_SERVER['QUERY_STRING'] . VERSION . $lastModified;
       
   498 		$cache_file = md5($cachename) . '.png';
       
   499 	}
       
   500 	
       
   501 	return $cache_file;
       
   502 
       
   503 }
       
   504 
       
   505 /**
       
   506  * check to if the url is valid or not
       
   507  */
       
   508 function valid_extension ($ext) {
       
   509 
       
   510 	if (preg_match("/jpg|jpeg|png|gif/i", $ext)) {
       
   511 		return TRUE;
       
   512 	} else {
       
   513 		return FALSE;
       
   514 	}
       
   515 	
       
   516 }
       
   517 
       
   518 /**
       
   519  * tidy up the image source url
       
   520  */
       
   521 function cleanSource($src) {
       
   522 
       
   523 	// remove slash from start of string
       
   524 	if(strpos($src, "/") == 0) {
       
   525 		$src = substr($src, -(strlen($src) - 1));
       
   526 	}
       
   527 
       
   528 	// remove http/ https/ ftp
       
   529 	$src = preg_replace("/^((ht|f)tp(s|):\/\/)/i", "", $src);
       
   530 	// remove domain name from the source url
       
   531 	$host = $_SERVER["HTTP_HOST"];
       
   532 	$src = str_replace($host, "", $src);
       
   533 	$host = str_replace("www.", "", $host);
       
   534 	$src = str_replace($host, "", $src);
       
   535 
       
   536 	// don't allow users the ability to use '../' 
       
   537 	// in order to gain access to files below document root
       
   538 
       
   539 	// src should be specified relative to document root like:
       
   540 	// src=images/img.jpg or src=/images/img.jpg
       
   541 	// not like:
       
   542 	// src=../images/img.jpg
       
   543 	$src = preg_replace("/\.\.+\//", "", $src);
       
   544 
       
   545 	//print_r($_SERVER);
       
   546 	
       
   547 	// get path to image on file system
       
   548 	$src = get_document_root($src) . '/' . $src;	
       
   549 
       
   550 	return $src;
       
   551 
       
   552 
       
   553 }
       
   554 
       
   555 /**
       
   556  * 
       
   557  */
       
   558 function get_document_root ($src) {
       
   559 
       
   560 	// check for unix servers
       
   561 	if(@file_exists($_SERVER['DOCUMENT_ROOT'] . '/' . $src)) {
       
   562 		return $_SERVER['DOCUMENT_ROOT'];
       
   563 	}
       
   564 	
       
   565 	// the relative paths below are useful if timthumb is moved outside of document root
       
   566 	// specifically if installed in wordpress themes like mimbo pro:
       
   567 	// /wp-content/themes/mimbopro/scripts/timthumb.php
       
   568 	$paths = array(
       
   569 		".",
       
   570 		"..",
       
   571 		"../..",
       
   572 		"../../..",
       
   573 		"../../../..",
       
   574 		"../../../../.."
       
   575 	);
       
   576 	
       
   577 	foreach($paths as $path) {
       
   578 		if(@file_exists($path . '/' . $src)) {
       
   579 			return $path;
       
   580 		}
       
   581 	}
       
   582 	
       
   583 	// special check for microsoft servers
       
   584 	if(!isset($_SERVER['DOCUMENT_ROOT'])) {
       
   585     	$path = str_replace("/", "\\", $_SERVER['ORIG_PATH_INFO']);
       
   586     	$path = str_replace($path, "", $_SERVER['SCRIPT_FILENAME']);
       
   587     	
       
   588     	if( @file_exists( $path . '/' . $src ) ) {
       
   589     		return $path;
       
   590     	}
       
   591 	}	
       
   592 	
       
   593 	displayError('file not found ' . $src);
       
   594 
       
   595 }
       
   596 
       
   597 /**
       
   598  * generic error message
       
   599  */
       
   600 function displayError($errorString = '') {
       
   601 
       
   602 	header('HTTP/1.1 400 Bad Request');
       
   603 	die($errorString);
       
   604 	
       
   605 }
       
   606 ?>