Advertisement
ETFovac

timthumb.php for 00webhost

Oct 28th, 2013
412
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 18.90 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. error_reporting(E_ALL);
  25. ini_set("display_errors", 1);
  26. */
  27.  
  28. // check to see if GD function exist
  29. if(!function_exists('imagecreatetruecolor')) {
  30.     displayError('GD Library Error: imagecreatetruecolor does not exist - please contact your webhost and ask them to install the GD library');
  31. }
  32.  
  33. define ('CACHE_SIZE', 250);                 // number of files to store before clearing cache
  34. define ('CACHE_CLEAR', 5);                  // maximum number of files to delete on each cache clear
  35. define ('VERSION', '1.14');                 // version number (to force a cache refresh)
  36. define ('DIRECTORY_CACHE', './cache');      // cache directory
  37. define ('DIRECTORY_TEMP', './temp');        // temp directory
  38.  
  39. if (function_exists('imagefilter') && defined('IMG_FILTER_NEGATE')) {
  40.     $imageFilters = array(
  41.         "1" => array(IMG_FILTER_NEGATE, 0),
  42.         "2" => array(IMG_FILTER_GRAYSCALE, 0),
  43.         "3" => array(IMG_FILTER_BRIGHTNESS, 1),
  44.         "4" => array(IMG_FILTER_CONTRAST, 1),
  45.         "5" => array(IMG_FILTER_COLORIZE, 4),
  46.         "6" => array(IMG_FILTER_EDGEDETECT, 0),
  47.         "7" => array(IMG_FILTER_EMBOSS, 0),
  48.         "8" => array(IMG_FILTER_GAUSSIAN_BLUR, 0),
  49.         "9" => array(IMG_FILTER_SELECTIVE_BLUR, 0),
  50.         "10" => array(IMG_FILTER_MEAN_REMOVAL, 0),
  51.         "11" => array(IMG_FILTER_SMOOTH, 0),
  52.     );
  53. }
  54.  
  55. // sort out image source
  56. $src = get_request("src", "");
  57. if($src == '' || strlen($src) <= 3) {
  58.     displayError ('no image specified');
  59. }
  60.  
  61. // clean params before use
  62. $src = cleanSource($src);
  63. // last modified time (for caching)
  64. $lastModified = filemtime($src);
  65.  
  66. // get properties
  67. $new_width         = preg_replace("/[^0-9]+/", '', get_request('w', 0));
  68. $new_height     = preg_replace("/[^0-9]+/", '', get_request('h', 0));
  69. $zoom_crop         = preg_replace("/[^0-9]+/", '', get_request('zc', 1));
  70. $quality         = preg_replace("/[^0-9]+/", '', get_request('q', 80));
  71. $filters        = get_request('f', '');
  72. $sharpen        = get_request('s', 0);
  73.  
  74. if ($new_width == 0 && $new_height == 0) {
  75.     $new_width = 100;
  76.     $new_height = 100;
  77. }
  78.  
  79. // get mime type of src
  80. $mime_type = mime_type($src);
  81.  
  82. // check to see if this image is in the cache already
  83. check_cache ($mime_type);
  84.  
  85. // if not in cache then clear some space and generate a new file
  86. cleanCache();
  87.  
  88. ini_set('memory_limit', '50M');
  89.  
  90. // make sure that the src is gif/jpg/png
  91. if(!valid_src_mime_type($mime_type)) {
  92.     displayError('Invalid src mime type: ' . $mime_type);
  93. }
  94.  
  95. if(strlen($src) && file_exists($src)) {
  96.  
  97.     // open the existing image
  98.     $image = open_image($mime_type, $src);
  99.     if($image === false) {
  100.         displayError('Unable to open image : ' . $src);
  101.     }
  102.  
  103.     // Get original width and height
  104.     $width = imagesx($image);
  105.     $height = imagesy($image);
  106.    
  107.     // generate new w/h if not provided
  108.     if( $new_width && !$new_height ) {
  109.        
  110.         $new_height = $height * ( $new_width / $width );
  111.        
  112.     } elseif($new_height && !$new_width) {
  113.        
  114.         $new_width = $width * ( $new_height / $height );
  115.        
  116.     } elseif(!$new_width && !$new_height) {
  117.        
  118.         $new_width = $width;
  119.         $new_height = $height;
  120.        
  121.     }
  122.    
  123.     // create a new true color image
  124.     $canvas = imagecreatetruecolor( $new_width, $new_height );
  125.     imagealphablending($canvas, false);
  126.     // Create a new transparent color for image
  127.     $color = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
  128.     // Completely fill the background of the new image with allocated color.
  129.     imagefill($canvas, 0, 0, $color);
  130.     // Restore transparency blending
  131.     imagesavealpha($canvas, true);
  132.  
  133.     if( $zoom_crop ) {
  134.  
  135.         $src_x = $src_y = 0;
  136.         $src_w = $width;
  137.         $src_h = $height;
  138.  
  139.         $cmp_x = $width  / $new_width;
  140.         $cmp_y = $height / $new_height;
  141.  
  142.         // calculate x or y coordinate and width or height of source
  143.  
  144.         if ( $cmp_x > $cmp_y ) {
  145.  
  146.             $src_w = round( ( $width / $cmp_x * $cmp_y ) );
  147.             $src_x = round( ( $width - ( $width / $cmp_x * $cmp_y ) ) / 2 );
  148.  
  149.         } elseif ( $cmp_y > $cmp_x ) {
  150.  
  151.             $src_h = round( ( $height / $cmp_y * $cmp_x ) );
  152.             $src_y = round( ( $height - ( $height / $cmp_y * $cmp_x ) ) / 2 );
  153.  
  154.         }
  155.        
  156.         imagecopyresampled( $canvas, $image, 0, 0, $src_x, $src_y, $new_width, $new_height, $src_w, $src_h );
  157.  
  158.     } else {
  159.  
  160.         // copy and resize part of an image with resampling
  161.         imagecopyresampled( $canvas, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
  162.  
  163.     }
  164.    
  165.     if ($filters != '' && function_exists('imagefilter') && defined('IMG_FILTER_NEGATE')) {
  166.         // apply filters to image
  167.         $filterList = explode("|", $filters);
  168.         foreach($filterList as $fl) {
  169.             $filterSettings = explode(",", $fl);
  170.             if(isset($imageFilters[$filterSettings[0]])) {
  171.            
  172.                 for($i = 0; $i < 4; $i ++) {
  173.                     if(!isset($filterSettings[$i])) {
  174.                         $filterSettings[$i] = null;
  175.                     }
  176.                 }
  177.                
  178.                 switch($imageFilters[$filterSettings[0]][1]) {
  179.                
  180.                     case 1:
  181.                    
  182.                         imagefilter($canvas, $imageFilters[$filterSettings[0]][0], $filterSettings[1]);
  183.                         break;
  184.                    
  185.                     case 2:
  186.                    
  187.                         imagefilter($canvas, $imageFilters[$filterSettings[0]][0], $filterSettings[1], $filterSettings[2]);
  188.                         break;
  189.                    
  190.                     case 3:
  191.                    
  192.                         imagefilter($canvas, $imageFilters[$filterSettings[0]][0], $filterSettings[1], $filterSettings[2], $filterSettings[3]);
  193.                         break;
  194.                    
  195.                     default:
  196.                    
  197.                         imagefilter($canvas, $imageFilters[$filterSettings[0]][0]);
  198.                         break;
  199.                        
  200.                 }
  201.             }
  202.         }
  203.     }
  204.    
  205.     if ($sharpen > 0 && function_exists('imageconvolution')) {
  206.    
  207.         $sharpenMatrix = array(
  208.             array(-1,-1,-1),
  209.             array(-1,16,-1),
  210.             array(-1,-1,-1),
  211.         );
  212.         $divisor = 8;
  213.         $offset = 0;
  214.  
  215.         imageconvolution($canvas, $sharpenMatrix, $divisor, $offset);
  216.    
  217.     }
  218.    
  219.     // output image to browser based on mime type
  220.     show_image($mime_type, $canvas);
  221.    
  222.     // remove image from memory
  223.     imagedestroy($canvas);
  224.    
  225. } else {
  226.  
  227.     if (strlen($src)) {
  228.         displayError ('image ' . $src . ' not found');
  229.     } else {
  230.         displayError ('no source specified');
  231.     }
  232.    
  233. }
  234.  
  235. /**
  236.  *
  237.  */
  238. function show_image($mime_type, $image_resized) {
  239.  
  240.     global $quality;
  241.  
  242.     // check to see if we can write to the cache directory
  243.     $is_writable = 0;
  244.     $cache_file_name = DIRECTORY_CACHE . '/' . get_cache_file();
  245.  
  246.     if (touch($cache_file_name)) {
  247.        
  248.         // give 666 permissions so that the developer
  249.         // can overwrite web server user
  250.         chmod ($cache_file_name, 0666);
  251.         $is_writable = 1;
  252.        
  253.     } else {
  254.        
  255.         $cache_file_name = NULL;
  256.         header ('Content-type: ' . $mime_type);
  257.        
  258.     }
  259.  
  260.     switch ($mime_type) {
  261.    
  262.         case 'image/jpeg':
  263.             imagejpeg($image_resized, $cache_file_name, $quality);
  264.             break;
  265.        
  266.         default :
  267.             $quality = floor ($quality * 0.09);
  268.             imagepng($image_resized, $cache_file_name, $quality);
  269.            
  270.     }
  271.    
  272.     if ($is_writable) {
  273.         show_cache_file ($mime_type);
  274.     }
  275.  
  276.     imagedestroy ($image_resized);
  277.    
  278.     displayError ('error showing image');
  279.  
  280. }
  281.  
  282. /**
  283.  *
  284.  */
  285. function get_request( $property, $default = 0 ) {
  286.    
  287.     if( isset($_REQUEST[$property]) ) {
  288.    
  289.         return $_REQUEST[$property];
  290.        
  291.     } else {
  292.    
  293.         return $default;
  294.        
  295.     }
  296.    
  297. }
  298.  
  299. /**
  300.  *
  301.  */
  302. function open_image($mime_type, $src) {
  303.  
  304.     $mime_type = strtolower($mime_type);
  305.    
  306.     if (stristr ($mime_type, 'gif')) {
  307.    
  308.         $image = imagecreatefromgif($src);
  309.        
  310.     } elseif (stristr($mime_type, 'jpeg')) {
  311.    
  312.         @ini_set ('gd.jpeg_ignore_warning', 1);
  313.         $image = imagecreatefromjpeg($src);
  314.        
  315.     } elseif (stristr ($mime_type, 'png')) {
  316.    
  317.         $image = imagecreatefrompng($src);
  318.        
  319.     }
  320.    
  321.     return $image;
  322.  
  323. }
  324.  
  325. /**
  326.  * clean out old files from the cache
  327.  * you can change the number of files to store and to delete per loop in the defines at the top of the code
  328.  */
  329. function cleanCache() {
  330.  
  331.     $files = glob("cache/*", GLOB_BRACE);
  332.    
  333.     if (count($files) > 0) {
  334.    
  335.         $yesterday = time() - (24 * 60 * 60);
  336.        
  337.         usort($files, 'filemtime_compare');
  338.         $i = 0;
  339.        
  340.         if (count($files) > CACHE_SIZE) {
  341.            
  342.             foreach ($files as $file) {
  343.                
  344.                 $i ++;
  345.                
  346.                 if ($i >= CACHE_CLEAR) {
  347.                     return;
  348.                 }
  349.                
  350.                 if (@filemtime($file) > $yesterday) {
  351.                     return;
  352.                 }
  353.                
  354.                 if (file_exists($file)) {
  355.                     unlink($file);
  356.                 }
  357.                
  358.             }
  359.            
  360.         }
  361.        
  362.     }
  363.  
  364. }
  365.  
  366.  
  367. /**
  368.  * compare the file time of two files
  369.  */
  370. function filemtime_compare($a, $b) {
  371.  
  372.     return filemtime($a) - filemtime($b);
  373.    
  374. }
  375.  
  376.  
  377. /**
  378.  * determine the file mime type
  379.  */
  380. function mime_type($file) {
  381.  
  382.     if (stristr(PHP_OS, 'WIN')) {
  383.         $os = 'WIN';
  384.     } else {
  385.         $os = PHP_OS;
  386.     }
  387.  
  388.     $mime_type = '';
  389.  
  390.     if (function_exists('mime_content_type') && $os != 'WIN') {
  391.         $mime_type = mime_content_type($file);
  392.     }
  393.    
  394.     // use PECL fileinfo to determine mime type
  395.     if (!valid_src_mime_type($mime_type)) {
  396.         if (function_exists('finfo_open')) {
  397.             $finfo = @finfo_open(FILEINFO_MIME);
  398.             if ($finfo != '') {
  399.                 $mime_type = finfo_file($finfo, $file);
  400.                 finfo_close($finfo);
  401.             }
  402.         }
  403.     }
  404.  
  405.     // try to determine mime type by using unix file command
  406.     // this should not be executed on windows
  407.     if (!valid_src_mime_type($mime_type) && $os != "WIN") {
  408.         if (preg_match("/FreeBSD|FREEBSD|LINUX/", $os)) {
  409.             $mime_type = trim(@shell_exec('file -bi ' . escapeshellarg($file)));
  410.         }
  411.     }
  412.  
  413.     // use file's extension to determine mime type
  414.     if (!valid_src_mime_type($mime_type)) {
  415.  
  416.         // set defaults
  417.         $mime_type = 'image/png';
  418.         // file details
  419.         $fileDetails = pathinfo($file);
  420.         $ext = strtolower($fileDetails["extension"]);
  421.         // mime types
  422.         $types = array(
  423.              'jpg'  => 'image/jpeg',
  424.              'jpeg' => 'image/jpeg',
  425.              'png'  => 'image/png',
  426.              'gif'  => 'image/gif'
  427.          );
  428.        
  429.         if (strlen($ext) && strlen($types[$ext])) {
  430.             $mime_type = $types[$ext];
  431.         }
  432.        
  433.     }
  434.    
  435.     return $mime_type;
  436.  
  437. }
  438.  
  439.  
  440. /**
  441.  *
  442.  */
  443. function valid_src_mime_type($mime_type) {
  444.  
  445.     if (preg_match("/jpg|jpeg|gif|png/i", $mime_type)) {
  446.         return true;
  447.     }
  448.    
  449.     return false;
  450.  
  451. }
  452.  
  453.  
  454. /**
  455.  *
  456.  */
  457. function check_cache ($mime_type) {
  458.  
  459.     // make sure cache dir exists
  460.     if (!file_exists(DIRECTORY_CACHE)) {
  461.         // give 777 permissions so that developer can overwrite
  462.         // files created by web server user
  463.         mkdir(DIRECTORY_CACHE);
  464.         chmod(DIRECTORY_CACHE, 0777);
  465.     }
  466.  
  467.     show_cache_file ($mime_type);
  468.  
  469. }
  470.  
  471.  
  472. /**
  473.  *
  474.  */
  475. function show_cache_file ($mime_type) {
  476.  
  477.     $cache_file = DIRECTORY_CACHE . '/' . get_cache_file();
  478.  
  479.     if (file_exists($cache_file)) {
  480.        
  481.         $gmdate_mod = gmdate("D, d M Y H:i:s", filemtime($cache_file));
  482.        
  483.         if(! strstr($gmdate_mod, "GMT")) {
  484.             $gmdate_mod .= " GMT";
  485.         }
  486.        
  487.         if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
  488.        
  489.             // check for updates
  490.             $if_modified_since = preg_replace ("/;.*$/", "", $_SERVER["HTTP_IF_MODIFIED_SINCE"]);
  491.            
  492.             if ($if_modified_since == $gmdate_mod) {
  493.                 header("HTTP/1.1 304 Not Modified");
  494.                 die();
  495.             }
  496.  
  497.        
  498.    
  499.    
  500.       }
  501.  
  502.         $fileSize = filesize ($cache_file);
  503.        
  504.         $buffer = file_get_contents($cache_file);
  505.  
  506.         ob_get_clean();
  507.         ob_start();
  508.  
  509.  
  510.  
  511.         header ('Last-Modified: ' . $gmdate_mod);
  512.         header ('Cache-Control: max-age=9999, must-revalidate');
  513.         header ('Expires: ' . $gmdate_mod);
  514.         header ('Accept-Ranges: bytes');
  515.         header ('Content-Type: ' . $mime_type);
  516.         header ('Content-Length: ' . $fileSize);
  517.  
  518.         echo $buffer;
  519.         $sContents = ob_get_contents();
  520.         ob_end_clean();
  521.         echo $sContents;
  522.    }  
  523.    
  524. }
  525.  
  526.  
  527. /**
  528.  *
  529.  */
  530. function get_cache_file() {
  531.  
  532.     global $lastModified;
  533.     static $cache_file;
  534.    
  535.     if (!$cache_file) {
  536.         $cachename = $_SERVER['QUERY_STRING'] . VERSION . $lastModified;
  537.         $cache_file = md5($cachename) . '.png';
  538.     }
  539.    
  540.     return $cache_file;
  541.  
  542. }
  543.  
  544.  
  545. /**
  546.  * check to if the url is valid or not
  547.  */
  548. function valid_extension ($ext) {
  549.  
  550.     if (preg_match("/jpg|jpeg|png|gif/i", $ext)) {
  551.         return TRUE;
  552.     } else {
  553.         return FALSE;
  554.     }
  555.    
  556. }
  557.  
  558.  
  559. /**
  560.  *
  561.  */
  562. function checkExternal ($src) {
  563.  
  564.     $allowedSites = array(
  565.         'flickr.com',
  566.         'picasa.com',
  567.         'blogger.com',
  568.         'wordpress.com',
  569.         'img.youtube.com',
  570.     );
  571.  
  572.     if (preg_match('/http:\/\//', $src) == true) {
  573.    
  574.         $url_info = parse_url ($src);
  575.        
  576.         $isAllowedSite = false;
  577.         foreach ($allowedSites as $site) {
  578.             $site = '/' . addslashes($site) . '/';
  579.             if (preg_match($site, $url_info['host']) == true) {
  580.                 $isAllowedSite = true;
  581.             }
  582.         }
  583.        
  584.         if ($isAllowedSite) {
  585.        
  586.             $fileDetails = pathinfo($src);
  587.             $ext = strtolower($fileDetails['extension']);
  588.            
  589.             $filename = md5($src);
  590.             $local_filepath = DIRECTORY_TEMP . '/' . $filename . '.' . $ext;
  591.            
  592.             if (!file_exists($local_filepath)) {
  593.                
  594.                 if (function_exists('curl_init')) {
  595.                
  596.                     $fh = fopen($local_filepath, 'w');
  597.                     $ch = curl_init($src);
  598.                    
  599.                     curl_setopt($ch, CURLOPT_URL, $src);
  600.                     curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  601.                     curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  602.                     curl_setopt($ch, CURLOPT_HEADER, 0);
  603.                     curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20041107 Firefox/1.0');
  604.                     curl_setopt($ch, CURLOPT_FILE, $fh);
  605.                    
  606.                     if (curl_exec($ch) === FALSE) {
  607.                         if (file_exists($local_filepath)) {
  608.                             unlink($local_filepath);
  609.                         }
  610.                         displayError('error reading file ' . $src . ' from remote host: ' . curl_error($ch));
  611.                     }
  612.                    
  613.                     curl_close($ch);
  614.                     fclose($fh);
  615.  
  616.                 } else {
  617.            
  618.                     if (!$img = file_get_contents($src)) {
  619.                         displayError('remote file for ' . $src . ' can not be accessed. It is likely that the file permissions are restricted');
  620.                     }
  621.                    
  622.                     if (file_put_contents($local_filepath, $img) == FALSE) {
  623.                         displayError('error writing temporary file');
  624.                     }
  625.                    
  626.                 }
  627.                
  628.                 if (!file_exists($local_filepath)) {
  629.                     displayError('local file for ' . $src . ' can not be created');
  630.                 }
  631.                
  632.             }
  633.            
  634.             $src = $local_filepath;
  635.            
  636.         } else {
  637.        
  638.             displayError('remote host "' . $url_info['host'] . '" not allowed');
  639.            
  640.         }
  641.        
  642.     }
  643.    
  644.     return $src;
  645.    
  646. }
  647.  
  648.  
  649. /**
  650.  * tidy up the image source url
  651.  */
  652. function cleanSource($src) {
  653.  
  654.     $host = str_replace('www.', '', $_SERVER['HTTP_HOST']);
  655.     $regex = "/^((ht|f)tp(s|):\/\/)(www\.|)" . $host . "/i";
  656.    
  657.     $src = preg_replace ($regex, '', $src);
  658.     $src = strip_tags ($src);
  659.     $src = checkExternal ($src);
  660.    
  661.     // remove slash from start of string
  662.     if (strpos($src, '/') === 0) {
  663.         $src = substr ($src, -(strlen($src) - 1));
  664.     }
  665.  
  666.     // don't allow users the ability to use '../'
  667.     // in order to gain access to files below document root
  668.     $src = preg_replace("/\.\.+\//", "", $src);
  669.    
  670.     // get path to image on file system
  671.     $src = get_document_root($src) . '/' . $src;
  672.  
  673.     return $src;
  674.  
  675. }
  676.  
  677.  
  678. /**
  679.  *
  680.  */
  681. function get_document_root ($src) {
  682.  
  683.     // check for unix servers
  684.     if(file_exists($_SERVER['DOCUMENT_ROOT'] . '/' . $src)) {
  685.         return $_SERVER['DOCUMENT_ROOT'];
  686.     }
  687.  
  688.     // check from script filename (to get all directories to timthumb location)
  689.     $parts = array_diff(explode('/', $_SERVER['SCRIPT_FILENAME']), explode('/', $_SERVER['DOCUMENT_ROOT']));
  690.     $path = $_SERVER['DOCUMENT_ROOT'];
  691.     foreach ($parts as $part) {
  692.         $path .= '/' . $part;
  693.         if (file_exists($path . '/' . $src)) {
  694.             return $path;
  695.         }
  696.     }    
  697.    
  698.     // the relative paths below are useful if timthumb is moved outside of document root
  699.     // specifically if installed in wordpress themes like mimbo pro:
  700.     // /wp-content/themes/mimbopro/scripts/timthumb.php
  701.     $paths = array(
  702.         ".",
  703.         "..",
  704.         "../..",
  705.         "../../..",
  706.         "../../../..",
  707.         "../../../../.."
  708.     );
  709.    
  710.     foreach ($paths as $path) {
  711.         if(file_exists($path . '/' . $src)) {
  712.             return $path;
  713.         }
  714.     }
  715.    
  716.     // special check for microsoft servers
  717.     if (!isset($_SERVER['DOCUMENT_ROOT'])) {
  718.         $path = str_replace("/", "\\", $_SERVER['ORIG_PATH_INFO']);
  719.         $path = str_replace($path, "", $_SERVER['SCRIPT_FILENAME']);
  720.        
  721.         if (file_exists($path . '/' . $src)) {
  722.             return $path;
  723.         }
  724.     }    
  725.    
  726.     displayError('file not found ' . $src);
  727.  
  728. }
  729.  
  730.  
  731. /**
  732.  * generic error message
  733.  */
  734. function displayError ($errorString = '') {
  735.  
  736.     header('HTTP/1.1 400 Bad Request');
  737.     echo '<pre>' . $errorString . '<br />TimThumb version : ' . VERSION . '</pre>';
  738.     die();
  739.    
  740. }
  741. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement