PageRenderTime 57ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 1ms

/Vendor/phpThumb/phpthumb.class.php

https://bitbucket.org/aaoliveira/cakephp-phpthumb
PHP | 4092 lines | 3414 code | 434 blank | 244 comment | 762 complexity | db76b3cbc61b7801c8efdf78a949ec42 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. //////////////////////////////////////////////////////////////
  3. /// phpThumb() by James Heinrich <info@silisoftware.com> //
  4. // available at http://phpthumb.sourceforge.net ///
  5. //////////////////////////////////////////////////////////////
  6. /// //
  7. // See: phpthumb.readme.txt for usage instructions //
  8. // ///
  9. //////////////////////////////////////////////////////////////
  10. ob_start();
  11. if (!include_once(dirname(__FILE__).'/phpthumb.functions.php')) {
  12. ob_end_flush();
  13. die('failed to include_once("'.realpath(dirname(__FILE__).'/phpthumb.functions.php').'")');
  14. }
  15. ob_end_clean();
  16. class phpthumb {
  17. // public:
  18. // START PARAMETERS (for object mode and phpThumb.php)
  19. // See phpthumb.readme.txt for descriptions of what each of these values are
  20. var $src = null; // SouRCe filename
  21. var $new = null; // NEW image (phpThumb.php only)
  22. var $w = null; // Width
  23. var $h = null; // Height
  24. var $wp = null; // Width (Portrait Images Only)
  25. var $hp = null; // Height (Portrait Images Only)
  26. var $wl = null; // Width (Landscape Images Only)
  27. var $hl = null; // Height (Landscape Images Only)
  28. var $ws = null; // Width (Square Images Only)
  29. var $hs = null; // Height (Square Images Only)
  30. var $f = null; // output image Format
  31. var $q = 75; // jpeg output Quality
  32. var $sx = null; // Source crop top-left X position
  33. var $sy = null; // Source crop top-left Y position
  34. var $sw = null; // Source crop Width
  35. var $sh = null; // Source crop Height
  36. var $zc = null; // Zoom Crop
  37. var $bc = null; // Border Color
  38. var $bg = null; // BackGround color
  39. var $fltr = array(); // FiLTeRs
  40. var $goto = null; // GO TO url after processing
  41. var $err = null; // default ERRor image filename
  42. var $xto = null; // extract eXif Thumbnail Only
  43. var $ra = null; // Rotate by Angle
  44. var $ar = null; // Auto Rotate
  45. var $aoe = null; // Allow Output Enlargement
  46. var $far = null; // Fixed Aspect Ratio
  47. var $iar = null; // Ignore Aspect Ratio
  48. var $maxb = null; // MAXimum Bytes
  49. var $down = null; // DOWNload thumbnail filename
  50. var $md5s = null; // MD5 hash of Source image
  51. var $sfn = 0; // Source Frame Number
  52. var $dpi = 150; // Dots Per Inch for vector source formats
  53. var $sia = null; // Save Image As filename
  54. var $file = null; // >>>deprecated, DO NOT USE, will be removed in future versions<<<
  55. var $phpThumbDebug = null;
  56. // END PARAMETERS
  57. // public:
  58. // START CONFIGURATION OPTIONS (for object mode only)
  59. // See phpThumb.config.php for descriptions of what each of these settings do
  60. // * Directory Configuration
  61. var $config_cache_directory = null;
  62. var $config_cache_directory_depth = 0;
  63. var $config_cache_disable_warning = true;
  64. var $config_cache_source_enabled = false;
  65. var $config_cache_source_directory = null;
  66. var $config_temp_directory = null;
  67. var $config_document_root = null;
  68. // * Default output configuration:
  69. var $config_output_format = 'jpeg';
  70. var $config_output_maxwidth = 0;
  71. var $config_output_maxheight = 0;
  72. var $config_output_interlace = true;
  73. // * Error message configuration
  74. var $config_error_image_width = 400;
  75. var $config_error_image_height = 100;
  76. var $config_error_message_image_default = '';
  77. var $config_error_bgcolor = 'CCCCFF';
  78. var $config_error_textcolor = 'FF0000';
  79. var $config_error_fontsize = 1;
  80. var $config_error_die_on_error = false;
  81. var $config_error_silent_die_on_error = false;
  82. var $config_error_die_on_source_failure = true;
  83. // * Anti-Hotlink Configuration:
  84. var $config_nohotlink_enabled = true;
  85. var $config_nohotlink_valid_domains = array();
  86. var $config_nohotlink_erase_image = true;
  87. var $config_nohotlink_text_message = 'Off-server thumbnailing is not allowed';
  88. // * Off-server Linking Configuration:
  89. var $config_nooffsitelink_enabled = false;
  90. var $config_nooffsitelink_valid_domains = array();
  91. var $config_nooffsitelink_require_refer = false;
  92. var $config_nooffsitelink_erase_image = true;
  93. var $config_nooffsitelink_watermark_src = '';
  94. var $config_nooffsitelink_text_message = 'Off-server linking is not allowed';
  95. // * Border & Background default colors
  96. var $config_border_hexcolor = '000000';
  97. var $config_background_hexcolor = 'FFFFFF';
  98. // * TrueType Fonts
  99. var $config_ttf_directory = './fonts';
  100. var $config_max_source_pixels = null;
  101. var $config_use_exif_thumbnail_for_speed = false;
  102. var $allow_local_http_src = false;
  103. var $config_imagemagick_path = null;
  104. var $config_prefer_imagemagick = true;
  105. var $config_imagemagick_use_thumbnail = true;
  106. var $config_cache_maxage = null;
  107. var $config_cache_maxsize = null;
  108. var $config_cache_maxfiles = null;
  109. var $config_cache_source_filemtime_ignore_local = false;
  110. var $config_cache_source_filemtime_ignore_remote = true;
  111. var $config_cache_default_only_suffix = false;
  112. var $config_cache_force_passthru = true;
  113. var $config_cache_prefix = ''; // default value set in the constructor below
  114. // * MySQL
  115. var $config_mysql_query = null;
  116. var $config_mysql_hostname = null;
  117. var $config_mysql_username = null;
  118. var $config_mysql_password = null;
  119. var $config_mysql_database = null;
  120. // * Security
  121. var $config_high_security_enabled = false;
  122. var $config_high_security_password = null;
  123. var $config_disable_debug = true;
  124. var $config_allow_src_above_docroot = true;
  125. var $config_allow_src_above_phpthumb = true;
  126. // * HTTP fopen
  127. var $config_http_fopen_timeout = 10;
  128. var $config_http_follow_redirect = true;
  129. // * Compatability
  130. var $config_disable_pathinfo_parsing = false;
  131. var $config_disable_imagecopyresampled = false;
  132. var $config_disable_onlycreateable_passthru = false;
  133. var $config_http_user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7';
  134. // END CONFIGURATION OPTIONS
  135. // public: error messages (read-only; persistant)
  136. var $debugmessages = array();
  137. var $debugtiming = array();
  138. var $fatalerror = null;
  139. // private: (should not be modified directly)
  140. var $thumbnailQuality = 75;
  141. var $thumbnailFormat = null;
  142. var $sourceFilename = null;
  143. var $rawImageData = null;
  144. var $IMresizedData = null;
  145. var $outputImageData = null;
  146. var $useRawIMoutput = false;
  147. var $gdimg_output = null;
  148. var $gdimg_source = null;
  149. var $getimagesizeinfo = null;
  150. var $source_width = null;
  151. var $source_height = null;
  152. var $thumbnailCropX = null;
  153. var $thumbnailCropY = null;
  154. var $thumbnailCropW = null;
  155. var $thumbnailCropH = null;
  156. var $exif_thumbnail_width = null;
  157. var $exif_thumbnail_height = null;
  158. var $exif_thumbnail_type = null;
  159. var $exif_thumbnail_data = null;
  160. var $exif_raw_data = null;
  161. var $thumbnail_width = null;
  162. var $thumbnail_height = null;
  163. var $thumbnail_image_width = null;
  164. var $thumbnail_image_height = null;
  165. var $tempFilesToDelete = array();
  166. var $cache_filename = null;
  167. var $AlphaCapableFormats = array('png', 'ico', 'gif');
  168. var $is_alpha = false;
  169. var $iswindows = null;
  170. var $issafemode = null;
  171. var $phpthumb_version = '1.7.11-201108081537';
  172. //////////////////////////////////////////////////////////////////////
  173. // public: constructor
  174. function phpThumb() {
  175. $this->DebugTimingMessage('phpThumb() constructor', __FILE__, __LINE__);
  176. $this->DebugMessage('phpThumb() v'.$this->phpthumb_version, __FILE__, __LINE__);
  177. $this->config_max_source_pixels = round(max(intval(ini_get('memory_limit')), intval(get_cfg_var('memory_limit'))) * 1048576 * 0.20); // 20% of memory_limit
  178. $this->iswindows = (bool) (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN');
  179. $this->issafemode = (bool) preg_match('#(1|ON)#i', ini_get('safe_mode'));
  180. $this->config_document_root = (!empty($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : $this->config_document_root);
  181. $this->config_cache_prefix = ( isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'].'_' : '');
  182. $this->purgeTempFiles(); // purge existing temp files if re-initializing object
  183. $php_sapi_name = strtolower(function_exists('php_sapi_name') ? php_sapi_name() : '');
  184. if ($php_sapi_name == 'cli') {
  185. $this->config_allow_src_above_docroot = true;
  186. }
  187. }
  188. function __destruct() {
  189. $this->purgeTempFiles();
  190. }
  191. // public:
  192. function purgeTempFiles() {
  193. foreach ($this->tempFilesToDelete as $tempFileToDelete) {
  194. if (file_exists($tempFileToDelete)) {
  195. $this->DebugMessage('Deleting temp file "'.$tempFileToDelete.'"', __FILE__, __LINE__);
  196. @unlink($tempFileToDelete);
  197. }
  198. }
  199. $this->tempFilesToDelete = array();
  200. return true;
  201. }
  202. // public:
  203. function setSourceFilename($sourceFilename) {
  204. //$this->resetObject();
  205. //$this->rawImageData = null;
  206. $this->sourceFilename = $sourceFilename;
  207. $this->src = $sourceFilename;
  208. if (is_null($this->config_output_format)) {
  209. $sourceFileExtension = strtolower(substr(strrchr($sourceFilename, '.'), 1));
  210. if (preg_match('#^[a-z]{3,4}$#', $sourceFileExtension)) {
  211. $this->config_output_format = $sourceFileExtension;
  212. $this->DebugMessage('setSourceFilename('.$sourceFilename.') set $this->config_output_format to "'.$sourceFileExtension.'"', __FILE__, __LINE__);
  213. } else {
  214. $this->DebugMessage('setSourceFilename('.$sourceFilename.') did NOT set $this->config_output_format to "'.$sourceFileExtension.'" because it did not seem like an appropriate image format', __FILE__, __LINE__);
  215. }
  216. }
  217. $this->DebugMessage('setSourceFilename('.$sourceFilename.') set $this->sourceFilename to "'.$this->sourceFilename.'"', __FILE__, __LINE__);
  218. return true;
  219. }
  220. // public:
  221. function setSourceData($rawImageData, $sourceFilename='') {
  222. //$this->resetObject();
  223. //$this->sourceFilename = null;
  224. $this->rawImageData = $rawImageData;
  225. $this->DebugMessage('setSourceData() setting $this->rawImageData ('.strlen($this->rawImageData).' bytes; magic="'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).'))', __FILE__, __LINE__);
  226. if ($this->config_cache_source_enabled) {
  227. $sourceFilename = ($sourceFilename ? $sourceFilename : md5($rawImageData));
  228. if (!is_dir($this->config_cache_source_directory)) {
  229. $this->ErrorImage('$this->config_cache_source_directory ('.$this->config_cache_source_directory.') is not a directory');
  230. } elseif (!@is_writable($this->config_cache_source_directory)) {
  231. $this->ErrorImage('$this->config_cache_source_directory ('.$this->config_cache_source_directory.') is not writable');
  232. }
  233. $this->DebugMessage('setSourceData() attempting to save source image to "'.$this->config_cache_source_directory.DIRECTORY_SEPARATOR.urlencode($sourceFilename).'"', __FILE__, __LINE__);
  234. if ($fp = @fopen($this->config_cache_source_directory.DIRECTORY_SEPARATOR.urlencode($sourceFilename), 'wb')) {
  235. fwrite($fp, $rawImageData);
  236. fclose($fp);
  237. } elseif (!$this->phpThumbDebug) {
  238. $this->ErrorImage('setSourceData() failed to write to source cache ('.$this->config_cache_source_directory.DIRECTORY_SEPARATOR.urlencode($sourceFilename).')');
  239. }
  240. }
  241. return true;
  242. }
  243. // public:
  244. function setSourceImageResource($gdimg) {
  245. //$this->resetObject();
  246. $this->gdimg_source = $gdimg;
  247. return true;
  248. }
  249. // public:
  250. function setParameter($param, $value) {
  251. if ($param == 'src') {
  252. $this->setSourceFilename($this->ResolveFilenameToAbsolute($value));
  253. } elseif (@is_array($this->$param)) {
  254. if (is_array($value)) {
  255. foreach ($value as $arraykey => $arrayvalue) {
  256. array_push($this->$param, $arrayvalue);
  257. }
  258. } else {
  259. array_push($this->$param, $value);
  260. }
  261. } else {
  262. $this->$param = $value;
  263. }
  264. return true;
  265. }
  266. // public:
  267. function getParameter($param) {
  268. //if (property_exists('phpThumb', $param)) {
  269. return $this->$param;
  270. //}
  271. //$this->DebugMessage('setParameter() attempting to get non-existant parameter "'.$param.'"', __FILE__, __LINE__);
  272. //return false;
  273. }
  274. // public:
  275. function GenerateThumbnail() {
  276. $this->setOutputFormat();
  277. $this->phpThumbDebug('8a');
  278. $this->ResolveSource();
  279. $this->phpThumbDebug('8b');
  280. $this->SetCacheFilename();
  281. $this->phpThumbDebug('8c');
  282. $this->ExtractEXIFgetImageSize();
  283. $this->phpThumbDebug('8d');
  284. if ($this->useRawIMoutput) {
  285. $this->DebugMessage('Skipping rest of GenerateThumbnail() because ($this->useRawIMoutput == true)', __FILE__, __LINE__);
  286. return true;
  287. }
  288. $this->phpThumbDebug('8e');
  289. if (!$this->SourceImageToGD()) {
  290. $this->DebugMessage('SourceImageToGD() failed', __FILE__, __LINE__);
  291. return false;
  292. }
  293. $this->phpThumbDebug('8f');
  294. $this->Rotate();
  295. $this->phpThumbDebug('8g');
  296. $this->CreateGDoutput();
  297. $this->phpThumbDebug('8h');
  298. switch ($this->far) {
  299. case 'L':
  300. case 'TL':
  301. case 'BL':
  302. $destination_offset_x = 0;
  303. $destination_offset_y = round(($this->thumbnail_height - $this->thumbnail_image_height) / 2);
  304. break;
  305. case 'R':
  306. case 'TR':
  307. case 'BR':
  308. $destination_offset_x = round($this->thumbnail_width - $this->thumbnail_image_width);
  309. $destination_offset_y = round(($this->thumbnail_height - $this->thumbnail_image_height) / 2);
  310. break;
  311. case 'T':
  312. case 'TL':
  313. case 'TR':
  314. $destination_offset_x = round(($this->thumbnail_width - $this->thumbnail_image_width) / 2);
  315. $destination_offset_y = 0;
  316. break;
  317. case 'B':
  318. case 'BL':
  319. case 'BR':
  320. $destination_offset_x = round(($this->thumbnail_width - $this->thumbnail_image_width) / 2);
  321. $destination_offset_y = round($this->thumbnail_height - $this->thumbnail_image_height);
  322. break;
  323. case 'C':
  324. default:
  325. $destination_offset_x = round(($this->thumbnail_width - $this->thumbnail_image_width) / 2);
  326. $destination_offset_y = round(($this->thumbnail_height - $this->thumbnail_image_height) / 2);
  327. }
  328. // // copy/resize image to appropriate dimensions
  329. // $borderThickness = 0;
  330. // if (!empty($this->fltr)) {
  331. // foreach ($this->fltr as $key => $value) {
  332. // if (preg_match('#^bord\|([0-9]+)#', $value, $matches)) {
  333. // $borderThickness = $matches[1];
  334. // break;
  335. // }
  336. // }
  337. // }
  338. // if ($borderThickness > 0) {
  339. // //$this->DebugMessage('Skipping ImageResizeFunction() because BorderThickness="'.$borderThickness.'"', __FILE__, __LINE__);
  340. // $this->thumbnail_image_height /= 2;
  341. // }
  342. $this->ImageResizeFunction(
  343. $this->gdimg_output,
  344. $this->gdimg_source,
  345. $destination_offset_x,
  346. $destination_offset_y,
  347. $this->thumbnailCropX,
  348. $this->thumbnailCropY,
  349. $this->thumbnail_image_width,
  350. $this->thumbnail_image_height,
  351. $this->thumbnailCropW,
  352. $this->thumbnailCropH
  353. );
  354. $this->DebugMessage('memory_get_usage() after copy-resize = '.(function_exists('memory_get_usage') ? @memory_get_usage() : 'n/a'), __FILE__, __LINE__);
  355. ImageDestroy($this->gdimg_source);
  356. $this->DebugMessage('memory_get_usage() after ImageDestroy = '.(function_exists('memory_get_usage') ? @memory_get_usage() : 'n/a'), __FILE__, __LINE__);
  357. $this->phpThumbDebug('8i');
  358. $this->AntiOffsiteLinking();
  359. $this->phpThumbDebug('8j');
  360. $this->ApplyFilters();
  361. $this->phpThumbDebug('8k');
  362. $this->AlphaChannelFlatten();
  363. $this->phpThumbDebug('8l');
  364. $this->MaxFileSize();
  365. $this->phpThumbDebug('8m');
  366. $this->DebugMessage('GenerateThumbnail() completed successfully', __FILE__, __LINE__);
  367. return true;
  368. }
  369. // public:
  370. function RenderOutput() {
  371. if (!$this->useRawIMoutput && !is_resource($this->gdimg_output)) {
  372. $this->DebugMessage('RenderOutput() failed because !is_resource($this->gdimg_output)', __FILE__, __LINE__);
  373. return false;
  374. }
  375. if (!$this->thumbnailFormat) {
  376. $this->DebugMessage('RenderOutput() failed because $this->thumbnailFormat is empty', __FILE__, __LINE__);
  377. return false;
  378. }
  379. if ($this->useRawIMoutput) {
  380. $this->DebugMessage('RenderOutput copying $this->IMresizedData ('.strlen($this->IMresizedData).' bytes) to $this->outputImage', __FILE__, __LINE__);
  381. $this->outputImageData = $this->IMresizedData;
  382. return true;
  383. }
  384. $builtin_formats = array();
  385. if (function_exists('ImageTypes')) {
  386. $imagetypes = ImageTypes();
  387. $builtin_formats['wbmp'] = (bool) ($imagetypes & IMG_WBMP);
  388. $builtin_formats['jpg'] = (bool) ($imagetypes & IMG_JPG);
  389. $builtin_formats['gif'] = (bool) ($imagetypes & IMG_GIF);
  390. $builtin_formats['png'] = (bool) ($imagetypes & IMG_PNG);
  391. }
  392. $this->DebugMessage('RenderOutput() attempting Image'.strtoupper(@$this->thumbnailFormat).'($this->gdimg_output)', __FILE__, __LINE__);
  393. ob_start();
  394. switch ($this->thumbnailFormat) {
  395. case 'wbmp':
  396. if (!@$builtin_formats['wbmp']) {
  397. $this->DebugMessage('GD does not have required built-in support for WBMP output', __FILE__, __LINE__);
  398. ob_end_clean();
  399. return false;
  400. }
  401. ImageJPEG($this->gdimg_output, null, $this->thumbnailQuality);
  402. $this->outputImageData = ob_get_contents();
  403. break;
  404. case 'jpeg':
  405. case 'jpg': // should be "jpeg" not "jpg" but just in case...
  406. if (!@$builtin_formats['jpg']) {
  407. $this->DebugMessage('GD does not have required built-in support for JPEG output', __FILE__, __LINE__);
  408. ob_end_clean();
  409. return false;
  410. }
  411. ImageJPEG($this->gdimg_output, null, $this->thumbnailQuality);
  412. $this->outputImageData = ob_get_contents();
  413. break;
  414. case 'png':
  415. if (!@$builtin_formats['png']) {
  416. $this->DebugMessage('GD does not have required built-in support for PNG output', __FILE__, __LINE__);
  417. ob_end_clean();
  418. return false;
  419. }
  420. ImagePNG($this->gdimg_output);
  421. $this->outputImageData = ob_get_contents();
  422. break;
  423. case 'gif':
  424. if (!@$builtin_formats['gif']) {
  425. $this->DebugMessage('GD does not have required built-in support for GIF output', __FILE__, __LINE__);
  426. ob_end_clean();
  427. return false;
  428. }
  429. ImageGIF($this->gdimg_output);
  430. $this->outputImageData = ob_get_contents();
  431. break;
  432. case 'bmp':
  433. $ImageOutFunction = '"builtin BMP output"';
  434. if (!@include_once(dirname(__FILE__).'/phpthumb.bmp.php')) {
  435. $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__);
  436. ob_end_clean();
  437. return false;
  438. }
  439. $phpthumb_bmp = new phpthumb_bmp();
  440. $this->outputImageData = $phpthumb_bmp->GD2BMPstring($this->gdimg_output);
  441. unset($phpthumb_bmp);
  442. break;
  443. case 'ico':
  444. $ImageOutFunction = '"builtin ICO output"';
  445. if (!@include_once(dirname(__FILE__).'/phpthumb.ico.php')) {
  446. $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__);
  447. ob_end_clean();
  448. return false;
  449. }
  450. $phpthumb_ico = new phpthumb_ico();
  451. $arrayOfOutputImages = array($this->gdimg_output);
  452. $this->outputImageData = $phpthumb_ico->GD2ICOstring($arrayOfOutputImages);
  453. unset($phpthumb_ico);
  454. break;
  455. default:
  456. $this->DebugMessage('RenderOutput failed because $this->thumbnailFormat "'.$this->thumbnailFormat.'" is not valid', __FILE__, __LINE__);
  457. ob_end_clean();
  458. return false;
  459. }
  460. ob_end_clean();
  461. if (!$this->outputImageData) {
  462. $this->DebugMessage('RenderOutput() for "'.$this->thumbnailFormat.'" failed', __FILE__, __LINE__);
  463. ob_end_clean();
  464. return false;
  465. }
  466. $this->DebugMessage('RenderOutput() completing with $this->outputImageData = '.strlen($this->outputImageData).' bytes', __FILE__, __LINE__);
  467. return true;
  468. }
  469. // public:
  470. function RenderToFile($filename) {
  471. if (preg_match('#^(f|ht)tps?\://#i', $filename)) {
  472. $this->DebugMessage('RenderToFile() failed because $filename ('.$filename.') is a URL', __FILE__, __LINE__);
  473. return false;
  474. }
  475. // render thumbnail to this file only, do not cache, do not output to browser
  476. //$renderfilename = $this->ResolveFilenameToAbsolute(dirname($filename)).DIRECTORY_SEPARATOR.basename($filename);
  477. $renderfilename = $filename;
  478. if (($filename{0} != '/') && ($filename{0} != '\\') && ($filename{1} != ':')) {
  479. $renderfilename = $this->ResolveFilenameToAbsolute($renderfilename);
  480. }
  481. if (!@is_writable(dirname($renderfilename))) {
  482. $this->DebugMessage('RenderToFile() failed because "'.dirname($renderfilename).'/" is not writable', __FILE__, __LINE__);
  483. return false;
  484. }
  485. if (@is_file($renderfilename) && !@is_writable($renderfilename)) {
  486. $this->DebugMessage('RenderToFile() failed because "'.$renderfilename.'" is not writable', __FILE__, __LINE__);
  487. return false;
  488. }
  489. if ($this->RenderOutput()) {
  490. if (file_put_contents($renderfilename, $this->outputImageData)) {
  491. $this->DebugMessage('RenderToFile('.$renderfilename.') succeeded', __FILE__, __LINE__);
  492. return true;
  493. }
  494. if (!@file_exists($renderfilename)) {
  495. $this->DebugMessage('RenderOutput ['.$this->thumbnailFormat.'('.$renderfilename.')] did not appear to fail, but the output image does not exist either...', __FILE__, __LINE__);
  496. }
  497. } else {
  498. $this->DebugMessage('RenderOutput ['.$this->thumbnailFormat.'('.$renderfilename.')] failed', __FILE__, __LINE__);
  499. }
  500. return false;
  501. }
  502. // public:
  503. function OutputThumbnail() {
  504. $this->purgeTempFiles();
  505. if (!$this->useRawIMoutput && !is_resource($this->gdimg_output)) {
  506. $this->DebugMessage('OutputThumbnail() failed because !is_resource($this->gdimg_output)', __FILE__, __LINE__);
  507. return false;
  508. }
  509. if (headers_sent()) {
  510. return $this->ErrorImage('OutputThumbnail() failed - headers already sent');
  511. exit;
  512. }
  513. $downloadfilename = phpthumb_functions::SanitizeFilename(is_string($this->sia) ? $this->sia : ($this->down ? $this->down : 'phpThumb_generated_thumbnail'.'.'.$this->thumbnailFormat));
  514. $this->DebugMessage('Content-Disposition header filename set to "'.$downloadfilename.'"', __FILE__, __LINE__);
  515. if ($downloadfilename) {
  516. header('Content-Disposition: '.($this->down ? 'attachment' : 'inline').'; filename="'.$downloadfilename.'"');
  517. } else {
  518. $this->DebugMessage('failed to send Content-Disposition header because $downloadfilename is empty', __FILE__, __LINE__);
  519. }
  520. if ($this->useRawIMoutput) {
  521. header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
  522. echo $this->IMresizedData;
  523. } else {
  524. $this->DebugMessage('ImageInterlace($this->gdimg_output, '.intval($this->config_output_interlace).')', __FILE__, __LINE__);
  525. ImageInterlace($this->gdimg_output, intval($this->config_output_interlace));
  526. switch ($this->thumbnailFormat) {
  527. case 'jpeg':
  528. header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
  529. $ImageOutFunction = 'image'.$this->thumbnailFormat;
  530. @$ImageOutFunction($this->gdimg_output, '', $this->thumbnailQuality);
  531. break;
  532. case 'png':
  533. case 'gif':
  534. header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
  535. $ImageOutFunction = 'image'.$this->thumbnailFormat;
  536. @$ImageOutFunction($this->gdimg_output);
  537. break;
  538. case 'bmp':
  539. if (!@include_once(dirname(__FILE__).'/phpthumb.bmp.php')) {
  540. $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__);
  541. return false;
  542. }
  543. $phpthumb_bmp = new phpthumb_bmp();
  544. if (is_object($phpthumb_bmp)) {
  545. $bmp_data = $phpthumb_bmp->GD2BMPstring($this->gdimg_output);
  546. unset($phpthumb_bmp);
  547. if (!$bmp_data) {
  548. $this->DebugMessage('$phpthumb_bmp->GD2BMPstring() failed', __FILE__, __LINE__);
  549. return false;
  550. }
  551. header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
  552. echo $bmp_data;
  553. } else {
  554. $this->DebugMessage('new phpthumb_bmp() failed', __FILE__, __LINE__);
  555. return false;
  556. }
  557. break;
  558. case 'ico':
  559. if (!@include_once(dirname(__FILE__).'/phpthumb.ico.php')) {
  560. $this->DebugMessage('Error including "'.dirname(__FILE__).'/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__);
  561. return false;
  562. }
  563. $phpthumb_ico = new phpthumb_ico();
  564. if (is_object($phpthumb_ico)) {
  565. $arrayOfOutputImages = array($this->gdimg_output);
  566. $ico_data = $phpthumb_ico->GD2ICOstring($arrayOfOutputImages);
  567. unset($phpthumb_ico);
  568. if (!$ico_data) {
  569. $this->DebugMessage('$phpthumb_ico->GD2ICOstring() failed', __FILE__, __LINE__);
  570. return false;
  571. }
  572. header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
  573. echo $ico_data;
  574. } else {
  575. $this->DebugMessage('new phpthumb_ico() failed', __FILE__, __LINE__);
  576. return false;
  577. }
  578. break;
  579. default:
  580. $this->DebugMessage('OutputThumbnail failed because $this->thumbnailFormat "'.$this->thumbnailFormat.'" is not valid', __FILE__, __LINE__);
  581. return false;
  582. break;
  583. }
  584. }
  585. return true;
  586. }
  587. // public:
  588. function CleanUpCacheDirectory() {
  589. $this->DebugMessage('CleanUpCacheDirectory() set to purge ('.(is_null($this->config_cache_maxage) ? 'NULL' : number_format($this->config_cache_maxage / 86400, 1)).' days; '.(is_null($this->config_cache_maxsize) ? 'NULL' : number_format($this->config_cache_maxsize / 1048576, 2)).' MB; '.(is_null($this->config_cache_maxfiles) ? 'NULL' : number_format($this->config_cache_maxfiles)).' files)', __FILE__, __LINE__);
  590. if (!is_writable($this->config_cache_directory)) {
  591. $this->DebugMessage('CleanUpCacheDirectory() skipped because "'.$this->config_cache_directory.'" is not writable', __FILE__, __LINE__);
  592. return true;
  593. }
  594. // cache status of cache directory for 1 hour to avoid hammering the filesystem functions
  595. $phpThumbCacheStats_filename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheStats.txt';
  596. if (file_exists($phpThumbCacheStats_filename) && is_readable($phpThumbCacheStats_filename) && (filemtime($phpThumbCacheStats_filename) >= (time() - 3600))) {
  597. $this->DebugMessage('CleanUpCacheDirectory() skipped because "'.$phpThumbCacheStats_filename.'" is recently modified', __FILE__, __LINE__);
  598. return true;
  599. }
  600. touch($phpThumbCacheStats_filename);
  601. $DeletedKeys = array();
  602. $AllFilesInCacheDirectory = array();
  603. if (($this->config_cache_maxage > 0) || ($this->config_cache_maxsize > 0) || ($this->config_cache_maxfiles > 0)) {
  604. $CacheDirOldFilesAge = array();
  605. $CacheDirOldFilesSize = array();
  606. $AllFilesInCacheDirectory = phpthumb_functions::GetAllFilesInSubfolders($this->config_cache_directory);
  607. foreach ($AllFilesInCacheDirectory as $fullfilename) {
  608. if (preg_match('#^'.preg_quote($this->config_cache_prefix).'#i', $fullfilename) && file_exists($fullfilename)) {
  609. $CacheDirOldFilesAge[$fullfilename] = @fileatime($fullfilename);
  610. if ($CacheDirOldFilesAge[$fullfilename] == 0) {
  611. $CacheDirOldFilesAge[$fullfilename] = @filemtime($fullfilename);
  612. }
  613. $CacheDirOldFilesSize[$fullfilename] = @filesize($fullfilename);
  614. }
  615. }
  616. if (empty($CacheDirOldFilesSize)) {
  617. return true;
  618. }
  619. $DeletedKeys['zerobyte'] = array();
  620. foreach ($CacheDirOldFilesSize as $fullfilename => $filesize) {
  621. // purge all zero-size files more than an hour old (to prevent trying to delete just-created and/or in-use files)
  622. $cutofftime = time() - 3600;
  623. if (($filesize == 0) && ($CacheDirOldFilesAge[$fullfilename] < $cutofftime)) {
  624. $this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
  625. if (@unlink($fullfilename)) {
  626. $DeletedKeys['zerobyte'][] = $fullfilename;
  627. unset($CacheDirOldFilesSize[$fullfilename]);
  628. unset($CacheDirOldFilesAge[$fullfilename]);
  629. }
  630. }
  631. }
  632. $this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['zerobyte']).' zero-byte files', __FILE__, __LINE__);
  633. asort($CacheDirOldFilesAge);
  634. if ($this->config_cache_maxfiles > 0) {
  635. $TotalCachedFiles = count($CacheDirOldFilesAge);
  636. $DeletedKeys['maxfiles'] = array();
  637. foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) {
  638. if ($TotalCachedFiles > $this->config_cache_maxfiles) {
  639. $this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
  640. if (@unlink($fullfilename)) {
  641. $TotalCachedFiles--;
  642. $DeletedKeys['maxfiles'][] = $fullfilename;
  643. }
  644. } else {
  645. // there are few enough files to keep the rest
  646. break;
  647. }
  648. }
  649. $this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['maxfiles']).' files based on (config_cache_maxfiles='.$this->config_cache_maxfiles.')', __FILE__, __LINE__);
  650. foreach ($DeletedKeys['maxfiles'] as $fullfilename) {
  651. unset($CacheDirOldFilesAge[$fullfilename]);
  652. unset($CacheDirOldFilesSize[$fullfilename]);
  653. }
  654. }
  655. if ($this->config_cache_maxage > 0) {
  656. $mindate = time() - $this->config_cache_maxage;
  657. $DeletedKeys['maxage'] = array();
  658. foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) {
  659. if ($filedate > 0) {
  660. if ($filedate < $mindate) {
  661. $this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
  662. if (@unlink($fullfilename)) {
  663. $DeletedKeys['maxage'][] = $fullfilename;
  664. }
  665. } else {
  666. // the rest of the files are new enough to keep
  667. break;
  668. }
  669. }
  670. }
  671. $this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['maxage']).' files based on (config_cache_maxage='.$this->config_cache_maxage.')', __FILE__, __LINE__);
  672. foreach ($DeletedKeys['maxage'] as $fullfilename) {
  673. unset($CacheDirOldFilesAge[$fullfilename]);
  674. unset($CacheDirOldFilesSize[$fullfilename]);
  675. }
  676. }
  677. if ($this->config_cache_maxsize > 0) {
  678. $TotalCachedFileSize = array_sum($CacheDirOldFilesSize);
  679. $DeletedKeys['maxsize'] = array();
  680. foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) {
  681. if ($TotalCachedFileSize > $this->config_cache_maxsize) {
  682. $this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
  683. if (@unlink($fullfilename)) {
  684. $TotalCachedFileSize -= $CacheDirOldFilesSize[$fullfilename];
  685. $DeletedKeys['maxsize'][] = $fullfilename;
  686. }
  687. } else {
  688. // the total filesizes are small enough to keep the rest of the files
  689. break;
  690. }
  691. }
  692. $this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['maxsize']).' files based on (config_cache_maxsize='.$this->config_cache_maxsize.')', __FILE__, __LINE__);
  693. foreach ($DeletedKeys['maxsize'] as $fullfilename) {
  694. unset($CacheDirOldFilesAge[$fullfilename]);
  695. unset($CacheDirOldFilesSize[$fullfilename]);
  696. }
  697. }
  698. } else {
  699. $this->DebugMessage('skipping CleanUpCacheDirectory() because config set to not use it', __FILE__, __LINE__);
  700. }
  701. $totalpurged = 0;
  702. foreach ($DeletedKeys as $key => $value) {
  703. $totalpurged += count($value);
  704. }
  705. $this->DebugMessage('CleanUpCacheDirectory() purged '.$totalpurged.' files (from '.count($AllFilesInCacheDirectory).') based on config settings', __FILE__, __LINE__);
  706. if ($totalpurged > 0) {
  707. $empty_dirs = array();
  708. foreach ($AllFilesInCacheDirectory as $fullfilename) {
  709. if (is_dir($fullfilename)) {
  710. $empty_dirs[realpath($fullfilename)] = 1;
  711. } else {
  712. unset($empty_dirs[realpath(dirname($fullfilename))]);
  713. }
  714. }
  715. krsort($empty_dirs);
  716. $totalpurgeddirs = 0;
  717. foreach ($empty_dirs as $empty_dir => $dummy) {
  718. if ($empty_dir == $this->config_cache_directory) {
  719. // shouldn't happen, but just in case, don't let it delete actual cache directory
  720. continue;
  721. } elseif (@rmdir($empty_dir)) {
  722. $totalpurgeddirs++;
  723. } else {
  724. $this->DebugMessage('failed to rmdir('.$empty_dir.')', __FILE__, __LINE__);
  725. }
  726. }
  727. $this->DebugMessage('purged '.$totalpurgeddirs.' empty directories', __FILE__, __LINE__);
  728. }
  729. return true;
  730. }
  731. //////////////////////////////////////////////////////////////////////
  732. // private: re-initializator (call between rendering multiple images with one object)
  733. function resetObject() {
  734. $class_vars = get_class_vars(get_class($this));
  735. foreach ($class_vars as $key => $value) {
  736. // do not clobber debug or config info
  737. if (!preg_match('#^(config_|debug|fatalerror)#i', $key)) {
  738. $this->$key = $value;
  739. }
  740. }
  741. $this->phpThumb(); // re-initialize some class variables
  742. return true;
  743. }
  744. //////////////////////////////////////////////////////////////////////
  745. function ResolveSource() {
  746. if (is_resource($this->gdimg_source)) {
  747. $this->DebugMessage('ResolveSource() exiting because is_resource($this->gdimg_source)', __FILE__, __LINE__);
  748. return true;
  749. }
  750. if ($this->rawImageData) {
  751. $this->sourceFilename = null;
  752. $this->DebugMessage('ResolveSource() exiting because $this->rawImageData is set ('.number_format(strlen($this->rawImageData)).' bytes)', __FILE__, __LINE__);
  753. return true;
  754. }
  755. if ($this->sourceFilename) {
  756. $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->sourceFilename);
  757. $this->DebugMessage('$this->sourceFilename set to "'.$this->sourceFilename.'"', __FILE__, __LINE__);
  758. } elseif ($this->src) {
  759. $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->src);
  760. $this->DebugMessage('$this->sourceFilename set to "'.$this->sourceFilename.'" from $this->src ('.$this->src.')', __FILE__, __LINE__);
  761. } else {
  762. return $this->ErrorImage('$this->sourceFilename and $this->src are both empty');
  763. }
  764. if ($this->iswindows && ((substr($this->sourceFilename, 0, 2) == '//') || (substr($this->sourceFilename, 0, 2) == '\\\\'))) {
  765. // Windows \\share\filename.ext
  766. } elseif (preg_match('#^(f|ht)tps?\://#i', $this->sourceFilename)) {
  767. // URL
  768. if ($this->config_http_user_agent) {
  769. ini_set('user_agent', $this->config_http_user_agent);
  770. }
  771. } elseif (!@file_exists($this->sourceFilename)) {
  772. return $this->ErrorImage('"'.$this->sourceFilename.'" does not exist');
  773. } elseif (!@is_file($this->sourceFilename)) {
  774. return $this->ErrorImage('"'.$this->sourceFilename.'" is not a file');
  775. }
  776. return true;
  777. }
  778. function setOutputFormat() {
  779. static $alreadyCalled = false;
  780. if ($this->thumbnailFormat && $alreadyCalled) {
  781. return true;
  782. }
  783. $alreadyCalled = true;
  784. $AvailableImageOutputFormats = array();
  785. $AvailableImageOutputFormats[] = 'text';
  786. if (@is_readable(dirname(__FILE__).'/phpthumb.ico.php')) {
  787. $AvailableImageOutputFormats[] = 'ico';
  788. }
  789. if (@is_readable(dirname(__FILE__).'/phpthumb.bmp.php')) {
  790. $AvailableImageOutputFormats[] = 'bmp';
  791. }
  792. $this->thumbnailFormat = 'ico';
  793. // Set default output format based on what image types are available
  794. if (function_exists('ImageTypes')) {
  795. $imagetypes = ImageTypes();
  796. if ($imagetypes & IMG_WBMP) {
  797. $this->thumbnailFormat = 'wbmp';
  798. $AvailableImageOutputFormats[] = 'wbmp';
  799. }
  800. if ($imagetypes & IMG_GIF) {
  801. $this->thumbnailFormat = 'gif';
  802. $AvailableImageOutputFormats[] = 'gif';
  803. }
  804. if ($imagetypes & IMG_PNG) {
  805. $this->thumbnailFormat = 'png';
  806. $AvailableImageOutputFormats[] = 'png';
  807. }
  808. if ($imagetypes & IMG_JPG) {
  809. $this->thumbnailFormat = 'jpeg';
  810. $AvailableImageOutputFormats[] = 'jpeg';
  811. }
  812. } else {
  813. //return $this->ErrorImage('ImageTypes() does not exist - GD support might not be enabled?');
  814. $this->DebugMessage('ImageTypes() does not exist - GD support might not be enabled?', __FILE__, __LINE__);
  815. }
  816. if ($this->ImageMagickVersion()) {
  817. $IMformats = array('jpeg', 'png', 'gif', 'bmp', 'ico', 'wbmp');
  818. $this->DebugMessage('Addding ImageMagick formats to $AvailableImageOutputFormats ('.implode(';', $AvailableImageOutputFormats).')', __FILE__, __LINE__);
  819. foreach ($IMformats as $key => $format) {
  820. $AvailableImageOutputFormats[] = $format;
  821. }
  822. }
  823. $AvailableImageOutputFormats = array_unique($AvailableImageOutputFormats);
  824. $this->DebugMessage('$AvailableImageOutputFormats = array('.implode(';', $AvailableImageOutputFormats).')', __FILE__, __LINE__);
  825. $this->f = preg_replace('#[^a-z]#', '', strtolower($this->f));
  826. if (strtolower($this->config_output_format) == 'jpg') {
  827. $this->config_output_format = 'jpeg';
  828. }
  829. if (strtolower($this->f) == 'jpg') {
  830. $this->f = 'jpeg';
  831. }
  832. if (phpthumb_functions::CaseInsensitiveInArray($this->config_output_format, $AvailableImageOutputFormats)) {
  833. // set output format to config default if that format is available
  834. $this->DebugMessage('$this->thumbnailFormat set to $this->config_output_format "'.strtolower($this->config_output_format).'"', __FILE__, __LINE__);
  835. $this->thumbnailFormat = strtolower($this->config_output_format);
  836. } elseif ($this->config_output_format) {
  837. $this->DebugMessage('$this->thumbnailFormat staying as "'.$this->thumbnailFormat.'" because $this->config_output_format ('.strtolower($this->config_output_format).') is not in $AvailableImageOutputFormats', __FILE__, __LINE__);
  838. }
  839. if ($this->f && (phpthumb_functions::CaseInsensitiveInArray($this->f, $AvailableImageOutputFormats))) {
  840. // override output format if $this->f is set and that format is available
  841. $this->DebugMessage('$this->thumbnailFormat set to $this->f "'.strtolower($this->f).'"', __FILE__, __LINE__);
  842. $this->thumbnailFormat = strtolower($this->f);
  843. } elseif ($this->f) {
  844. $this->DebugMessage('$this->thumbnailFormat staying as "'.$this->thumbnailFormat.'" because $this->f ('.strtolower($this->f).') is not in $AvailableImageOutputFormats', __FILE__, __LINE__);
  845. }
  846. // for JPEG images, quality 1 (worst) to 99 (best)
  847. // quality < 25 is nasty, with not much size savings - not recommended
  848. // problems with 100 - invalid JPEG?
  849. $this->thumbnailQuality = max(1, min(99, ($this->q ? intval($this->q) : 75)));
  850. $this->DebugMessage('$this->thumbnailQuality set to "'.$this->thumbnailQuality.'"', __FILE__, __LINE__);
  851. return true;
  852. }
  853. function setCacheDirectory() {
  854. // resolve cache directory to absolute pathname
  855. $this->DebugMessage('setCacheDirectory() starting with config_cache_directory = "'.$this->config_cache_directory.'"', __FILE__, __LINE__);
  856. if (substr($this->config_cache_directory, 0, 1) == '.') {
  857. if (preg_match('#^(f|ht)tps?\://#i', $this->src)) {
  858. if (!$this->config_cache_disable_warning) {
  859. $this->ErrorImage('$this->config_cache_directory ('.$this->config_cache_directory.') cannot be used for remote images. Adjust "cache_directory" or "cache_disable_warning" in phpThumb.config.php');
  860. }
  861. } elseif ($this->src) {
  862. // resolve relative cache directory to source image
  863. $this->config_cache_directory = dirname($this->ResolveFilenameToAbsolute($this->src)).DIRECTORY_SEPARATOR.$this->config_cache_directory;
  864. } else {
  865. // $this->new is probably set
  866. }
  867. }
  868. if (substr($this->config_cache_directory, -1) == '/') {
  869. $this->config_cache_directory = substr($this->config_cache_directory, 0, -1);
  870. }
  871. if ($this->iswindows) {
  872. $this->config_cache_directory = str_replace('/', DIRECTORY_SEPARATOR, $this->config_cache_directory);
  873. }
  874. if ($this->config_cache_directory) {
  875. $real_cache_path = realpath($this->config_cache_directory);
  876. if (!$real_cache_path) {
  877. $this->DebugMessage('realpath($this->config_cache_directory) failed for "'.$this->config_cache_directory.'"', __FILE__, __LINE__);
  878. if (!is_dir($this->config_cache_directory)) {
  879. $this->DebugMessage('!is_dir('.$this->config_cache_directory.')', __FILE__, __LINE__);
  880. }
  881. }
  882. if ($real_cache_path) {
  883. $this->DebugMessage('setting config_cache_directory to realpath('.$this->config_cache_directory.') = "'.$real_cache_path.'"', __FILE__, __LINE__);
  884. $this->config_cache_directory = $real_cache_path;
  885. }
  886. }
  887. if (!is_dir($this->config_cache_directory)) {
  888. if (!$this->config_cache_disable_warning) {
  889. $this->ErrorImage('$this->config_cache_directory ('.$this->config_cache_directory.') does not exist. Adjust "cache_directory" or "cache_disable_warning" in phpThumb.config.php');
  890. }
  891. $this->DebugMessage('$this->config_cache_directory ('.$this->config_cache_directory.') is not a directory', __FILE__, __LINE__);
  892. $this->config_cache_directory = null;
  893. } elseif (!@is_writable($this->config_cache_directory)) {
  894. $this->DebugMessage('$this->config_cache_directory is not writable ('.$this->config_cache_directory.')', __FILE__, __LINE__);
  895. }
  896. $this->InitializeTempDirSetting();
  897. if (!@is_dir($this->config_temp_directory) && !@is_writable($this->config_temp_directory) && @is_dir($this->config_cache_directory) && @is_writable($this->config_cache_directory)) {
  898. $this->DebugMessage('setting $this->config_temp_directory = $this->config_cache_directory ('.$this->config_cache_directory.')', __FILE__, __LINE__);
  899. $this->config_temp_directory = $this->config_cache_directory;
  900. }
  901. return true;
  902. }
  903. function ResolveFilenameToAbsolute($filename) {
  904. if (empty($filename)) {
  905. return false;
  906. }
  907. if (preg_match('#^[a-z0-9]+\:/{1,2}#i', $filename)) {
  908. // eg: http://host/path/file.jpg (HTTP URL)
  909. // eg: ftp://host/path/file.jpg (FTP URL)
  910. // eg: data1:/path/file.jpg (Netware path)
  911. //$AbsoluteFilename = $filename;
  912. return $filename;
  913. } elseif ($this->iswindows && isset($filename{1}) && ($filename{1} == ':')) {
  914. // absolute pathname (Windows)
  915. $AbsoluteFilename = $filename;
  916. } elseif ($this->iswindows && ((substr($filename, 0, 2) == '//') || (substr($filename, 0, 2) == '\\\\'))) {
  917. // absolute pathname (Windows)
  918. $AbsoluteFilename = $filename;
  919. } elseif ($filename{0} == '/') {
  920. if (@is_readable($filename) && !@is_readable($this->config_document_root.$filename)) {
  921. // absolute filename (*nix)
  922. $AbsoluteFilename = $filename;
  923. } elseif (isset($filename{1}) && ($filename{1} == '~')) {
  924. // /~user/path
  925. if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray($filename)) {
  926. $AbsoluteFilename = $ApacheLookupURIarray['filename'];
  927. } else {
  928. $AbsoluteFilename = realpath($filename);
  929. if (@is_readable($AbsoluteFilename)) {
  930. $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.$filename.'", but the correct filename ('.$AbsoluteFilename.') seems to have been resolved with realpath($filename)', __FILE__, __LINE__);
  931. } elseif (is_dir(dirname($AbsoluteFilename))) {
  932. $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname($filename).'", but the correct directory ('.dirname($AbsoluteFilename).') seems to have been resolved with realpath(.)', __FILE__, __LINE__);
  933. } else {
  934. return $this->ErrorImage('phpthumb_functions::ApacheLookupURIarray() failed for "'.$filename.'". This has been known to fail on Apache2 - try using the absolute filename for the source image (ex: "/home/user/httpdocs/image.jpg" instead of "/~user/image.jpg")');
  935. }
  936. }
  937. } else {
  938. // relative filename (any OS)
  939. if (preg_match('#^'.preg_quote($this->config_document_root).'#', $filename)) {
  940. $AbsoluteFilename = $filename;
  941. $this->DebugMessage('ResolveFilenameToAbsolute() NOT prepending $this->config_document_root ('.$this->config_document_root.') to $filename ('.$filename.') resulting in ($AbsoluteFilename = "'.$AbsoluteFilename.'")', __FILE__, __LINE__);
  942. } else {
  943. $AbsoluteFilename = $this->config_document_root.$filename;
  944. $this->DebugMessage('ResolveFilenameToAbsolute() prepending $this->config_document_root ('.$this->config_document_root.') to $filename ('.$filename.') resulting in ($AbsoluteFilename = "'.$AbsoluteFilename.'")', __FILE__, __LINE__);
  945. }
  946. }
  947. } else {
  948. // relative to current directory (any OS)
  949. //$AbsoluteFilename = $this->config_document_root.preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, dirname(@$_SERVER['PHP_SELF'])).DIRECTORY_SEPARATOR.preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $filename);
  950. $AbsoluteFilename = dirname(__FILE__).DIRECTORY_SEPARATOR.preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $filename);
  951. //if (!@file_exists($AbsoluteFilename) && @file_exists(realpath($this->DotPadRelativeDirectoryPath($filename)))) {
  952. // $AbsoluteFilename = realpath($this->DotPadRelativeDirectoryPath($filename));
  953. //}
  954. if (substr(dirname(@$_SERVER['PHP_SELF']), 0, 2) == '/~') {
  955. if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) {
  956. $AbsoluteFilename = $ApacheLookupURIarray['filename'].DIRECTORY_SEPARATOR.$filename;
  957. } else {
  958. $AbsoluteFilename = realpath('.').DIRECTORY_SEPARATOR.$filename;
  959. if (@is_readable($AbsoluteFilename)) {
  960. $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'", but the correct filename ('.$AbsoluteFilename.') seems to have been resolved with realpath(.)/$filename', __FILE__, __LINE__);
  961. } elseif (is_dir(dirname($AbsoluteFilename))) {
  962. $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'", but the correct directory ('.dirname($AbsoluteFilename).') seems to have been resolved with realpath(.)', __FILE__, __LINE__);
  963. } else {
  964. return $this->ErrorImage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'". This has been known to fail on Apache2 - try using the absolute filename for the source image');
  965. }
  966. }
  967. }
  968. }
  969. if (is_link($AbsoluteFilename)) {
  970. $this->DebugMessage('is_link()==true, changing "'.$AbsoluteFilename.'" to "'.readlink($AbsoluteFilename).'"', __FILE__, __LINE__);
  971. $AbsoluteFilename = readlink($AbsoluteFilename);
  972. }
  973. if (realpath($AbsoluteFilename)) {
  974. $AbsoluteFilename = realpath($AbsoluteFilename);
  975. }
  976. if ($this->iswindows) {
  977. $AbsoluteFilename = preg_replace('#^'.preg_quote(realpath($this->config_document_root)).'#i', realpath($this->config_document_root), $AbsoluteFilename);
  978. $AbsoluteFilename = str_replace(DIRECTORY_SEPARATOR, '/', $AbsoluteFilename);
  979. }
  980. if (!$this->config_allow_src_above_docroot && !preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', realpath($this->config_document_root))).'#', $AbsoluteFilename)) {
  981. $this->DebugMessage('!$this->config_allow_src_above_docroot therefore setting "'.$AbsoluteFilename.'" (outside "'.realpath($this->config_document_root).'") to null', __FILE__, __LINE__);
  982. return false;
  983. }
  984. if (!$this->config_allow_src_above_phpthumb && !preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', dirname(__FILE__))).'#', $AbsoluteFilename)) {
  985. $this->DebugMessage('!$this->config_allow_src_above_phpthumb therefore setting "'.$AbsoluteFilename.'" (outside "'.dirname(__FILE__).'") to null', __FILE__, __LINE__);
  986. return false;
  987. }
  988. return $AbsoluteFilename;
  989. }
  990. function file_exists_ignoreopenbasedir($filename, $cached=true) {
  991. static $open_basedirs = null;
  992. static $file_exists_cache = array();
  993. if (!$cached || !isset($file_exists_cache[$filename])) {
  994. if (is_null($open_basedirs)) {
  995. $open_basedirs = explode(';', ini_get('open_basedir'));
  996. }
  997. if (empty($open_basedirs) || in_array(dirname($filename), $open_basedirs)) {
  998. $file_exists_cache[$filename] = file_exists($filename);
  999. } elseif ($this->iswindows) {
  1000. $ls_filename = trim(phpthumb_functions::SafeExec('dir '.escapeshellarg($filename)));
  1001. $file_exists_cache[$filename] = !preg_match('#File Not Found#i', $ls_filename);
  1002. } else {
  1003. $ls_filename = trim(phpthumb_functions::SafeExec('ls '.escapeshellarg($filename)));
  1004. $file_exists_cache[$filename] = ($ls_filename == $filename);
  1005. }
  1006. }
  1007. return $file_exists_cache[$filename];
  1008. }
  1009. function ImageMagickWhichConvert() {
  1010. static $WhichConvert = null;
  1011. if (is_null($WhichConvert)) {
  1012. if ($this->iswindows) {
  1013. $WhichConvert = false;
  1014. } else {
  1015. $WhichConvert = trim(phpthumb_functions::SafeExec('which convert'));
  1016. }
  1017. }
  1018. return $WhichConvert;
  1019. }
  1020. function ImageMagickCommandlineBase() {
  1021. static $commandline = null;
  1022. if (is_null($commandline)) {
  1023. if ($this->issafemode) {
  1024. $commandline = '';
  1025. return $commandline;
  1026. }
  1027. $commandline = (!is_null($this->config_imagemagick_path) ? $this->config_imagemagick_path : '');
  1028. if ($this->config_imagemagick_path && ($this->config_imagemagick_path != realpath($this->config_imagemagick_path))) {
  1029. if (@is_executable(realpath($this->config_imagemagick_path))) {
  1030. $this->DebugMessage('Changing $this->config_imagemagick_path ('.$this->config_imagemagick_path.') to realpath($this->config_imagemagick_path) ('.realpath($this->config_imagemagick_path).')', __FILE__, __LINE__);
  1031. $this->config_imagemagick_path = realpath($this->config_imagemagick_path);
  1032. } else {
  1033. $this->DebugMessage('Leaving $this->config_imagemagick_path as ('.$this->config_imagemagick_path.') because !is_execuatable(realpath($this->config_imagemagick_path)) ('.realpath($this->config_imagemagick_path).')', __FILE__, __LINE__);
  1034. }
  1035. }
  1036. $this->DebugMessage(' file_exists('.$this->config_imagemagick_path.') = '.intval( @file_exists($this-

Large files files are truncated, but you can click here to view the full file