PageRenderTime 45ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/administrator/components/com_virtuemart/classes/imageTools.class.php

https://bitbucket.org/dgough/annamaria-daneswood-25102012
PHP | 397 lines | 262 code | 45 blank | 90 comment | 67 complexity | 2c216bf95a5bac45ecc5b2b3e0ba5405 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
  3. /**
  4. * This file contains functions and classes for common image manipulation tasks
  5. *
  6. * @version $Id: imageTools.class.php 1324 2008-03-26 20:12:56Z soeren_nb $
  7. * @package VirtueMart
  8. * @subpackage classes
  9. * @copyright Copyright (C) 2004-2008 soeren - All rights reserved.
  10. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
  11. * VirtueMart is free software. This version may have been modified pursuant
  12. * to the GNU General Public License, and as distributed it includes or
  13. * is derivative of works licensed under the GNU General Public License or
  14. * other free or open source software licenses.
  15. * See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
  16. *
  17. * http://virtuemart.net
  18. */
  19. class vmImageTools {
  20. /**
  21. * Validates an uploaded image. Creates UNIX commands to be used
  22. * by the process_images function, which has to be called after
  23. * the validation.
  24. * @author jep
  25. * @author soeren
  26. * @static
  27. * @param array $d
  28. * @param string $field_name The name of the field in the table $table, the image is assigned to [e.g. product_thumb_image]
  29. * @param string $table_name The name of a table in the database [e.g. #__{vm}_product]
  30. * @return boolean When the upload validation was sucessfull, true is returned, otherwise false
  31. */
  32. function validate_image(&$d,$field_name,$table_name) {
  33. global $vmLogger;
  34. // The commands to be executed by the process_images
  35. // function are returned as strings in an array here.
  36. if (empty($d['image_commands']) || !empty( $_REQUEST['image_commands'])) {
  37. unset( $_REQUEST['image_commands'] );
  38. $d['image_commands'] = array();
  39. }
  40. // Generate the path to images
  41. $path = IMAGEPATH;
  42. $path .= $table_name . "/";
  43. // Check permissions to write to destination directory
  44. // Workaround for Window$
  45. if(strstr($path , ":" )) {
  46. $path_begin = substr( $path, strpos( $path , ":" )+1, strlen($path));
  47. $path = str_replace( "//", "/", $path_begin );
  48. }
  49. if (!is_dir( $path )) {
  50. mkdir( $path, 0777 );
  51. $vmLogger->debug( 'Had to create the directory '.$path);
  52. }
  53. if( !is_writable($path) && !empty( $_FILES[$field_name]["tmp_name"]) ) {
  54. $vmLogger->err( 'Cannot write to '.$table_name.' image directory: '.$path );
  55. return false;
  56. }
  57. // Check for upload errors
  58. require_once( CLASSPATH. 'ps_product_files.php');
  59. ps_product_files::checkUploadedFile( $field_name );
  60. $tmp_field_name = str_replace( "thumb", "full", $field_name );
  61. // Class for resizing Thumbnails
  62. require_once( CLASSPATH . "class.img2thumb.php");
  63. if( @$d[$tmp_field_name.'_action'] == 'auto_resize' ) {
  64. // Resize the Full Image
  65. if( !empty ( $_FILES[$tmp_field_name]["tmp_name"] )) {
  66. $full_file = $_FILES[$tmp_field_name]["tmp_name"];
  67. $image_info = getimagesize($full_file);
  68. }
  69. elseif( !empty($d[$tmp_field_name."_url"] )) {
  70. $tmp_file_from_url = $full_file = ps_product_files::getRemoteFile($d[$tmp_field_name."_url"]);
  71. if( $full_file ) {
  72. $vmLogger->debug( 'Successfully fetched the image file from '.$d[$tmp_field_name."_url"].' for later resizing' );
  73. $image_info = getimagesize($full_file);
  74. }
  75. }
  76. if( !empty( $image_info )) {
  77. if( $image_info[2] == 1) {
  78. if( function_exists("imagegif") ) {
  79. $ext = ".gif";
  80. $noimgif="";
  81. }
  82. else {
  83. $ext = ".jpg";
  84. $noimgif = ".gif";
  85. }
  86. }
  87. elseif( $image_info[2] == 2) {
  88. $ext = ".jpg";
  89. $noimgif="";
  90. }
  91. elseif( $image_info[2] == 3) {
  92. $ext = ".png";
  93. $noimgif="";
  94. }
  95. $vmLogger->debug( 'The resized Thumbnail will have extension '.$noimgif.$ext );
  96. /* Generate Image Destination File Name */
  97. if( !empty( $d[$table_name.'_name'] )) {
  98. $filename = substr( $d[$table_name.'_name'], 0, 16 );
  99. $filename = vmSafeFileName( $filename );
  100. }
  101. else {
  102. $filename = md5( 'virtuemart' );
  103. }
  104. $to_file_thumb = uniqid( $filename.'_' );
  105. $fileout = IMAGEPATH."$table_name/resized/$to_file_thumb".'_'.PSHOP_IMG_WIDTH.'x'.PSHOP_IMG_HEIGHT.$noimgif.$ext;
  106. if( !file_exists( dirname( $fileout ))) {
  107. mkdir( dirname( $fileout ));
  108. $vmLogger->debug('Created Directory '.dirname( $fileout ));
  109. }
  110. $neu = new Img2Thumb( $full_file, PSHOP_IMG_WIDTH, PSHOP_IMG_HEIGHT, $fileout, 0, 255, 255, 255 );
  111. $thumbname = 'resized/'.basename( $fileout );
  112. $vmLogger->debug( 'Finished creating the thumbnail '.$thumbname );
  113. if( isset($tmp_file_from_url) ) unlink( realpath($tmp_file_from_url) );
  114. $tmp_field_name = str_replace( "full", "thumb", $tmp_field_name );
  115. $tmp_field_name = str_replace( "_url", "", $tmp_field_name );
  116. $_FILES[$tmp_field_name]['tmp_name'] = $fileout;
  117. $_FILES[$tmp_field_name]['name'] = $thumbname;
  118. $d[$tmp_field_name] = $thumbname;
  119. $curr_file = isset($_REQUEST[$tmp_field_name."_curr"]) ? $_REQUEST[$tmp_field_name."_curr"] : "";
  120. if (!empty($curr_file)) {
  121. $delete = str_replace("\\", "/", realpath($path."/".$curr_file));
  122. $d["image_commands"][] = array( 'command' => 'unlink',
  123. 'param1' => $delete
  124. );
  125. $vmLogger->debug( 'Preparing: delete old thumbnail image: '.$delete );
  126. /* Remove the resized image if exists */
  127. if( PSHOP_IMG_RESIZE_ENABLE=="1" ) {
  128. $pathinfo = pathinfo( $delete );
  129. isset($pathinfo["dirname"]) or $pathinfo["dirname"] = "";
  130. isset($pathinfo["extension"]) or $pathinfo["extension"] = "";
  131. $filehash = basename( $delete, ".".$pathinfo["extension"] );
  132. $resizedfilename = $pathinfo["dirname"]."/resized/".$filehash."_".PSHOP_IMG_WIDTH."x".PSHOP_IMG_HEIGHT.".".$pathinfo["extension"];
  133. $d["image_commands"][] = array( 'command' => 'unlink',
  134. 'param1' => $resizedfilename
  135. );
  136. $vmLogger->debug( 'Preparing: delete resized thumbnail '.$resizedfilename );
  137. }
  138. }
  139. }
  140. }
  141. $temp_file = isset($_FILES[$field_name]['tmp_name']) ? $_FILES[$field_name]['tmp_name'] : "";
  142. $file_type = isset($_FILES[$field_name]['type']) ? $_FILES[$field_name]['type'] : "";
  143. $orig_file = isset($_FILES[$field_name]["name"]) ? $_FILES[$field_name]['name'] : "";
  144. $curr_file = isset($_REQUEST[$field_name."_curr"]) ? $_REQUEST[$field_name."_curr"] : "";
  145. /* Generate text to display in error messages */
  146. if (eregi("thumb",$field_name)) {
  147. $image_type = "thumbnail image";
  148. } elseif (eregi("full",$field_name)) {
  149. $image_type = "full image";
  150. } else {
  151. $image_type = ereg_replace("_"," ",$field_name);
  152. }
  153. /* If User types "none" in Image Upload Field */
  154. if ( @$d[$field_name."_action"] == "delete") {
  155. /* If there is a current image file */
  156. if (!empty($curr_file)) {
  157. $delete = str_replace("\\", "/", realpath($path."/".$curr_file));
  158. $d["image_commands"][] = array( 'command' => 'unlink',
  159. 'param1' => $delete
  160. );
  161. $vmLogger->debug( 'Preparing: delete old '.$image_type.' '.$delete );
  162. /* Remove the resized image if exists */
  163. if( PSHOP_IMG_RESIZE_ENABLE=="1" && $image_type == "thumbnail image") {
  164. $pathinfo = pathinfo( $delete );
  165. isset($pathinfo["dirname"]) or $pathinfo["dirname"] = "";
  166. isset($pathinfo["extension"]) or $pathinfo["extension"] = "";
  167. $filehash = basename( $delete, ".".$pathinfo["extension"] );
  168. $resizedfilename = $pathinfo["dirname"]."/resized/".$filehash."_".PSHOP_IMG_WIDTH."x".PSHOP_IMG_HEIGHT.".".$pathinfo["extension"];
  169. $d["image_commands"][] = array( 'command' => 'unlink',
  170. 'param1' => $resizedfilename
  171. );
  172. $vmLogger->debug( 'Preparing: delete resized thumbnail '.$resizedfilename );
  173. }
  174. }
  175. $d[$field_name] = "";
  176. return true;
  177. }
  178. /* If upload fails */
  179. elseif($orig_file and $temp_file == "none") {
  180. $vmLogger->err( $image_type.' upload failed.');
  181. return false;
  182. }
  183. else {
  184. // If nothing was entered in the Upload box, there is no image to process
  185. if (!$orig_file ) {
  186. $d[$field_name] = $curr_file;
  187. return true;
  188. }
  189. }
  190. if( empty( $temp_file )) {
  191. $vmLogger->err( 'The File Upload was not successful: there\'s no uploaded temporary file!' );
  192. return false;
  193. }
  194. /* Generate Image Destination File Name */
  195. if( !empty( $d[$table_name.'_name'] )) {
  196. $filename = substr( $d[$table_name.'_name'], 0, 16 );
  197. $filename = vmSafeFileName( $filename );
  198. }
  199. else {
  200. $filename = md5( 'virtuemart' );
  201. }
  202. $to_file = uniqid( $filename.'_' );
  203. /* Check image file format */
  204. if( $orig_file != "none" ) {
  205. $to_file .= $ext = '.'.Img2Thumb::GetImgType( $temp_file );
  206. if( !$to_file ) {
  207. $vmLogger->err( $image_type.' file is invalid: '.$file_type.'.' );
  208. return false;
  209. }
  210. }
  211. /*
  212. ** If it gets to this point then there is an uploaded file in the system
  213. ** and it is a valid image file.
  214. */
  215. /* If Updating */
  216. if (!empty($curr_file)) {
  217. /* Command to remove old image file */
  218. $delete = str_replace( "\\", "/", realpath($path)."/".$curr_file);
  219. $d["image_commands"][] = array( 'command' => 'unlink',
  220. 'param1' => $delete
  221. );
  222. /* Remove the resized image if exists */
  223. if( PSHOP_IMG_RESIZE_ENABLE=="1" && $image_type == "thumbnail image") {
  224. $pathinfo = pathinfo( $delete );
  225. $filehash = basename( $delete, ".".$pathinfo["extension"] );
  226. $resizedfilename = $pathinfo["dirname"]."/resized/".$filehash."_".PSHOP_IMG_WIDTH."x".PSHOP_IMG_HEIGHT.".".$pathinfo["extension"];
  227. $d["image_commands"][] = array( 'command' => 'unlink',
  228. 'param1' => $resizedfilename
  229. );
  230. $vmLogger->debug( 'Preparing: delete resized thumbnail '.$resizedfilename );
  231. }
  232. }
  233. /* Command to move uploaded file into destination directory */
  234. // Command to move uploaded file into destination directory
  235. $d["image_commands"][] = array( 'command' => 'move_uploaded_file',
  236. 'param1' => $temp_file,
  237. 'param2' => $path.$to_file
  238. );
  239. $d["image_commands"][] = array( 'command' => 'unlink',
  240. 'param1' => $temp_file
  241. );
  242. if( empty( $d[$field_name] )) {
  243. /* Return new image file name */
  244. $d[$field_name] = $to_file;
  245. }
  246. return true;
  247. }
  248. /**
  249. * The function that safely executes $d['image_commands'] and catches errors
  250. *
  251. * @param array $d
  252. * @return boolean True when all image commands were executed successfully, false when not
  253. */
  254. function process_images(&$d) {
  255. global $vmLogger;
  256. require_once(CLASSPATH.'ps_product_files.php');
  257. if (!empty($d["image_commands"])) {
  258. foreach( $d['image_commands'] as $exec ) {
  259. switch( $exec['command'] ) {
  260. case 'unlink':
  261. if( file_exists( $exec['param1']) ) {
  262. $ret = unlink( $exec['param1'] );
  263. } else {
  264. $ret = true;
  265. }
  266. break;
  267. case 'move_uploaded_file':
  268. if( is_uploaded_file( $exec['param1']) ) {
  269. $ret = move_uploaded_file( $exec['param1'], $exec['param2'] );
  270. } else {
  271. $ret = copy( $exec['param1'], $exec['param2'] );
  272. }
  273. @chmod( $exec['param2'], 0666 );
  274. break;
  275. }
  276. if ($ret == false) {
  277. $vmLogger->err ( 'The following image update command failed: '. $exec['command'] );
  278. return false;
  279. }
  280. else {
  281. $vmLogger->debug( 'Successfully processed image command: '.$exec['command'] );
  282. }
  283. }
  284. $d["image_commands"] = array();
  285. }
  286. return true;
  287. }
  288. /**
  289. * Resizes an image to a given size
  290. *
  291. * @since VirtueMart 1.1.0
  292. * @author soeren
  293. *
  294. * @static
  295. *
  296. * @param string $sourceFile
  297. * @param string $resizedFile
  298. * @param int $width
  299. * @param int $height
  300. * @param boolean $enlargeSmallerImg
  301. * @return boolean
  302. */
  303. function resizeImage($sourceFile, $resizedFile, $height, $width, $enlargeSmallerImg=false ) {
  304. global $vmLogger;
  305. if( $width <= 0 || $height <= 0 ) {
  306. if( is_callable(array($vmLogger,'err'))) {
  307. $vmLogger->err( 'An invalid image height or weight was specified!');
  308. return false;
  309. }
  310. }
  311. // We must take care of images which are already smaller than the size they are to be resized to
  312. // In most case it is not wanted to enlarge them
  313. $imgArr = @getimagesize( $sourceFile );
  314. $isSmallerThanResizeto = $imgArr[0] < $width && $imgArr[1] < $height;
  315. if( $isSmallerThanResizeto && !$enlargeSmallerImg ) {
  316. if( $sourceFile != $resizedFile ) {
  317. @copy( $sourceFile, $resizedFile );
  318. }
  319. $vmLogger->debug( 'The image '.basename( $sourceFile ).' was not resized because would have been enlarged.');
  320. return false;
  321. }
  322. // Class for resizing Thumbnails
  323. require_once( CLASSPATH . "class.img2thumb.php");
  324. $Img2Thumb = new Img2Thumb( $sourceFile, $width, $height, $resizedFile, 0, 255, 255, 255 );
  325. if( is_file( $resizedFile )) {
  326. return true;
  327. }
  328. else {
  329. return false;
  330. }
  331. }
  332. /**
  333. * Returns the filename of an image's resized copy in the /resized folder
  334. * @since VirtueMart 1.1.0
  335. * @author soeren
  336. * @static
  337. * @param string $filename
  338. * @param string $section
  339. * @param string $ext
  340. * @return string
  341. */
  342. function getResizedFilename( $filename, $section='product', $ext='', $height=0, $width=0 ) {
  343. $fileinfo = pathinfo( $filename );
  344. if( $ext == '' ) {
  345. $ext = $fileinfo['extension'];
  346. }
  347. $width = ( $width > 0 ) ? (int)$width : PSHOP_IMG_WIDTH;
  348. $height = ( $height > 0 ) ? (int)$height : PSHOP_IMG_HEIGHT;
  349. $basename = str_replace( "_".$height."x".$width, '', basename( $filename, '.'.$ext ) );
  350. return IMAGEPATH.$section.'/resized/'.$basename."_".$height."x".$width.'.'.$ext;
  351. }
  352. }