PageRenderTime 64ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/library/core/class.uploadimage.php

https://github.com/abhishekmica/Garden
PHP | 221 lines | 139 code | 33 blank | 49 comment | 45 complexity | 5153d018f5a10f0629e369bfec4bf845 MD5 | raw file
  1. <?php if (!defined('APPLICATION')) exit();
  2. /*
  3. Copyright 2008, 2009 Vanilla Forums Inc.
  4. This file is part of Garden.
  5. Garden is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  6. Garden is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  7. You should have received a copy of the GNU General Public License along with Garden. If not, see <http://www.gnu.org/licenses/>.
  8. Contact Vanilla Forums Inc. at support [at] vanillaforums [dot] com
  9. */
  10. /**
  11. * Handles uploading image files.
  12. */
  13. class Gdn_UploadImage extends Gdn_Upload {
  14. public static function CanUploadImages() {
  15. // Check that we have the necessary tools to allow image uploading
  16. // Is the Uploads directory available and correctly permissioned?
  17. if (!Gdn_Upload::CanUpload())
  18. return FALSE;
  19. // Do we have GD?
  20. if (!function_exists('gd_info'))
  21. return FALSE;
  22. $GdInfo = gd_info();
  23. // Do we have a good version of GD?
  24. $GdVersion = preg_replace('/[a-z ()]+/i', '', $GdInfo['GD Version']);
  25. if ($GdVersion < 2)
  26. return FALSE;
  27. return TRUE;
  28. }
  29. /**
  30. * Validates the uploaded image. Returns the temporary name of the uploaded file.
  31. */
  32. public function ValidateUpload($InputName) {
  33. if (!function_exists('gd_info'))
  34. throw new Exception(T('The uploaded file could not be processed because GD is not installed.'));
  35. // Make sure that all standard file upload checks are performed.
  36. $TmpFileName = parent::ValidateUpload($InputName);
  37. // Now perform image-specific checks
  38. $Size = getimagesize($TmpFileName);
  39. if ($Size === FALSE)
  40. throw new Exception(T('The uploaded file was not an image.'));
  41. return $TmpFileName;
  42. }
  43. /**
  44. * Saves the specified image at $Target in the specified format with the
  45. * specified dimensions (or the existing dimensions if height/width are not
  46. * provided.
  47. *
  48. * @param string The path to the source image. Typically this is the tmp file name returned by $this->ValidateUpload();
  49. * @param string The full path to where the image should be saved, including image name.
  50. * @param int An integer value indicating the maximum allowed height of the image (in pixels).
  51. * @param int An integer value indicating the maximum allowed width of the image (in pixels).
  52. * @param array Options additional options for saving the image.
  53. * - <b>Crop</b>: Image proportions will always remain constrained. The Crop parameter is a boolean value indicating if the image should be cropped when one dimension (height or width) goes beyond the constrained proportions.
  54. * - <b>OutputType</b>: The format in which the output image should be saved. Options are: jpg, png, and gif. Default is jpg.
  55. * - <b>ImageQuality</b>: An integer value representing the qualityof the saved image. Ranging from 0 (worst quality, smaller file) to 100 (best quality, biggest file).
  56. * - <b>SourceX, SourceY</b>: If you want to create a thumbnail that is a crop of the image these are the coordinates of the thumbnail.
  57. * - <b>SourceHeight. SourceWidth</b>: If you want to create a thumbnail that is a crop of the image these are it's dimensions.
  58. */
  59. public static function SaveImageAs($Source, $Target, $Height = '', $Width = '', $Options = array()) {
  60. $Crop = FALSE; $OutputType = ''; $ImageQuality = C('Garden.UploadImage.Quality', 75);
  61. // Make function work like it used to.
  62. $Args = func_get_args();
  63. if (count($Args) > 5) {
  64. $Crop = GetValue(4, $Args, $Crop);
  65. $OutputType = GetValue(5, $Args, $OutputType);
  66. $ImageQuality = GetValue(6, $Args, $ImageQuality);
  67. } elseif (is_bool($Options)) {
  68. $Crop = $Options;
  69. } else {
  70. $Crop = GetValue('Crop', $Options, $Crop);
  71. $OutputType = GetValue('OutputType', $Options, $OutputType);
  72. $ImageQuality = GetValue('ImageQuality', $Options, $ImageQuality);
  73. }
  74. // Make sure type, height & width are properly defined.
  75. if (!function_exists('gd_info'))
  76. throw new Exception(T('The uploaded file could not be processed because GD is not installed.'));
  77. $GdInfo = gd_info();
  78. $Size = getimagesize($Source);
  79. list($WidthSource, $HeightSource, $Type) = $Size;
  80. $WidthSource = GetValue('SourceWidth', $Options, $WidthSource);
  81. $HeightSource = GetValue('SourceHeight', $Options, $HeightSource);
  82. if ($Height == '' || !is_numeric($Height))
  83. $Height = $HeightSource;
  84. if ($Width == '' || !is_numeric($Width))
  85. $Width = $WidthSource;
  86. if (!$OutputType) {
  87. $OutputTypes = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
  88. $OutputType = GetValue($Type, $OutputTypes, 'jpg');
  89. }
  90. // Figure out the target path.
  91. $TargetParsed = Gdn_Upload::Parse($Target);
  92. $TargetPath = PATH_LOCAL_UPLOADS.'/'.ltrim($TargetParsed['Name'], '/');
  93. if (!file_exists(dirname($TargetPath)))
  94. mkdir(dirname($TargetPath), 0777, TRUE);
  95. // Don't resize if the source dimensions are smaller than the target dimensions
  96. $XCoord = GetValue('SourceX', $Options, 0);
  97. $YCoord = GetValue('SourceY', $Options, 0);
  98. if ($HeightSource > $Height || $WidthSource > $Width) {
  99. $AspectRatio = (float) $WidthSource / $HeightSource;
  100. if ($Crop === FALSE) {
  101. if (round($Width / $AspectRatio) > $Height) {
  102. $Width = round($Height * $AspectRatio);
  103. } else {
  104. $Height = round($Width / $AspectRatio);
  105. }
  106. } else {
  107. $HeightDiff = $HeightSource - $Height;
  108. $WidthDiff = $WidthSource - $Width;
  109. if ($WidthDiff > $HeightDiff) {
  110. // Crop the original width down
  111. $NewWidthSource = round(($Width * $HeightSource) / $Height);
  112. // And set the original x position to the cropped start point.
  113. if (!isset($Options['SourceX']))
  114. $XCoord = round(($WidthSource - $NewWidthSource) / 2);
  115. $WidthSource = $NewWidthSource;
  116. } else {
  117. // Crop the original height down
  118. $NewHeightSource = round(($Height * $WidthSource) / $Width);
  119. // And set the original y position to the cropped start point.
  120. if (!isset($Options['SourceY']))
  121. $YCoord = round(($HeightSource - $NewHeightSource) / 2);
  122. $HeightSource = $NewHeightSource;
  123. }
  124. }
  125. } else {
  126. // Neither target dimension is larger than the original, so keep the original dimensions.
  127. $Height = $HeightSource;
  128. $Width = $WidthSource;
  129. }
  130. // Create GD image from the provided file, but first check if we have the necessary tools
  131. $SourceImage = FALSE;
  132. switch ($Type) {
  133. case 1:
  134. if (GetValue('GIF Read Support', $GdInfo) || GetValue('GIF Write Support', $GdInfo))
  135. $SourceImage = imagecreatefromgif($Source);
  136. break;
  137. case 2:
  138. if (GetValue('JPG Support', $GdInfo) || GetValue('JPEG Support', $GdInfo))
  139. $SourceImage = imagecreatefromjpeg($Source);
  140. break;
  141. case 3:
  142. if (GetValue('PNG Support', $GdInfo)) {
  143. $SourceImage = imagecreatefrompng($Source);
  144. imagealphablending($SourceImage, TRUE);
  145. }
  146. break;
  147. }
  148. if (!$SourceImage)
  149. throw new Exception(sprintf(T('You cannot save images of this type (%s).'), $Type));
  150. // Create a new image from the raw source
  151. if (function_exists('imagecreatetruecolor')) {
  152. $TargetImage = imagecreatetruecolor($Width, $Height); // Only exists if GD2 is installed
  153. } else
  154. $TargetImage = imagecreate($Width, $Height); // Always exists if any GD is installed
  155. if ($OutputType == 'png') {
  156. imagealphablending($TargetImage, FALSE);
  157. imagesavealpha($TargetImage, TRUE);
  158. }
  159. imagecopyresampled($TargetImage, $SourceImage, 0, 0, $XCoord, $YCoord, $Width, $Height, $WidthSource, $HeightSource);
  160. imagedestroy($SourceImage);
  161. // No need to check these, if we get here then whichever function we need will be available
  162. if ($OutputType == 'gif')
  163. imagegif($TargetImage, $TargetPath);
  164. else if ($OutputType == 'png') {
  165. imagepng($TargetImage, $TargetPath, (int)($ImageQuality/10));
  166. } else
  167. imagejpeg($TargetImage, $TargetPath, $ImageQuality);
  168. // Allow a plugin to move the file to a differnt location.
  169. $Sender = new stdClass();
  170. $Sender->EventArguments = array();
  171. $Sender->EventArguments['Path'] = $TargetPath;
  172. $Parsed = self::Parse($TargetPath);
  173. $Sender->EventArguments['Parsed'] =& $Parsed;
  174. $Sender->Returns = array();
  175. Gdn::PluginManager()->CallEventHandlers($Sender, 'Gdn_UploadImage', 'SaveImageAs');
  176. return $Sender->EventArguments['Parsed'];
  177. }
  178. public function GenerateTargetName($TargetFolder, $Extension = 'jpg') {
  179. if (!$Extension) {
  180. $Extension = trim(pathinfo($this->_UploadedFile['name'], PATHINFO_EXTENSION), '.');
  181. }
  182. $Name = RandomString(12);
  183. while (file_exists($TargetFolder . DS . $Name . '.' . $Extension)) {
  184. $Name = RandomString(12);
  185. }
  186. return $TargetFolder . DS . $Name . '.' . $Extension;
  187. }
  188. }