Advertisement
Guest User

mpalasis, osC2.3.1 product_thumb.php from contrib 8104

a guest
May 2nd, 2012
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 16.80 KB | None | 0 0
  1. <?php
  2.  
  3. // This is "On the Fly Thumbnailer with Caching Option" by Pallieter Koopmans.
  4. // Based on Marcello Colaruotolo (1.5.1) which builds upon Nathan Welch (1.5)
  5. // and Roberto Ghizzi. With improvements by @Quest WebDesign, http://atQuest.nl/,
  6. // Martijn Loeffen (browser-caching and thumbnail-cache-dir) and Richard Burford
  7. // aka psynaptic (admin control and documentation)
  8. //
  9. // Modified 2012-05-02 by mpalasis. (block '..' in paths, lock users into the DIR_WS_IMAGES folder,
  10. // make varnames clearer, modify modify_tn_path, remove unneeded calls to modify_tn_path)
  11. //
  12. // Scales product images dynamically, resulting in smaller file sizes, and keeps
  13. // proper image ratio.
  14. //
  15. // Used in conjunction with modified tep_image in html_output.php (see: readme.html).
  16. // get config values from the database
  17. require('includes/configure.php'); // include server parameters
  18. $server = DB_SERVER;
  19. $username = DB_SERVER_USERNAME;
  20. $password = DB_SERVER_PASSWORD;
  21. $database = DB_DATABASE;
  22. $connect = @mysql_connect($server, $username, $password) or http_headers('', 'Error,Database Connection');
  23. @mysql_select_db($database, $connect) or http_headers('', 'Error,Database Connection');
  24. $query = "select configuration_key as cfgKey, configuration_value as cfgValue from configuration where configuration_group_id='100'";
  25. $output = @mysql_query($query, $connect) or http_headers('', 'Error,Database Connection');
  26. while ($row = @mysql_fetch_array($output)) {
  27.   define($row['cfgKey'], $row['cfgValue']);
  28. }
  29.  
  30. // CONFIGURATION SETTINGS
  31. //
  32. // Server cache directory. Set the value below to true to generate resampled thumbnails
  33. // resulting in smoother-looking images. Not supported in GD ver. < 2.01
  34. $use_resampling = true;
  35. if (THUMBNAIL_USE_RESAMPLING === 'false') {
  36.   $use_resampling = false;
  37. }
  38. //
  39. // Create True Color Thumbnails? Better quality overall but set to false if you
  40. // have GD version < 2.01 or if creating transparent thumbnails.
  41. $use_truecolor = true;
  42. if (THUMBNAIL_TRUE_COLOUR === 'false') {
  43.   $use_truecolor = false;
  44. }
  45. //
  46. // Output GIFs as JPEGS? Set this option to true if you have GD version > 1.6
  47. // and want to output GIF thumbnails as JPGs instead of GIFs or PNGs. Note that your
  48. // GIF transparencies will not be retained in the thumbnail if you output them
  49. // as JPGs. If you have GD Library < 1.6 with GIF create support, GIFs will
  50. // be output as GIFs. Set the "matte" color below if setting this option to true.
  51. $gif_as_jpeg = false;
  52. if (THUMBNAIL_OUTPUT_JPEG === 'true') {
  53.   $gif_as_jpeg = true;
  54. }
  55. //
  56. // Cache Images on the server? Set to true if you want to save requested thumbnails
  57. // on disk. This will add to disk space but will save your processor from having to
  58. // create the thumbnail for every visitor.
  59. $tn_server_cache = true;
  60. if (THUMBNAIL_CACHE_SERVER === 'false') {
  61.   $tn_server_cache = false;
  62. }
  63. //
  64. // Thumbnail Path. If server-caching is enabled, specify a sub-directory
  65. // where the thumbnails should be kept. Use '' for the default images-directory,
  66. // which is /catalog/images/
  67. // Note: Make sure this path actually exists as a subdirectory and is writeable!
  68. $tn_path = THUMBNAIL_PATH; // The default is 'thumbnails/', should be chmod 777
  69. //
  70. // Cache Images in Browser-Cache? Set to true if you want browsers to be able to
  71. // cache viewed thumbnails in their own cache. This will save bandwidth for every
  72. // visitor that views the same thumbnail again. The default is true
  73. $tn_browser_cache = true;
  74. if (THUMBNAIL_CACHE_BROWSER === 'false') {
  75.   $tn_browser_cache = false;
  76. }
  77. //
  78. // Send a 404 http response when an image is not found
  79. // If set to false, will show a small error-image (as in version < 2.0.0)
  80. $use404 = true; // The default is true
  81. //
  82. // Define RGB Color Value for background matte color if outputting GIFs as JPEGs
  83. // Example: white is r=255, b=255, g=255; black is r=0, b=0, g=0; red is r=255, b=0, g=0;
  84. $tn_colours = explode(",", THUMBNAIL_BACKGROUND_MATTE);
  85. $r = $tn_colours[0];
  86. $g = $tn_colours[1];
  87. $b = $tn_colours[2];
  88. //
  89. // Allow the creation of thumbnail images that are larger than the original images:
  90. $allow_larger = false;
  91. if (THUMBNAIL_ALLOW_LARGER === 'true') {
  92.   $allow_larger = true;
  93. }
  94. //
  95. // If allow_larger is set to false, you can opt to output the original image:
  96. // Better leave it true if you want pixel_trans_* to work as expected
  97. $show_original = true;
  98. if (THUMBNAIL_SHOW_ORIGINAL == 'false') {
  99.   $show_original = false;
  100. }
  101. //
  102. // Set jpeg compression quality for resampled images.
  103. $jpeg_quality = THUMBNAIL_JPEG_COMPRESSION; // The default is 100.
  104. // END CONFIGURATION SETTINGS
  105. //
  106. // Note: In order to manually debug this script, you might want to comment
  107. // some header() lines -- otherwise no output is shown.
  108. // reverse strrchr(), taken from http://nl2.php.net/manual/en/function.strrchr.php
  109.  
  110. function reverse_strrchr($haystack, $needle) {
  111.   return strrpos($haystack, $needle)
  112.           ? substr($haystack, 0, strrpos($haystack, $needle) + 1)
  113.           : false;
  114. }
  115.  
  116. function modify_tn_path($file) {
  117.   global $tn_path;
  118.  
  119.   if ($tn_path == '')
  120.     return $file;
  121.   else {
  122.     return $tn_path . $file;
  123.   }
  124. }
  125.  
  126. function http_headers($file = '') {
  127.   //
  128.   // This function supports the use of browser-caching (optional)
  129.   //
  130.     // A 304 (Not Modified) will be sent when the thumbnail has not changed
  131.   //       since the time it was last cached by the client
  132.   // A 200 (OK) will be sent when the thumbnail was not cached by the client
  133.   //       or when the thumbnail was cached but changed afterwards
  134.   // A 404 (Not Found) will be sent when the thumbnail is not found (optional)
  135.   global $use404, $tn_browser_cache, $jpeg_quality, $w, $h;
  136.  
  137.   if (isset($_SERVER["SERVER_PROTOCOL"]) && $_SERVER["SERVER_PROTOCOL"] == "HTTP/1.1")
  138.     $httpProtocol = "HTTP/1.1";
  139.   else
  140.     $httpProtocol = "HTTP/1.0";
  141.  
  142.   if (is_readable($file)) {
  143.  
  144.     if (isset($_SERVER["HTTP_CACHE_CONTROL"])) {
  145.       $tn_browser_cache = strtolower($_SERVER["HTTP_CACHE_CONTROL"]) == "no-cache"
  146.               ? false
  147.               : $tn_browser_cache;
  148.     }
  149.  
  150.     //Build our entity tag, which is "inode-lastmodtime-filesize"
  151.     $lastModified = filemtime($file);
  152.     $lastModifiedGMT = $lastModified - date('Z');
  153.     $lastModifiedHttpFormat = gmstrftime("%a, %d %b %Y %T %Z", $lastModified);
  154.     // Don't use inode in eTag when you have multiple webservers, instead I use a dummy value (1fa44b7)
  155.     $eTag = '"1fa44b7-' . dechex(filesize($file)) . "-" . dechex($lastModifiedGMT) . '"';
  156.  
  157.     if ($tn_browser_cache) {
  158.  
  159.       $lastModifiedFromHttp = "xxx";
  160.       if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
  161.         $lastModifiedFromHttp = ($_SERVER["HTTP_IF_MODIFIED_SINCE"] === "")
  162.                 ? "xxx"
  163.                 : $_SERVER["HTTP_IF_MODIFIED_SINCE"];
  164.       }
  165.  
  166.       // Read sent eTag by browser
  167.       $foundETag = "";
  168.       if (isset($_SERVER["HTTP_IF_NONE_MATCH"])) {
  169.         $foundETag = stripslashes($_SERVER["HTTP_IF_NONE_MATCH"]);
  170.       }
  171.  
  172.       // Last Modification Time
  173.       if ($lastModifiedFromHttp == $lastModifiedHttpFormat) {
  174.         $sameLastModified = true;
  175.       } elseif (strpos($lastModifiedFromHttp, $lastModifiedHttpFormat) !== false) {
  176.         $sameLastModified = true;
  177.       } else {
  178.         $sameLastModified = false;
  179.       }
  180.  
  181.       if (($eTag == $foundETag) && $sameLastModified) {
  182.         // same eTag and Last Modification Time (e.g. with Firefox)
  183.         $is304 = true;
  184.       }
  185.       else
  186.       // no eTag supplied, but Last Modification Time is unchanged (e.g. with IE 6.0)
  187.         $is304 = (($foundETag == "") && $sameLastModified);
  188.  
  189.       if ($is304) {
  190.         //
  191.         // They already have an up to date copy so tell them
  192.         if ($lastModifiedGMT > 946080000) {        // 946080000 = Dec 24, 1999 4PM
  193.           // only send if valid eTag
  194.           header("ETag: " . $eTag);
  195.         }
  196.         header("Status: 304 Not Modified");
  197.         header($httpProtocol . " 304 Not Modified");
  198.         header("Connection: close");
  199.         exit();
  200.       }
  201.     }
  202.  
  203.     //
  204.     // We have to send them the whole page
  205.     header('Pragma: ');
  206.     header('Expires: ');
  207.     if ($tn_browser_cache) {
  208.       if ($lastModifiedGMT > 946080000) {        // 946080000 = Dec 24, 1999 4PM
  209.         header('ETag: ' . $eTag);
  210.       }
  211.       header('Last-Modified: ' . $lastModifiedHttpFormat);
  212.       header('Cache-Control: private');
  213.     } else {
  214.       header('Cache-Control: no-cache');
  215.     }
  216.   } else {
  217.     if ($use404) {
  218.       //
  219.       // send them a 404 http response header
  220.       header("TEST404: TEST404");
  221.       header("Status: 404 Not Found");
  222.       header($httpProtocol . " 404 Not Found");
  223.       exit();
  224.     } else {
  225.       //
  226.       // show a custom error-image (non-cacheable by the browser)
  227.       header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");    // Date in the past
  228.       header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // Always modified
  229.       header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
  230.       header("Cache-Control: post-check=0, pre-check=0", false);  // HTTP/1.1
  231.       header("Pragma: no-cache");          // HTTP/1.0
  232.       header('Content-type: image/jpeg');
  233.       $src = imagecreate($w, $h);      // Create a blank image.
  234.       $bgc = imagecolorallocate($src, 255, 255, 255);
  235.       $tc = imagecolorallocate($src, 0, 0, 0);
  236.       imagefilledrectangle($src, 0, 0, $w, $h, $bgc);
  237.       imagestring($src, 1, 5, 5, 'Error', $tc);
  238.       imagejpeg($src, '', $jpeg_quality);
  239.       imagedestroy($src);
  240.       exit();
  241.     }
  242.   }
  243. }
  244.  
  245. /**
  246.  * The FS path to...
  247.  */
  248. $FS_img = $_GET['img']; // the source image
  249. $FS_thumb = ''; // the thumbnail
  250. //paranoia is good.
  251. $FS_img = str_replace ( "../", "/", $FS_img); // don't permit goind 'up' (replace '../' with '/')
  252.  
  253. /**
  254.  * The WS path (relative to docroot?) to... (see also: $use_fs_paths)
  255.  */
  256. $WS_img = $FS_img; // the source image (this is sent to modify_tn_path)
  257. $WS_thumb = ''; // the thumbnail
  258.  
  259. /* more paranoia:
  260.  * allow usage of exact paths on the url, ie product_thumb.php?img=/images/foo/bar.jpg
  261.  * but ONLY for the DIR_WS_IMAGES folder.
  262.  * allow usage of relative paths on the url, ie product_thumb.php?img=images/foo/bar.jpg
  263.  * but ONLY for the DIR_WS_IMAGES folder.
  264.  * ignore any other requests.
  265.  */
  266. $use_fs_paths = true; //turn this into a configuration setting?...
  267. if ($use_fs_paths) {
  268.   if (substr_compare($FS_img, '/', 0, 1) === 0) {
  269.     if (substr_compare($FS_img, DIR_WS_IMAGES, 1, strlen(DIR_WS_IMAGES)) !== 0) {
  270.       exit(1);
  271.     }
  272.   } elseif (substr_compare($FS_img, DIR_WS_IMAGES, 0, strlen(DIR_WS_IMAGES)) !== 0) {
  273.     exit(2);
  274.   }
  275.  
  276.   $FS_img = DIR_FS_CATALOG . $FS_img;
  277. }
  278.  
  279. $FS_img = preg_replace('/\/\//', '/', $FS_img); // cleanup consecutive slashes
  280. $WS_img = preg_replace('/\/\//', '/', $WS_img); // cleanup consecutive slashes
  281.  
  282. $w = (int) $_GET['w'];
  283. $h = (int) $_GET['h'];
  284.  
  285. // check that the file exists and is world-readable
  286. if (!is_readable($FS_img) || !(fileperms($FS_img) & 0x0004)) { // http://php.net/manual/en/function.fileperms.php
  287.   exit(3);
  288. }
  289.  
  290. // Get the size of the image:
  291. $image = @getimagesize($FS_img);
  292.  
  293. // Check the input variables and decide what to do:
  294. if (empty($image) || empty($_GET['w']) || empty($_GET['h'])
  295.         || (empty($allow_larger) && ($w > $image[0] || $h > $image[1]))) {
  296.   if (empty($image) || empty($show_original)) {
  297.     http_headers();
  298.   } else {
  299.     // 2Do: Return the original image w/o making a copy (as that is what we currently do):
  300. //  $_GET['w'] = $image[0];
  301. //  $_GET['h'] = $image[1];
  302.   }
  303. }
  304.  
  305.  
  306.  
  307. // Create appropriate image header:
  308. if ($image[2] == 2 || ($image[2] == 1 && $gif_as_jpeg)) {
  309.   header('Content-type: image/jpeg');
  310.   if ($tn_server_cache)
  311.     $WS_thumb = modify_tn_path($WS_img . '.thumb_' . $w . 'x' . $h . '.jpg');
  312. }
  313. elseif ($image[2] == 1 && function_exists('imagegif')) {
  314.   header('Content-type: image/gif');
  315.   if ($tn_server_cache)
  316.     $WS_thumb = modify_tn_path($WS_img . '.thumb_' . $w . 'x' . $h . '.gif');
  317. }
  318. elseif ($image[2] == 3 || $image[2] == 1) {
  319.   header('Content-type: image/png');
  320.   if ($tn_server_cache)
  321.     $WS_thumb = modify_tn_path($WS_img . '.thumb_' . $w . 'x' . $h . '.png');
  322. }
  323.  
  324. if ($tn_server_cache) {
  325.   $FS_thumb = $WS_thumb;
  326.   if ($use_fs_paths) {
  327.     $FS_thumb = DIR_FS_CATALOG . $FS_thumb;
  328.   }
  329. }
  330.  
  331. // If you are required to set the full path for file_exists(), set this:
  332. // $filename = '/your/path/to/catalog/'.$filename;
  333. // Protect against visitors resizing images at will and eating up your server resources (only allows images up to 4x the original).
  334. if ($w < $image[0] * 4 && $h < $image[1] * 4) {
  335.  
  336.   if (is_readable($FS_thumb) && $tn_server_cache && filemtime($FS_thumb) > filemtime($FS_img)) {
  337.     // Output Cache Headers
  338.     http_headers($FS_thumb);
  339.  
  340.     ////// imagejpeg(), imagegif(), imagepng() will output the raw image stream if the second parameter is null
  341.     if ($image[2] == 2 || ($image[2] == 1 && $gif_as_jpeg)) {
  342.       $thumb_resource = imagecreatefromjpeg($FS_thumb);
  343.       imagejpeg($thumb_resource, '', $jpeg_quality);
  344.     } elseif ($image[2] == 1 && function_exists('imagegif')) {
  345.       $thumb_resource = imagecreatefromgif($FS_thumb);
  346.       imagegif($thumb_resource);
  347.     } elseif ($image[2] == 3 || $image[2] == 1) {
  348.       $thumb_resource = imagecreatefrompng($FS_thumb);
  349.       imagepng($thumb_resource);
  350.     } else {
  351.       // Not an image or imagecreatefrom...-function does not exits.
  352.       // Let's output an error
  353.       http_headers();
  354.     }
  355.   } else {
  356.     // create thumbnail directory if not exist.
  357.     //$tmp_path = str_replace(basename($filename), '', $filename);
  358.     $FS_path = dirname($FS_thumb);
  359.     if (is_dir($FS_path) == false) {
  360.       if (!mkdir($FS_path, 0755, true)) { // recursively create path to thumbnail
  361.         exit(4);
  362.       }
  363.     }
  364.     // Create a new, empty image based on settings:
  365.     if (function_exists('imagecreatetruecolor') && $use_truecolor && ($image[2] == 2 || $image[2] == 3)) {
  366.       $thumb_resource = imagecreatetruecolor($w, $h);
  367.     } else {
  368.       $thumb_resource = imagecreate($w, $h);
  369.     }
  370.  
  371.     $th_bg_color = imagecolorallocate($thumb_resource, $r, $g, $b);
  372.  
  373.     imagefill($thumb_resource, 0, 0, $th_bg_color);
  374.     imagecolortransparent($thumb_resource, $th_bg_color);
  375.  
  376.     // Create the image to be scaled:
  377.     if ($image[2] == 2 && function_exists('imagecreatefromjpeg')) {
  378.       $src_resource = imagecreatefromjpeg($FS_img);
  379.     } elseif ($image[2] == 1 && function_exists('imagecreatefromgif')) {
  380.       $src_resource = imagecreatefromgif($FS_img);
  381.     } elseif (($image[2] == 3 || $image[2] == 1) && function_exists('imagecreatefrompng')) {
  382.       $src_resource = imagecreatefrompng($FS_img);
  383.     } else {
  384.       // Not an image or imagecreatefrom...-function does not exist.
  385.       // Let's output an error
  386.       http_headers();
  387.     }
  388.  
  389.     // Scale the image based on settings:
  390.     if (empty($allow_larger) && ($w > $image[0] || $h > $image[1])) {
  391.       // existing image is smaller than thumbnail so create the thumbnail
  392.       // with the smaller original image centred on it
  393.       $dx = ($w - $image[0]) / 2;
  394.       $dy = ($h - $image[1]) / 2;
  395.       imagecopy($thumb_resource, $src_resource, $dx, $dy, 0, 0, $image[0], $image[1]);
  396.     } elseif (function_exists('imagecopyresampled') && $use_resampling) {
  397.       imagecopyresampled($thumb_resource, $src_resource, 0, 0, 0, 0, $w, $h, $image[0], $image[1]);
  398.     } else {
  399.       imagecopyresized($thumb_resource, $src_resource, 0, 0, 0, 0, $w, $h, $image[0], $image[1]);
  400.     }
  401.  
  402.     // Clear the image from memory:
  403.     imagedestroy($src_resource);
  404.  
  405.     // Output the image:
  406.     if ($image[2] == 2 || ($image[2] == 1 && $gif_as_jpeg)) {
  407.       if ($tn_server_cache) {
  408.         imagejpeg($thumb_resource, $FS_thumb, $jpeg_quality); //store the thumbnail
  409.         http_headers($FS_thumb);
  410.       } else {
  411.         http_headers($FS_img);
  412.       }
  413.       //Uhmm, I'm sure this could probably be improved, but leave it for now
  414.       imagejpeg($thumb_resource, '', $jpeg_quality); //output the thumbnail to the browser
  415.     } elseif ($image[2] == 1 && function_exists('imagegif')) {
  416.       if ($tn_server_cache) {
  417.         imagegif($thumb_resource, $FS_thumb); //store the thumbnail
  418.         http_headers($FS_thumb);
  419.       } else {
  420.         http_headers($FS_img);
  421.       }
  422.       imagegif($thumb_resource); //output the thumbnail to the browser
  423.     } elseif ($image[2] == 3 || $image[2] == 1) {
  424.       if ($tn_server_cache) {
  425.         imagepng($thumb_resource, $FS_thumb); //store the thumbnail
  426.         http_headers($FS_thumb);
  427.       } else {
  428.         http_headers($FS_img);
  429.       }
  430.       imagepng($thumb_resource); //output the thumbnail to the browser
  431.     } else {
  432.       // Not an image or image...-function not supported
  433.       // Let's output an error:
  434.       http_headers();
  435.     }
  436.  
  437.   }
  438.   // Clear the thumb from memory: (not really needed here since after this normally is the EOF.)
  439.   imagedestroy($thumb_resource);
  440. }
  441. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement