Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2012
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 17.27 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', 250);             // 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.09');             // 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.         // get path to image on file system
  546.         $src = get_document_root($src) . '/' . $src;    
  547.  
  548.         return $src;
  549.  
  550. }
  551.  
  552. /**
  553.  *
  554.  */
  555. function get_document_root ($src) {
  556.  
  557.         // check for unix servers
  558.         if(@file_exists($_SERVER['DOCUMENT_ROOT'] . '/' . $src)) {
  559.                 return $_SERVER['DOCUMENT_ROOT'];
  560.         }
  561.  
  562.         // check from script filename (to get all directories to timthumb location)
  563.         $parts = array_diff(explode('/', $_SERVER['SCRIPT_FILENAME']), explode('/', $_SERVER['DOCUMENT_ROOT']));
  564.         $path = $_SERVER['DOCUMENT_ROOT'] . '/';
  565.         foreach ($parts as $part) {
  566.                 $path .= $part . '/';
  567.                 if (file_exists($path . $src)) {
  568.                         return $path;
  569.                 }
  570.         }      
  571.  
  572.         // the relative paths below are useful if timthumb is moved outside of document root
  573.         // specifically if installed in wordpress themes like mimbo pro:
  574.         // /wp-content/themes/mimbopro/scripts/timthumb.php
  575.         $paths = array(
  576.                 ".",
  577.                 "..",
  578.                 "../..",
  579.                 "../../..",
  580.                 "../../../..",
  581.                 "../../../../.."
  582.         );
  583.  
  584.         foreach($paths as $path) {
  585.                 if(@file_exists($path . '/' . $src)) {
  586.                         return $path;
  587.                 }
  588.         }
  589.  
  590.         // special check for microsoft servers
  591.         if(!isset($_SERVER['DOCUMENT_ROOT'])) {
  592.         $path = str_replace("/", "\\", $_SERVER['ORIG_PATH_INFO']);
  593.         $path = str_replace($path, "", $_SERVER['SCRIPT_FILENAME']);
  594.  
  595.         if( @file_exists( $path . '/' . $src ) ) {
  596.                 return $path;
  597.         }
  598.         }      
  599.  
  600.         displayError('file not found ' . $src);
  601.  
  602. }
  603.  
  604. /**
  605.  * generic error message
  606.  */
  607. function displayError($errorString = '') {
  608.  
  609.         header('HTTP/1.1 400 Bad Request');
  610.         die($errorString);
  611.  
  612. }
  613. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement