Advertisement
codewildman

Untitled

Mar 1st, 2012
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.63 KB | None | 0 0
  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. // clean params before use
  49. $src = cleanSource($src);
  50.  
  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.  
  218. if(strlen($src)) {
  219. displayError("image " . $src . " not found");
  220. } else {
  221. displayError("no source specified");
  222. }
  223.  
  224. }
  225.  
  226. /**
  227. *
  228. */
  229. function show_image($mime_type, $image_resized, $cache_dir) {
  230.  
  231. global $quality;
  232.  
  233. // check to see if we can write to the cache directory
  234. $is_writable = 0;
  235. $cache_file_name = $cache_dir . '/' . get_cache_file();
  236.  
  237. if(touch($cache_file_name)) {
  238.  
  239. // give 666 permissions so that the developer
  240. // can overwrite web server user
  241. chmod($cache_file_name, 0666);
  242. $is_writable = 1;
  243.  
  244. } else {
  245.  
  246. $cache_file_name = NULL;
  247. header('Content-type: ' . $mime_type);
  248.  
  249. }
  250.  
  251. $quality = floor($quality * 0.09);
  252.  
  253. imagepng($image_resized, $cache_file_name, $quality);
  254.  
  255. if($is_writable) {
  256. show_cache_file($cache_dir, $mime_type);
  257. }
  258.  
  259. imagedestroy($image_resized);
  260.  
  261. displayError("error showing image");
  262.  
  263. }
  264.  
  265. /**
  266. *
  267. */
  268. function get_request( $property, $default = 0 ) {
  269.  
  270. if( isset($_REQUEST[$property]) ) {
  271.  
  272. return $_REQUEST[$property];
  273.  
  274. } else {
  275.  
  276. return $default;
  277.  
  278. }
  279.  
  280. }
  281.  
  282. /**
  283. *
  284. */
  285. function open_image($mime_type, $src) {
  286.  
  287. if(stristr($mime_type, 'gif')) {
  288.  
  289. $image = imagecreatefromgif($src);
  290.  
  291. } elseif(stristr($mime_type, 'jpeg')) {
  292.  
  293. @ini_set('gd.jpeg_ignore_warning', 1);
  294. $image = imagecreatefromjpeg($src);
  295.  
  296. } elseif( stristr($mime_type, 'png')) {
  297.  
  298. $image = imagecreatefrompng($src);
  299.  
  300. }
  301.  
  302. return $image;
  303.  
  304. }
  305.  
  306. /**
  307. * clean out old files from the cache
  308. * you can change the number of files to store and to delete per loop in the defines at the top of the code
  309. */
  310. function cleanCache() {
  311.  
  312. $files = glob("cache/*", GLOB_BRACE);
  313.  
  314. $yesterday = time() - (24 * 60 * 60);
  315.  
  316. if (count($files) > 0) {
  317.  
  318. usort($files, "filemtime_compare");
  319. $i = 0;
  320.  
  321. if (count($files) > CACHE_SIZE) {
  322.  
  323. foreach ($files as $file) {
  324.  
  325. $i ++;
  326.  
  327. if ($i >= CACHE_CLEAR) {
  328. return;
  329. }
  330.  
  331. if (filemtime($file) > $yesterday) {
  332. return;
  333. }
  334.  
  335. unlink($file);
  336.  
  337. }
  338.  
  339. }
  340.  
  341. }
  342.  
  343. }
  344.  
  345. /**
  346. * compare the file time of two files
  347. */
  348. function filemtime_compare($a, $b) {
  349.  
  350. return filemtime($a) - filemtime($b);
  351.  
  352. }
  353.  
  354. /**
  355. * determine the file mime type
  356. */
  357. function mime_type($file) {
  358.  
  359. if (stristr(PHP_OS, 'WIN')) {
  360. $os = 'WIN';
  361. } else {
  362. $os = PHP_OS;
  363. }
  364.  
  365. $mime_type = '';
  366.  
  367. if (function_exists('mime_content_type')) {
  368. $mime_type = mime_content_type($file);
  369. }
  370.  
  371. // use PECL fileinfo to determine mime type
  372. if (!valid_src_mime_type($mime_type)) {
  373. if (function_exists('finfo_open')) {
  374. $finfo = finfo_open(FILEINFO_MIME);
  375. $mime_type = finfo_file($finfo, $file);
  376. finfo_close($finfo);
  377. }
  378. }
  379.  
  380. // try to determine mime type by using unix file command
  381. // this should not be executed on windows
  382. if (!valid_src_mime_type($mime_type) && $os != "WIN") {
  383. if (preg_match("/FREEBSD|LINUX/", $os)) {
  384. $mime_type = trim(@shell_exec('file -bi "' . $file . '"'));
  385. }
  386. }
  387.  
  388. // use file's extension to determine mime type
  389. if (!valid_src_mime_type($mime_type)) {
  390.  
  391. // set defaults
  392. $mime_type = 'image/png';
  393. // file details
  394. $fileDetails = pathinfo($file);
  395. $ext = strtolower($fileDetails["extension"]);
  396. // mime types
  397. $types = array(
  398. 'jpg' => 'image/jpeg',
  399. 'jpeg' => 'image/jpeg',
  400. 'png' => 'image/png',
  401. 'gif' => 'image/gif'
  402. );
  403.  
  404. if (strlen($ext) && strlen($types[$ext])) {
  405. $mime_type = $types[$ext];
  406. }
  407.  
  408. }
  409.  
  410. return $mime_type;
  411.  
  412. }
  413.  
  414. /**
  415. *
  416. */
  417. function valid_src_mime_type($mime_type) {
  418.  
  419.  
  420. if (preg_match("/jpg|jpeg|gif|png/i", $mime_type)) {
  421. return true;
  422. }
  423.  
  424. return false;
  425.  
  426. }
  427.  
  428. /**
  429. *
  430. */
  431. function check_cache($cache_dir, $mime_type) {
  432.  
  433. // make sure cache dir exists
  434. if (!file_exists($cache_dir)) {
  435. // give 777 permissions so that developer can overwrite
  436. // files created by web server user
  437. mkdir($cache_dir);
  438. chmod($cache_dir, 0777);
  439. }
  440.  
  441. show_cache_file($cache_dir, $mime_type);
  442.  
  443. }
  444.  
  445. /**
  446. *
  447. */
  448. function show_cache_file($cache_dir) {
  449.  
  450. $cache_file = $cache_dir . '/' . get_cache_file();
  451.  
  452. if (file_exists($cache_file)) {
  453.  
  454. $gmdate_mod = gmdate("D, d M Y H:i:s", filemtime($cache_file));
  455.  
  456. if(! strstr($gmdate_mod, "GMT")) {
  457. $gmdate_mod .= " GMT";
  458. }
  459.  
  460. if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
  461.  
  462. // check for updates
  463. $if_modified_since = preg_replace("/;.*$/", "", $_SERVER["HTTP_IF_MODIFIED_SINCE"]);
  464.  
  465. if ($if_modified_since == $gmdate_mod) {
  466. header("HTTP/1.1 304 Not Modified");
  467. exit;
  468. }
  469.  
  470. }
  471.  
  472. $fileSize = filesize($cache_file);
  473.  
  474. // send headers then display image
  475. header("Content-Type: image/png");
  476. header("Accept-Ranges: bytes");
  477. header("Last-Modified: " . $gmdate_mod);
  478. header("Content-Length: " . $fileSize);
  479. header("Cache-Control: max-age=9999, must-revalidate");
  480. header("Expires: " . $gmdate_mod);
  481.  
  482. readfile($cache_file);
  483.  
  484. exit;
  485.  
  486. }
  487.  
  488. }
  489.  
  490. /**
  491. *
  492. */
  493. function get_cache_file() {
  494.  
  495. global $lastModified;
  496. static $cache_file;
  497.  
  498. if(!$cache_file) {
  499. $cachename = $_SERVER['QUERY_STRING'] . VERSION . $lastModified;
  500. $cache_file = md5($cachename) . '.png';
  501. }
  502.  
  503. return $cache_file;
  504.  
  505. }
  506.  
  507. /**
  508. * check to if the url is valid or not
  509. */
  510. function valid_extension ($ext) {
  511.  
  512. if (preg_match("/jpg|jpeg|png|gif/i", $ext)) {
  513. return TRUE;
  514. } else {
  515. return FALSE;
  516. }
  517.  
  518. }
  519.  
  520. /**
  521. * tidy up the image source url
  522. */
  523. function cleanSource($src) {
  524.  
  525. // remove slash from start of string
  526. if(strpos($src, "/") == 0) {
  527. $src = substr($src, -(strlen($src) - 1));
  528. }
  529.  
  530. // remove http/ https/ ftp
  531. $src = preg_replace("/^((ht|f)tp(s|):\/\/)/i", "", $src);
  532. // remove domain name from the source url
  533. $host = $_SERVER["HTTP_HOST"];
  534. $src = str_replace($host, "", $src);
  535. $host = str_replace("www.", "", $host);
  536. $src = str_replace($host, "", $src);
  537.  
  538. // don't allow users the ability to use '../'
  539. // in order to gain access to files below document root
  540.  
  541. // src should be specified relative to document root like:
  542. // src=images/img.jpg or src=/images/img.jpg
  543. // not like:
  544. // src=../images/img.jpg
  545. $src = preg_replace("/\.\.+\//", "", $src);
  546.  
  547. //print_r($_SERVER);
  548.  
  549. // get path to image on file system
  550. $src = get_document_root($src);
  551.  
  552. return $src;
  553.  
  554. }
  555.  
  556. /**
  557. *
  558. */
  559. function get_document_root ($src) {
  560.  
  561. // check for unix servers
  562. if(@file_exists($_SERVER['DOCUMENT_ROOT'] . '/' . $src)) {
  563. return $_SERVER['DOCUMENT_ROOT'] . '/' . $src;
  564. }
  565. $blog_id = $_REQUEST['bid'];
  566. $src = str_replace("/files/", "/wp-content/blogs.dir/$blog_id/files/", $src);
  567. if(@file_exists($src)) {
  568. return $src;
  569. }
  570.  
  571. $src_arr = explode('/',$src);
  572. for($i=0;$i<count($src_arr);$i++)
  573. {
  574. if($src_arr[$i]=='wp-content')
  575. {
  576. unset($src_arr[$i-1]);
  577. break;
  578. }
  579. }
  580. $str = implode('/',$src_arr);
  581.  
  582. if(@file_exists($_SERVER['DOCUMENT_ROOT'] . '/' . $str)) {
  583. return $_SERVER['DOCUMENT_ROOT'] . '/' . $str;
  584. }
  585.  
  586. $src_arr = explode('/',$src);
  587. unset($src_arr[0]);
  588. unset($src_arr[2]);
  589. $str = implode('/',$src_arr);
  590. if(@file_exists($_SERVER['DOCUMENT_ROOT'] . '/' . $str)) {
  591. return $_SERVER['DOCUMENT_ROOT'] . '/' . $str;
  592. }
  593.  
  594. $src_arr = explode('/',$src);
  595. unset($src_arr[0]);
  596. unset($src_arr[1]);
  597. $str = implode('/',$src_arr);
  598. if(@file_exists($_SERVER['DOCUMENT_ROOT'] . '/' . $str)) {
  599. return $_SERVER['DOCUMENT_ROOT'] . '/' . $str;
  600. }
  601. // the relative paths below are useful if timthumb is moved outside of document root
  602. // specifically if installed in wordpress themes like mimbo pro:
  603. // /wp-content/themes/mimbopro/scripts/timthumb.php
  604. $paths = array(
  605. ".",
  606. "..",
  607. "../..",
  608. "../../..",
  609. "../../../..",
  610. "../../../../.."
  611. );
  612.  
  613. foreach($paths as $path) {
  614. if(@file_exists($path . '/' . $src)) {
  615. return $path . '/' . $src;
  616. }
  617. }
  618.  
  619. // special check for microsoft servers
  620. if(!isset($_SERVER['DOCUMENT_ROOT'])) {
  621. $path = str_replace("/", "\\", $_SERVER['ORIG_PATH_INFO']);
  622. $path = str_replace($path, "", $_SERVER['SCRIPT_FILENAME']);
  623.  
  624. if( @file_exists( $path . '/' . $src ) ) {
  625. return $path . '/' . $src;
  626. }
  627. }
  628.  
  629. $src_arr = explode('/',$src);
  630. unset($src_arr[0]);
  631. unset($src_arr[1]);
  632. $src = implode('/',$src_arr);
  633. $paths = array(
  634. ".",
  635. "..",
  636. "../..",
  637. "../../..",
  638. "../../../..",
  639. "../../../../.."
  640. );
  641.  
  642. foreach($paths as $path) {
  643. if(@file_exists($path . '/' . $src)) {
  644. return $path . '/' . $src;
  645. }
  646. }
  647. displayError('file not found ' . $src);
  648.  
  649. }
  650.  
  651. /**
  652. * generic error message
  653. */
  654. function displayError($errorString = '') {
  655.  
  656. header('HTTP/1.1 400 Bad Request');
  657. die($errorString);
  658.  
  659. }
  660. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement