AvatarModel.php (9828B)
1 <?php 2 3 class AvatarModel 4 { 5 /** 6 * Gets a gravatar image link from given email address 7 * 8 * Gravatar is the #1 (free) provider for email address based global avatar hosting. 9 * The URL (or image) returns always a .jpg file ! For deeper info on the different parameter possibilities: 10 * @see http://gravatar.com/site/implement/images/ 11 * @source http://gravatar.com/site/implement/images/php/ 12 * 13 * This method will return something like http://www.gravatar.com/avatar/79e2e5b48aec07710c08d50?s=80&d=mm&r=g 14 * Note: the url does NOT have something like ".jpg" ! It works without. 15 * 16 * Set the configs inside the application/config/ files. 17 * 18 * @param string $email The email address 19 * @return string 20 */ 21 public static function getGravatarLinkByEmail($email) 22 { 23 return 'http://www.gravatar.com/avatar/' . 24 md5(strtolower(trim($email))) . 25 '?s=' . Config::get('AVATAR_SIZE') . '&d=' . Config::get('GRAVATAR_DEFAULT_IMAGESET') . '&r=' . Config::get('GRAVATAR_RATING'); 26 } 27 28 /** 29 * Gets the user's avatar file path 30 * @param int $user_has_avatar Marker from database 31 * @param int $user_id User's id 32 * @return string Avatar file path 33 */ 34 public static function getPublicAvatarFilePathOfUser($user_has_avatar, $user_id) 35 { 36 if ($user_has_avatar) { 37 return Config::get('URL') . Config::get('PATH_AVATARS_PUBLIC') . $user_id . '.jpg'; 38 } 39 40 return Config::get('URL') . Config::get('PATH_AVATARS_PUBLIC') . Config::get('AVATAR_DEFAULT_IMAGE'); 41 } 42 43 /** 44 * Gets the user's avatar file path 45 * @param $user_id integer The user's id 46 * @return string avatar picture path 47 */ 48 public static function getPublicUserAvatarFilePathByUserId($user_id) 49 { 50 $database = DatabaseFactory::getFactory()->getConnection(); 51 52 $query = $database->prepare("SELECT user_has_avatar FROM users WHERE user_id = :user_id LIMIT 1"); 53 $query->execute(array(':user_id' => $user_id)); 54 55 if ($query->fetch()->user_has_avatar) { 56 return Config::get('URL') . Config::get('PATH_AVATARS_PUBLIC') . $user_id . '.jpg'; 57 } 58 59 return Config::get('URL') . Config::get('PATH_AVATARS_PUBLIC') . Config::get('AVATAR_DEFAULT_IMAGE'); 60 } 61 62 /** 63 * Create an avatar picture (and checks all necessary things too) 64 * TODO decouple 65 * TODO total rebuild 66 */ 67 public static function createAvatar() 68 { 69 // check avatar folder writing rights, check if upload fits all rules 70 if (self::isAvatarFolderWritable() AND self::validateImageFile()) { 71 // create a jpg file in the avatar folder, write marker to database 72 $target_file_path = Config::get('PATH_AVATARS') . Session::get('user_id'); 73 self::resizeAvatarImage($_FILES['avatar_file']['tmp_name'], $target_file_path, Config::get('AVATAR_SIZE'), Config::get('AVATAR_SIZE')); 74 self::writeAvatarToDatabase(Session::get('user_id')); 75 Session::set('user_avatar_file', self::getPublicUserAvatarFilePathByUserId(Session::get('user_id'))); 76 Session::add('feedback_positive', Text::get('FEEDBACK_AVATAR_UPLOAD_SUCCESSFUL')); 77 } 78 } 79 80 /** 81 * Checks if the avatar folder exists and is writable 82 * 83 * @return bool success status 84 */ 85 public static function isAvatarFolderWritable() 86 { 87 if (is_dir(Config::get('PATH_AVATARS')) AND is_writable(Config::get('PATH_AVATARS'))) { 88 return true; 89 } 90 91 Session::add('feedback_negative', Text::get('FEEDBACK_AVATAR_FOLDER_DOES_NOT_EXIST_OR_NOT_WRITABLE')); 92 return false; 93 } 94 95 /** 96 * Validates the image 97 * Only accepts gif, jpg, png types 98 * @see http://php.net/manual/en/function.image-type-to-mime-type.php 99 * 100 * @return bool 101 */ 102 public static function validateImageFile() 103 { 104 if (!isset($_FILES['avatar_file'])) { 105 Session::add('feedback_negative', Text::get('FEEDBACK_AVATAR_IMAGE_UPLOAD_FAILED')); 106 return false; 107 } 108 109 // if input file too big (>5MB) 110 if ($_FILES['avatar_file']['size'] > 5000000) { 111 Session::add('feedback_negative', Text::get('FEEDBACK_AVATAR_UPLOAD_TOO_BIG')); 112 return false; 113 } 114 115 // get the image width, height and mime type 116 $image_proportions = getimagesize($_FILES['avatar_file']['tmp_name']); 117 118 // if input file too small, [0] is the width, [1] is the height 119 if ($image_proportions[0] < Config::get('AVATAR_SIZE') OR $image_proportions[1] < Config::get('AVATAR_SIZE')) { 120 Session::add('feedback_negative', Text::get('FEEDBACK_AVATAR_UPLOAD_TOO_SMALL')); 121 return false; 122 } 123 124 // if file type is not jpg, gif or png 125 if (!in_array($image_proportions['mime'], array('image/jpeg', 'image/gif', 'image/png'))) { 126 Session::add('feedback_negative', Text::get('FEEDBACK_AVATAR_UPLOAD_WRONG_TYPE')); 127 return false; 128 } 129 130 return true; 131 } 132 133 /** 134 * Writes marker to database, saying user has an avatar now 135 * 136 * @param $user_id 137 */ 138 public static function writeAvatarToDatabase($user_id) 139 { 140 $database = DatabaseFactory::getFactory()->getConnection(); 141 142 $query = $database->prepare("UPDATE users SET user_has_avatar = TRUE WHERE user_id = :user_id LIMIT 1"); 143 $query->execute(array(':user_id' => $user_id)); 144 } 145 146 /** 147 * Resize avatar image (while keeping aspect ratio and cropping it off in a clean way). 148 * Only works with gif, jpg and png file types. If you want to change this also have a look into 149 * method validateImageFile() inside this model. 150 * 151 * TROUBLESHOOTING: You don't see the new image ? Press F5 or CTRL-F5 to refresh browser cache. 152 * 153 * @param string $source_image The location to the original raw image 154 * @param string $destination The location to save the new image 155 * @param int $final_width The desired width of the new image 156 * @param int $final_height The desired height of the new image 157 * 158 * @return bool success state 159 */ 160 public static function resizeAvatarImage($source_image, $destination, $final_width = 44, $final_height = 44) 161 { 162 $imageData = getimagesize($source_image); 163 $width = $imageData[0]; 164 $height = $imageData[1]; 165 $mimeType = $imageData['mime']; 166 167 if (!$width || !$height) { 168 return false; 169 } 170 171 switch ($mimeType) { 172 case 'image/jpeg': $myImage = imagecreatefromjpeg($source_image); break; 173 case 'image/png': $myImage = imagecreatefrompng($source_image); break; 174 case 'image/gif': $myImage = imagecreatefromgif($source_image); break; 175 default: return false; 176 } 177 178 // calculating the part of the image to use for thumbnail 179 if ($width > $height) { 180 $verticalCoordinateOfSource = 0; 181 $horizontalCoordinateOfSource = ($width - $height) / 2; 182 $smallestSide = $height; 183 } else { 184 $horizontalCoordinateOfSource = 0; 185 $verticalCoordinateOfSource = ($height - $width) / 2; 186 $smallestSide = $width; 187 } 188 189 // copying the part into thumbnail, maybe edit this for square avatars 190 $thumb = imagecreatetruecolor($final_width, $final_height); 191 imagecopyresampled($thumb, $myImage, 0, 0, $horizontalCoordinateOfSource, $verticalCoordinateOfSource, $final_width, $final_height, $smallestSide, $smallestSide); 192 193 // add '.jpg' to file path, save it as a .jpg file with our $destination_filename parameter 194 imagejpeg($thumb, $destination . '.jpg', Config::get('AVATAR_JPEG_QUALITY')); 195 imagedestroy($thumb); 196 197 if (file_exists($destination)) { 198 return true; 199 } 200 return false; 201 } 202 203 /** 204 * Delete a user's avatar 205 * 206 * @param int $userId 207 * @return bool success 208 */ 209 public static function deleteAvatar($userId) 210 { 211 if (!ctype_digit($userId)) { 212 Session::add("feedback_negative", Text::get("FEEDBACK_AVATAR_IMAGE_DELETE_FAILED")); 213 return false; 214 } 215 216 // try to delete image, but still go on regardless of file deletion result 217 self::deleteAvatarImageFile($userId); 218 219 $database = DatabaseFactory::getFactory()->getConnection(); 220 221 $sth = $database->prepare("UPDATE users SET user_has_avatar = 0 WHERE user_id = :user_id LIMIT 1"); 222 $sth->bindValue(":user_id", (int)$userId, PDO::PARAM_INT); 223 $sth->execute(); 224 225 if ($sth->rowCount() == 1) { 226 Session::set('user_avatar_file', self::getPublicUserAvatarFilePathByUserId($userId)); 227 Session::add("feedback_positive", Text::get("FEEDBACK_AVATAR_IMAGE_DELETE_SUCCESSFUL")); 228 return true; 229 } else { 230 Session::add("feedback_negative", Text::get("FEEDBACK_AVATAR_IMAGE_DELETE_FAILED")); 231 return false; 232 } 233 } 234 235 /** 236 * Removes the avatar image file from the filesystem 237 * 238 * @param integer $userId 239 * @return bool 240 */ 241 public static function deleteAvatarImageFile($userId) 242 { 243 // Check if file exists 244 if (!file_exists(Config::get('PATH_AVATARS') . $userId . ".jpg")) { 245 Session::add("feedback_negative", Text::get("FEEDBACK_AVATAR_IMAGE_DELETE_NO_FILE")); 246 return false; 247 } 248 249 // Delete avatar file 250 if (!unlink(Config::get('PATH_AVATARS') . $userId . ".jpg")) { 251 Session::add("feedback_negative", Text::get("FEEDBACK_AVATAR_IMAGE_DELETE_FAILED")); 252 return false; 253 } 254 255 return true; 256 } 257 }