saveImageAs() public static method

Saves the specified image at $Target in the specified format with the specified dimensions (or the existing dimensions if height/width are not provided.
public static saveImageAs ( $Source, $Target, $Height = '', $Width = '', $Options = [] )
示例#1
0
 /**
  * Save an image from a field and delete any old image that's been uploaded.
  *
  * @param string $Field The name of the field. The image will be uploaded with the _New extension while the current image will be just the field name.
  * @param array $Options
  */
 public function saveImage($Field, $Options = array())
 {
     $Upload = new Gdn_UploadImage();
     $FileField = str_replace('.', '_', $Field);
     if (!getValueR("{$FileField}_New.name", $_FILES)) {
         trace("{$Field} not uploaded, returning.");
         return false;
     }
     // First make sure the file is valid.
     try {
         $TmpName = $Upload->validateUpload($FileField . '_New', true);
         if (!$TmpName) {
             return false;
             // no file uploaded.
         }
     } catch (Exception $Ex) {
         $this->addError($Ex);
         return false;
     }
     // Get the file extension of the file.
     $Ext = val('OutputType', $Options, trim($Upload->getUploadedFileExtension(), '.'));
     if ($Ext == 'jpeg') {
         $Ext = 'jpg';
     }
     Trace($Ext, 'Ext');
     // The file is valid so let's come up with its new name.
     if (isset($Options['Name'])) {
         $Name = $Options['Name'];
     } elseif (isset($Options['Prefix'])) {
         $Name = $Options['Prefix'] . md5(microtime()) . '.' . $Ext;
     } else {
         $Name = md5(microtime()) . '.' . $Ext;
     }
     // We need to parse out the size.
     $Size = val('Size', $Options);
     if ($Size) {
         if (is_numeric($Size)) {
             touchValue('Width', $Options, $Size);
             touchValue('Height', $Options, $Size);
         } elseif (preg_match('`(\\d+)x(\\d+)`i', $Size, $M)) {
             touchValue('Width', $Options, $M[1]);
             touchValue('Height', $Options, $M[2]);
         }
     }
     trace($Options, "Saving image {$Name}.");
     try {
         $Parsed = $Upload->saveImageAs($TmpName, $Name, val('Height', $Options, ''), val('Width', $Options, ''), $Options);
         trace($Parsed, 'Saved Image');
         $Current = $this->getFormValue($Field);
         if ($Current && val('DeleteOriginal', $Options, true)) {
             // Delete the current image.
             trace("Deleting original image: {$Current}.");
             if ($Current) {
                 $Upload->delete($Current);
             }
         }
         // Set the current value.
         $this->setFormValue($Field, $Parsed['SaveName']);
     } catch (Exception $Ex) {
         $this->addError($Ex);
     }
 }
 /**
  *
  *
  * @param PostController $Sender
  * @param array $Args
  */
 public function postController_editorUpload_create($Sender, $Args = array())
 {
     // @Todo Move to a library/functions file.
     require 'generate_thumbnail.php';
     // Grab raw upload data ($_FILES), essentially. It's only needed
     // because the methods on the Upload class do not expose all variables.
     $fileData = Gdn::request()->getValueFrom(Gdn_Request::INPUT_FILES, $this->editorFileInputName, false);
     $discussionID = $Sender->Request->post('DiscussionID') ? $Sender->Request->post('DiscussionID') : '';
     // JSON payload of media info will get sent back to the client.
     $json = array('error' => 1, 'feedback' => 'There was a problem.', 'errors' => array(), 'payload' => array());
     // New upload instance
     $Upload = new Gdn_Upload();
     // This will validate, such as size maxes, file extensions. Upon doing
     // this, $_FILES is set as a protected property, so all the other Gdn_Upload methods work on it.
     $tmpFilePath = $Upload->validateUpload($this->editorFileInputName);
     // Get base destination path for editor uploads
     $this->editorBaseUploadDestinationDir = $this->getBaseUploadDestinationDir();
     // Pass path, if doesn't exist, will create, and determine if valid.
     $canUpload = Gdn_Upload::canUpload($this->editorBaseUploadDestinationDir);
     if ($tmpFilePath && $canUpload) {
         $fileExtension = strtolower($Upload->getUploadedFileExtension());
         $fileName = $Upload->getUploadedFileName();
         list($tmpwidth, $tmpheight, $imageType) = getimagesize($tmpFilePath);
         // This will return the absolute destination path, including generated
         // filename based on md5_file, and the full path. It
         // will create a filename, with extension, and check if its dir can be writable.
         $absoluteFileDestination = $this->getAbsoluteDestinationFilePath($tmpFilePath, $fileExtension);
         // Save original file to uploads, then manipulate from this location if
         // it's a photo. This will also call events in Vanilla so other plugins can tie into this.
         if (empty($imageType)) {
             $filePathParsed = $Upload->saveAs($tmpFilePath, $absoluteFileDestination, array('source' => 'content'));
         } else {
             $filePathParsed = Gdn_UploadImage::saveImageAs($tmpFilePath, $absoluteFileDestination, '', '', array('SaveGif' => true));
             $tmpwidth = $filePathParsed['Width'];
             $tmpheight = $filePathParsed['Height'];
         }
         // Determine if image, and thus requires thumbnail generation, or simply saving the file.
         // Not all files will be images.
         $thumbHeight = '';
         $thumbWidth = '';
         $imageHeight = '';
         $imageWidth = '';
         $thumbPathParsed = array('SaveName' => '');
         $thumbUrl = '';
         // This is a redundant check, because it's in the thumbnail function,
         // but there's no point calling it blindly on every file, so just check here before calling it.
         $generate_thumbnail = false;
         if (in_array($fileExtension, array('jpg', 'jpeg', 'gif', 'png', 'bmp', 'ico'))) {
             $imageHeight = $tmpheight;
             $imageWidth = $tmpwidth;
             $generate_thumbnail = true;
         }
         // Save data to database using model with media table
         $Model = new Gdn_Model('Media');
         // Will be passed to model for database insertion/update. All thumb vars will be empty.
         $Media = array('Name' => $fileName, 'Type' => $fileData['type'], 'Size' => $fileData['size'], 'ImageWidth' => $imageWidth, 'ImageHeight' => $imageHeight, 'ThumbWidth' => $thumbWidth, 'ThumbHeight' => $thumbHeight, 'InsertUserID' => Gdn::session()->UserID, 'DateInserted' => date('Y-m-d H:i:s'), 'StorageMethod' => 'local', 'Path' => $filePathParsed['SaveName'], 'ThumbPath' => $thumbPathParsed['SaveName']);
         // Get MediaID and pass it to client in payload.
         $MediaID = $Model->save($Media);
         $Media['MediaID'] = $MediaID;
         if ($generate_thumbnail) {
             $thumbUrl = url('/utility/mediathumbnail/' . $MediaID, true);
         }
         $payload = array('MediaID' => $MediaID, 'Filename' => htmlspecialchars($fileName), 'Filesize' => $fileData['size'], 'FormatFilesize' => Gdn_Format::bytes($fileData['size'], 1), 'type' => $fileData['type'], 'Thumbnail' => '', 'FinalImageLocation' => '', 'Parsed' => $filePathParsed, 'Media' => (array) $Media, 'original_url' => $Upload->url($filePathParsed['SaveName']), 'thumbnail_url' => $thumbUrl, 'original_width' => $imageWidth, 'original_height' => $imageHeight);
         $json = array('error' => 0, 'feedback' => 'Editor received file successfully.', 'payload' => $payload);
     }
     // Return JSON payload
     echo json_encode($json);
 }
示例#3
0
 /**
  * Form for adding an email image.
  * Exposes the Garden.EmailTemplate.Image setting.
  * Garden.EmailTemplate.Image must be an upload.
  *
  * Saves the image based on 2 config settings:
  * Garden.EmailTemplate.ImageMaxWidth (default 400px) and
  * Garden.EmailTemplate.ImageMaxHeight (default 300px)
  *
  * @throws Gdn_UserException
  */
 public function emailImage()
 {
     if (!Gdn::session()->checkPermission('Garden.Community.Manage')) {
         throw permissionException();
     }
     $this->addJsFile('email.js');
     $this->addSideMenu('dashboard/settings/email');
     $image = c('Garden.EmailTemplate.Image');
     $this->Form = new Gdn_Form();
     $validation = new Gdn_Validation();
     $configurationModel = new Gdn_ConfigurationModel($validation);
     // Set the model on the form.
     $this->Form->setModel($configurationModel);
     if ($this->Form->authenticatedPostBack() !== false) {
         try {
             $upload = new Gdn_UploadImage();
             // Validate the upload
             $tmpImage = $upload->validateUpload('EmailImage', false);
             if ($tmpImage) {
                 // Generate the target image name
                 $targetImage = $upload->generateTargetName(PATH_UPLOADS);
                 $imageBaseName = pathinfo($targetImage, PATHINFO_BASENAME);
                 // Delete any previously uploaded images.
                 if ($image) {
                     $upload->delete($image);
                 }
                 // Save the uploaded image
                 $parts = $upload->saveImageAs($tmpImage, $imageBaseName, c('Garden.EmailTemplate.ImageMaxWidth', 400), c('Garden.EmailTemplate.ImageMaxHeight', 300));
                 $imageBaseName = $parts['SaveName'];
                 saveToConfig('Garden.EmailTemplate.Image', $imageBaseName);
                 $this->setData('EmailImage', Gdn_UploadImage::url($imageBaseName));
             } else {
                 $this->Form->addError(t('There\'s been an error uploading the image. Your email logo can uploaded in one of the following filetypes: gif, jpg, png'));
             }
         } catch (Exception $ex) {
             $this->Form->addError($ex);
         }
     }
     $this->render();
 }
 /**
  * Saves the default avatar to /uploads in three formats:
  *   The default image, which is not resized or cropped.
  *   p* : The profile-sized image, which is constrained by Garden.Profile.MaxWidth and Garden.Profile.MaxHeight.
  *   n* : The thumbnail-sized image, which is constrained and cropped according to Garden.Thumbnail.Size.
  *
  * @param string $source The path to the local copy of the image.
  * @param array $thumbOptions The options to save the thumbnail-sized avatar with.
  * @return bool Whether the saves were successful.
  */
 private function saveDefaultAvatars($source, $thumbOptions)
 {
     try {
         $upload = new Gdn_UploadImage();
         // Generate the target image name
         $targetImage = $upload->generateTargetName(PATH_UPLOADS);
         $imageBaseName = pathinfo($targetImage, PATHINFO_BASENAME);
         // Save the full size image.
         $parts = Gdn_UploadImage::saveImageAs($source, self::DEFAULT_AVATAR_FOLDER . '/' . $imageBaseName);
         // Save the profile size image.
         Gdn_UploadImage::saveImageAs($source, self::DEFAULT_AVATAR_FOLDER . "/p{$imageBaseName}", c('Garden.Profile.MaxHeight', 1000), c('Garden.Profile.MaxWidth', 250), array('SaveGif' => c('Garden.Thumbnail.SaveGif')));
         $thumbnailSize = c('Garden.Thumbnail.Size', 40);
         // Save the thumbnail size image.
         Gdn_UploadImage::saveImageAs($source, self::DEFAULT_AVATAR_FOLDER . "/n{$imageBaseName}", $thumbnailSize, $thumbnailSize, $thumbOptions);
     } catch (Exception $ex) {
         $this->Form->addError($ex);
         return false;
     }
     $imageBaseName = $parts['SaveName'];
     saveToConfig('Garden.DefaultAvatar', $imageBaseName);
     return true;
 }
 /**
  * Allows plugin to handle ajax file uploads.
  *
  * @access public
  * @param object $Sender
  */
 public function postController_upload_create($Sender)
 {
     list($FieldName) = $Sender->RequestArgs;
     $Sender->deliveryMethod(DELIVERY_METHOD_JSON);
     $Sender->deliveryType(DELIVERY_TYPE_VIEW);
     include_once $Sender->fetchViewLocation('fileupload_functions', '', 'plugins/FileUpload');
     $Sender->FieldName = $FieldName;
     $Sender->ApcKey = Gdn::request()->getValueFrom(Gdn_Request::INPUT_POST, 'APC_UPLOAD_PROGRESS');
     $FileData = Gdn::request()->getValueFrom(Gdn_Request::INPUT_FILES, $FieldName, false);
     try {
         if (!$this->CanUpload) {
             throw new FileUploadPluginUploadErrorException("You do not have permission to upload files", 11, '???');
         }
         if (!$Sender->Form->isPostBack()) {
             $PostMaxSize = ini_get('post_max_size');
             throw new FileUploadPluginUploadErrorException("The post data was too big (max {$PostMaxSize})", 10, '???');
         }
         if (!$FileData) {
             throw new FileUploadPluginUploadErrorException("No file data could be found in your post", 10, '???');
         }
         // Validate the file upload now.
         $FileErr = $FileData['error'];
         $FileType = $FileData['type'];
         $FileName = $FileData['name'];
         $FileTemp = $FileData['tmp_name'];
         $FileSize = $FileData['size'];
         $FileKey = $Sender->ApcKey ? $Sender->ApcKey : '';
         if ($FileErr != UPLOAD_ERR_OK) {
             $ErrorString = '';
             switch ($FileErr) {
                 case UPLOAD_ERR_INI_SIZE:
                     $MaxUploadSize = ini_get('upload_max_filesize');
                     $ErrorString = sprintf(t('The uploaded file was too big (max %s).'), $MaxUploadSize);
                     break;
                 case UPLOAD_ERR_FORM_SIZE:
                     $ErrorString = 'The uploaded file was too big';
                     break;
                 case UPLOAD_ERR_PARTIAL:
                     $ErrorString = 'The uploaded file was only partially uploaded';
                     break;
                 case UPLOAD_ERR_NO_FILE:
                     $ErrorString = 'No file was uploaded';
                     break;
                 case UPLOAD_ERR_NO_TMP_DIR:
                     $ErrorString = 'Missing a temporary folder';
                     break;
                 case UPLOAD_ERR_CANT_WRITE:
                     $ErrorString = 'Failed to write file to disk';
                     break;
                 case UPLOAD_ERR_EXTENSION:
                     $ErrorString = 'A PHP extension stopped the file upload';
                     break;
             }
             throw new FileUploadPluginUploadErrorException($ErrorString, $FileErr, $FileName, $FileKey);
         }
         // Analyze file extension
         $FileNameParts = pathinfo($FileName);
         $Extension = strtolower($FileNameParts['extension']);
         $AllowedExtensions = C('Garden.Upload.AllowedFileExtensions', array("*"));
         if (!in_array($Extension, $AllowedExtensions) && !in_array('*', $AllowedExtensions)) {
             throw new FileUploadPluginUploadErrorException("Uploaded file type is not allowed.", 11, $FileName, $FileKey);
         }
         // Check upload size
         $MaxUploadSize = Gdn_Upload::unformatFileSize(c('Garden.Upload.MaxFileSize', '1G'));
         if ($FileSize > $MaxUploadSize) {
             $Message = sprintf(t('The uploaded file was too big (max %s).'), Gdn_Upload::formatFileSize($MaxUploadSize));
             throw new FileUploadPluginUploadErrorException($Message, 11, $FileName, $FileKey);
         }
         // Build filename
         $SaveFilename = md5(microtime()) . '.' . strtolower($Extension);
         $SaveFilename = '/FileUpload/' . substr($SaveFilename, 0, 2) . '/' . substr($SaveFilename, 2);
         // Get the image size before doing anything.
         list($ImageWidth, $ImageHeight, $ImageType) = Gdn_UploadImage::imageSize($FileTemp, $FileName);
         // Fire event for hooking save location
         $this->EventArguments['Path'] = $FileTemp;
         $Parsed = Gdn_Upload::parse($SaveFilename);
         $this->EventArguments['Parsed'] =& $Parsed;
         $this->EventArguments['OriginalFilename'] = $FileName;
         $Handled = false;
         $this->EventArguments['Handled'] =& $Handled;
         $this->EventArguments['ImageType'] = $ImageType;
         $this->fireAs('Gdn_Upload')->fireEvent('SaveAs');
         if (!$Handled) {
             // Build save location
             $SavePath = MediaModel::pathUploads() . $SaveFilename;
             if (!is_dir(dirname($SavePath))) {
                 @mkdir(dirname($SavePath), 0777, true);
             }
             if (!is_dir(dirname($SavePath))) {
                 throw new FileUploadPluginUploadErrorException("Internal error, could not save the file.", 9, $FileName);
             }
             // Move to permanent location
             // Use SaveImageAs so that image is rotated if necessary
             if ($ImageType !== false) {
                 try {
                     $ImgParsed = Gdn_UploadImage::saveImageAs($FileTemp, $SavePath);
                     $MoveSuccess = true;
                     // In case image got rotated
                     $ImageWidth = $ImgParsed['Width'];
                     $ImageHeight = $ImgParsed['Height'];
                 } catch (Exception $Ex) {
                     // In case it was an image, but not a supported type - still upload
                     $MoveSuccess = @move_uploaded_file($FileTemp, $SavePath);
                 }
             } else {
                 // If not an image, just upload it
                 $MoveSuccess = @move_uploaded_file($FileTemp, $SavePath);
             }
             if (!$MoveSuccess) {
                 throw new FileUploadPluginUploadErrorException("Internal error, could not move the file.", 9, $FileName);
             }
         } else {
             $SaveFilename = $Parsed['SaveName'];
         }
         // Save Media data
         $Media = array('Name' => $FileName, 'Type' => $FileType, 'Size' => $FileSize, 'ImageWidth' => $ImageWidth, 'ImageHeight' => $ImageHeight, 'InsertUserID' => Gdn::session()->UserID, 'DateInserted' => date('Y-m-d H:i:s'), 'StorageMethod' => 'local', 'Path' => $SaveFilename);
         $MediaID = $this->mediaModel()->save($Media);
         $Media['MediaID'] = $MediaID;
         $MediaResponse = array('Status' => 'success', 'MediaID' => $MediaID, 'Filename' => $FileName, 'Filesize' => $FileSize, 'FormatFilesize' => Gdn_Format::bytes($FileSize, 1), 'ProgressKey' => $Sender->ApcKey ? $Sender->ApcKey : '', 'Thumbnail' => base64_encode(MediaThumbnail($Media)), 'FinalImageLocation' => Url(MediaModel::url($Media)), 'Parsed' => $Parsed);
     } catch (FileUploadPluginUploadErrorException $e) {
         $MediaResponse = array('Status' => 'failed', 'ErrorCode' => $e->getCode(), 'Filename' => $e->getFilename(), 'StrError' => $e->getMessage());
         if (!is_null($e->getApcKey())) {
             $MediaResponse['ProgressKey'] = $e->getApcKey();
         }
         if ($e->getFilename() != '???') {
             $MediaResponse['StrError'] = '(' . $e->getFilename() . ') ' . $MediaResponse['StrError'];
         }
     } catch (Exception $Ex) {
         $MediaResponse = array('Status' => 'failed', 'ErrorCode' => $Ex->getCode(), 'StrError' => $Ex->getMessage());
     }
     $Sender->setJSON('MediaResponse', $MediaResponse);
     // Kludge: This needs to have a content type of text/* because it's in an iframe.
     ob_clean();
     header('Content-Type: text/html');
     echo json_encode($Sender->getJson());
     die;
 }
 /**
  * Save an icon image file.
  *
  * @param string $imageLocation Where to save the icon to file.
  * @return mixed
  * @throws Exception Unable to save icon or GD is not installed.
  */
 protected function saveIcon($imageLocation)
 {
     $uploadImage = new Gdn_UploadImage();
     // Generate the target image name
     $extension = val('extension', pathinfo($imageLocation), '');
     $targetLocation = $uploadImage->generateTargetName('addons/icons', $extension);
     // Save the uploaded icon
     $parsed = $uploadImage->saveImageAs($imageLocation, $targetLocation, 256, 256, false, false);
     return $parsed['SaveName'];
 }
 /**
  * Settings page for HTML email styling.
  *
  * Exposes config settings:
  * Garden.EmailTemplate.BackgroundColor
  * Garden.EmailTemplate.ButtonBackgroundColor
  * Garden.EmailTemplate.ButtonTextColor
  * Garden.EmailTemplate.Image
  *
  * Saves the image based on 2 config settings:
  * Garden.EmailTemplate.ImageMaxWidth (default 400px) and
  * Garden.EmailTemplate.ImageMaxHeight (default 300px)
  *
  * @throws Gdn_UserException
  */
 public function emailStyles()
 {
     // Set default colors
     if (!c('Garden.EmailTemplate.TextColor')) {
         saveToConfig('Garden.EmailTemplate.TextColor', EmailTemplate::DEFAULT_TEXT_COLOR, false);
     }
     if (!c('Garden.EmailTemplate.BackgroundColor')) {
         saveToConfig('Garden.EmailTemplate.BackgroundColor', EmailTemplate::DEFAULT_BACKGROUND_COLOR, false);
     }
     if (!c('Garden.EmailTemplate.ContainerBackgroundColor')) {
         saveToConfig('Garden.EmailTemplate.ContainerBackgroundColor', EmailTemplate::DEFAULT_CONTAINER_BACKGROUND_COLOR, false);
     }
     if (!c('Garden.EmailTemplate.ButtonTextColor')) {
         saveToConfig('Garden.EmailTemplate.ButtonTextColor', EmailTemplate::DEFAULT_BUTTON_TEXT_COLOR, false);
     }
     if (!c('Garden.EmailTemplate.ButtonBackgroundColor')) {
         saveToConfig('Garden.EmailTemplate.ButtonBackgroundColor', EmailTemplate::DEFAULT_BUTTON_BACKGROUND_COLOR, false);
     }
     $this->permission('Garden.Settings.Manage');
     $this->setHighlightRoute('dashboard/settings/emailstyles');
     $this->addJsFile('email.js');
     // Get the current logo.
     $image = c('Garden.EmailTemplate.Image');
     if ($image) {
         $image = ltrim($image, '/');
         $this->setData('EmailImage', Gdn_UploadImage::url($image));
     }
     $this->Form = new Gdn_Form();
     $validation = new Gdn_Validation();
     $configurationModel = new Gdn_ConfigurationModel($validation);
     $configurationModel->setField(array('Garden.EmailTemplate.TextColor', 'Garden.EmailTemplate.BackgroundColor', 'Garden.EmailTemplate.ContainerBackgroundColor', 'Garden.EmailTemplate.ButtonTextColor', 'Garden.EmailTemplate.ButtonBackgroundColor'));
     // Set the model on the form.
     $this->Form->setModel($configurationModel);
     // If seeing the form for the first time...
     if ($this->Form->authenticatedPostBack() === false) {
         // Apply the config settings to the form.
         $this->Form->setData($configurationModel->Data);
     } else {
         $image = c('Garden.EmailTemplate.Image');
         $upload = new Gdn_UploadImage();
         if ($upload->isUpload('EmailImage')) {
             try {
                 $tmpImage = $upload->validateUpload('EmailImage');
                 if ($tmpImage) {
                     // Generate the target image name
                     $targetImage = $upload->generateTargetName(PATH_UPLOADS);
                     $imageBaseName = pathinfo($targetImage, PATHINFO_BASENAME);
                     // Delete any previously uploaded images.
                     if ($image) {
                         $upload->delete($image);
                     }
                     // Save the uploaded image
                     $parts = $upload->saveImageAs($tmpImage, $imageBaseName, c('Garden.EmailTemplate.ImageMaxWidth', 400), c('Garden.EmailTemplate.ImageMaxHeight', 300));
                     $imageBaseName = $parts['SaveName'];
                     saveToConfig('Garden.EmailTemplate.Image', $imageBaseName);
                     $this->setData('EmailImage', Gdn_UploadImage::url($imageBaseName));
                 }
             } catch (Exception $ex) {
                 $this->Form->addError($ex);
             }
         }
         if ($this->Form->save() !== false) {
             $this->informMessage(t("Your settings have been saved."));
         }
     }
     $this->render();
 }
 /**
  * Set user's photo (avatar).
  *
  * @since 2.0.0
  * @access public
  * @param mixed $UserReference Unique identifier, possible username or ID.
  * @param string $Username .
  */
 public function picture($UserReference = '', $Username = '', $UserID = '')
 {
     if (!Gdn::session()->checkRankedPermission(c('Garden.Profile.EditPhotos', true))) {
         throw forbiddenException('@Editing user photos has been disabled.');
     }
     // Permission checks
     $this->permission(array('Garden.Profiles.Edit', 'Moderation.Profiles.Edit', 'Garden.ProfilePicture.Edit'), false);
     $Session = Gdn::session();
     if (!$Session->isValid()) {
         $this->Form->addError('You must be authenticated in order to use this form.');
     }
     // Check ability to manipulate image
     $ImageManipOk = false;
     if (function_exists('gd_info')) {
         $GdInfo = gd_info();
         $GdVersion = preg_replace('/[a-z ()]+/i', '', $GdInfo['GD Version']);
         if ($GdVersion < 2) {
             throw new Exception(sprintf(t("This installation of GD is too old (v%s). Vanilla requires at least version 2 or compatible."), $GdVersion));
         }
     } else {
         throw new Exception(sprintf(t("Unable to detect PHP GD installed on this system. Vanilla requires GD version 2 or better.")));
     }
     // Get user data & prep form.
     if ($this->Form->authenticatedPostBack() && $this->Form->getFormValue('UserID')) {
         $UserID = $this->Form->getFormValue('UserID');
     }
     $this->getUserInfo($UserReference, $Username, $UserID, true);
     $this->Form->setModel($this->UserModel);
     if ($this->Form->authenticatedPostBack() === true) {
         $this->Form->setFormValue('UserID', $this->User->UserID);
         // Set user's Photo attribute to a URL, provided the current user has proper permission to do so.
         $photoUrl = $this->Form->getFormValue('Url', false);
         if ($photoUrl && Gdn::session()->checkPermission('Garden.Settings.Manage')) {
             if (isUrl($photoUrl) && filter_var($photoUrl, FILTER_VALIDATE_URL)) {
                 $UserPhoto = $photoUrl;
             } else {
                 $this->Form->addError('Invalid photo URL');
             }
         } else {
             $UploadImage = new Gdn_UploadImage();
             try {
                 // Validate the upload
                 $TmpImage = $UploadImage->ValidateUpload('Picture');
                 // Generate the target image name.
                 $TargetImage = $UploadImage->GenerateTargetName(PATH_UPLOADS, '', true);
                 $Basename = pathinfo($TargetImage, PATHINFO_BASENAME);
                 $Subdir = stringBeginsWith(dirname($TargetImage), PATH_UPLOADS . '/', false, true);
                 // Delete any previously uploaded image.
                 $UploadImage->delete(changeBasename($this->User->Photo, 'p%s'));
                 // Save the uploaded image in profile size.
                 $Props = $UploadImage->SaveImageAs($TmpImage, "userpics/{$Subdir}/p{$Basename}", c('Garden.Profile.MaxHeight', 1000), c('Garden.Profile.MaxWidth', 250), array('SaveGif' => c('Garden.Thumbnail.SaveGif')));
                 $UserPhoto = sprintf($Props['SaveFormat'], "userpics/{$Subdir}/{$Basename}");
                 //            // Save the uploaded image in preview size
                 //            $UploadImage->SaveImageAs(
                 //               $TmpImage,
                 //               'userpics/t'.$ImageBaseName,
                 //               Gdn::config('Garden.Preview.MaxHeight', 100),
                 //               Gdn::config('Garden.Preview.MaxWidth', 75)
                 //            );
                 // Save the uploaded image in thumbnail size
                 $ThumbSize = Gdn::config('Garden.Thumbnail.Size', 40);
                 $UploadImage->saveImageAs($TmpImage, "userpics/{$Subdir}/n{$Basename}", $ThumbSize, $ThumbSize, array('Crop' => true, 'SaveGif' => c('Garden.Thumbnail.SaveGif')));
             } catch (Exception $Ex) {
                 // Throw the exception on API calls.
                 if ($this->deliveryType() === DELIVERY_TYPE_DATA) {
                     throw $Ex;
                 }
                 $this->Form->addError($Ex);
             }
         }
         // If there were no errors, associate the image with the user
         if ($this->Form->errorCount() == 0) {
             if (!$this->UserModel->save(array('UserID' => $this->User->UserID, 'Photo' => $UserPhoto), array('CheckExisting' => true))) {
                 $this->Form->setValidationResults($this->UserModel->validationResults());
             } else {
                 $this->User->Photo = $UserPhoto;
                 setValue('Photo', $this->Data['Profile'], $UserPhoto);
                 setValue('PhotoUrl', $this->Data['Profile'], Gdn_Upload::url(changeBasename($UserPhoto, 'n%s')));
             }
         }
         // If there were no problems, redirect back to the user account
         if ($this->Form->errorCount() == 0 && $this->deliveryType() !== DELIVERY_TYPE_DATA) {
             $this->informMessage(sprite('Check', 'InformSprite') . t('Your changes have been saved.'), 'Dismissable AutoDismiss HasSprite');
             redirect($this->deliveryType() == DELIVERY_TYPE_VIEW ? userUrl($this->User) : userUrl($this->User, '', 'picture'));
         }
     }
     if ($this->Form->errorCount() > 0 && $this->deliveryType() !== DELIVERY_TYPE_DATA) {
         $this->deliveryType(DELIVERY_TYPE_ALL);
     }
     $this->title(t('Change Picture'));
     $this->_setBreadcrumbs(t('Change My Picture'), userUrl($this->User, '', 'picture'));
     $this->render();
 }
 /**
  * Saves the avatar to /uploads in two sizes:
  *   p* : The profile-sized image, which is constrained by Garden.Profile.MaxWidth and Garden.Profile.MaxHeight.
  *   n* : The thumbnail-sized image, which is constrained and cropped according to Garden.Thumbnail.Size.
  * Also deletes the old avatars.
  *
  * @param string $source The path to the local copy of the image.
  * @param array $thumbOptions The options to save the thumbnail-sized avatar with.
  * @param Gdn_UploadImage|null $upload The upload object.
  * @return bool Whether the saves were successful.
  */
 private function saveAvatars($source, $thumbOptions, $upload = null)
 {
     try {
         $ext = '';
         if (!$upload) {
             $upload = new Gdn_UploadImage();
             $ext = 'jpg';
         }
         // Generate the target image name
         $targetImage = $upload->generateTargetName(PATH_UPLOADS, $ext, true);
         $imageBaseName = pathinfo($targetImage, PATHINFO_BASENAME);
         $subdir = stringBeginsWith(dirname($targetImage), PATH_UPLOADS . '/', false, true);
         // Save the profile size image.
         $parts = Gdn_UploadImage::saveImageAs($source, self::AVATAR_FOLDER . "/{$subdir}/p{$imageBaseName}", c('Garden.Profile.MaxHeight', 1000), c('Garden.Profile.MaxWidth', 250), array('SaveGif' => c('Garden.Thumbnail.SaveGif')));
         $thumbnailSize = c('Garden.Thumbnail.Size', 40);
         // Save the thumbnail size image.
         Gdn_UploadImage::saveImageAs($source, self::AVATAR_FOLDER . "/{$subdir}/n{$imageBaseName}", $thumbnailSize, $thumbnailSize, $thumbOptions);
     } catch (Exception $ex) {
         $this->Form->addError($ex);
         return false;
     }
     $bak = $this->User->Photo;
     $userPhoto = sprintf($parts['SaveFormat'], self::AVATAR_FOLDER . "/{$subdir}/{$imageBaseName}");
     if (!$this->UserModel->save(array('UserID' => $this->User->UserID, 'Photo' => $userPhoto), array('CheckExisting' => true))) {
         $this->Form->setValidationResults($this->UserModel->validationResults());
     } else {
         $this->User->Photo = $userPhoto;
     }
     $this->deleteAvatars($bak);
     return $userPhoto;
 }