UserModel.php (13506B)
1 <?php 2 3 /** 4 * UserModel 5 * Handles all the PUBLIC profile stuff. This is not for getting data of the logged in user, it's more for handling 6 * data of all the other users. Useful for display profile information, creating user lists etc. 7 */ 8 class UserModel 9 { 10 /** 11 * Gets an array that contains all the users in the database. The array's keys are the user ids. 12 * Each array element is an object, containing a specific user's data. 13 * The avatar line is built using Ternary Operators, have a look here for more: 14 * @see http://davidwalsh.name/php-shorthand-if-else-ternary-operators 15 * 16 * @return array The profiles of all users 17 */ 18 public static function getPublicProfilesOfAllUsers() 19 { 20 $database = DatabaseFactory::getFactory()->getConnection(); 21 22 $sql = "SELECT user_id, user_name, user_email, user_active, user_has_avatar, user_deleted FROM users"; 23 $query = $database->prepare($sql); 24 $query->execute(); 25 26 $all_users_profiles = array(); 27 28 foreach ($query->fetchAll() as $user) { 29 30 // all elements of array passed to Filter::XSSFilter for XSS sanitation, have a look into 31 // application/core/Filter.php for more info on how to use. Removes (possibly bad) JavaScript etc from 32 // the user's values 33 array_walk_recursive($user, 'Filter::XSSFilter'); 34 35 $all_users_profiles[$user->user_id] = new stdClass(); 36 $all_users_profiles[$user->user_id]->user_id = $user->user_id; 37 $all_users_profiles[$user->user_id]->user_name = $user->user_name; 38 $all_users_profiles[$user->user_id]->user_email = $user->user_email; 39 $all_users_profiles[$user->user_id]->user_active = $user->user_active; 40 $all_users_profiles[$user->user_id]->user_deleted = $user->user_deleted; 41 $all_users_profiles[$user->user_id]->user_avatar_link = (Config::get('USE_GRAVATAR') ? AvatarModel::getGravatarLinkByEmail($user->user_email) : AvatarModel::getPublicAvatarFilePathOfUser($user->user_has_avatar, $user->user_id)); 42 } 43 44 return $all_users_profiles; 45 } 46 47 /** 48 * Gets a user's profile data, according to the given $user_id 49 * @param int $user_id The user's id 50 * @return mixed The selected user's profile 51 */ 52 public static function getPublicProfileOfUser($user_id) 53 { 54 $database = DatabaseFactory::getFactory()->getConnection(); 55 56 $sql = "SELECT user_id, user_name, user_email, user_active, user_has_avatar, user_deleted 57 FROM users WHERE user_id = :user_id LIMIT 1"; 58 $query = $database->prepare($sql); 59 $query->execute(array(':user_id' => $user_id)); 60 61 $user = $query->fetch(); 62 63 if ($query->rowCount() == 1) { 64 if (Config::get('USE_GRAVATAR')) { 65 $user->user_avatar_link = AvatarModel::getGravatarLinkByEmail($user->user_email); 66 } else { 67 $user->user_avatar_link = AvatarModel::getPublicAvatarFilePathOfUser($user->user_has_avatar, $user->user_id); 68 } 69 } else { 70 Session::add('feedback_negative', Text::get('FEEDBACK_USER_DOES_NOT_EXIST')); 71 } 72 73 // all elements of array passed to Filter::XSSFilter for XSS sanitation, have a look into 74 // application/core/Filter.php for more info on how to use. Removes (possibly bad) JavaScript etc from 75 // the user's values 76 array_walk_recursive($user, 'Filter::XSSFilter'); 77 78 return $user; 79 } 80 81 /** 82 * @param $user_name_or_email 83 * 84 * @return mixed 85 */ 86 public static function getUserDataByUserNameOrEmail($user_name_or_email) 87 { 88 $database = DatabaseFactory::getFactory()->getConnection(); 89 90 $query = $database->prepare("SELECT user_id, user_name, user_email FROM users 91 WHERE (user_name = :user_name_or_email OR user_email = :user_name_or_email) 92 AND user_provider_type = :provider_type LIMIT 1"); 93 $query->execute(array(':user_name_or_email' => $user_name_or_email, ':provider_type' => 'DEFAULT')); 94 95 return $query->fetch(); 96 } 97 98 /** 99 * Checks if a username is already taken 100 * 101 * @param $user_name string username 102 * 103 * @return bool 104 */ 105 public static function doesUsernameAlreadyExist($user_name) 106 { 107 $database = DatabaseFactory::getFactory()->getConnection(); 108 109 $query = $database->prepare("SELECT user_id FROM users WHERE user_name = :user_name LIMIT 1"); 110 $query->execute(array(':user_name' => $user_name)); 111 if ($query->rowCount() == 0) { 112 return false; 113 } 114 return true; 115 } 116 117 /** 118 * Checks if a email is already used 119 * 120 * @param $user_email string email 121 * 122 * @return bool 123 */ 124 public static function doesEmailAlreadyExist($user_email) 125 { 126 $database = DatabaseFactory::getFactory()->getConnection(); 127 128 $query = $database->prepare("SELECT user_id FROM users WHERE user_email = :user_email LIMIT 1"); 129 $query->execute(array(':user_email' => $user_email)); 130 if ($query->rowCount() == 0) { 131 return false; 132 } 133 return true; 134 } 135 136 /** 137 * Writes new username to database 138 * 139 * @param $user_id int user id 140 * @param $new_user_name string new username 141 * 142 * @return bool 143 */ 144 public static function saveNewUserName($user_id, $new_user_name) 145 { 146 $database = DatabaseFactory::getFactory()->getConnection(); 147 148 $query = $database->prepare("UPDATE users SET user_name = :user_name WHERE user_id = :user_id LIMIT 1"); 149 $query->execute(array(':user_name' => $new_user_name, ':user_id' => $user_id)); 150 if ($query->rowCount() == 1) { 151 return true; 152 } 153 return false; 154 } 155 156 /** 157 * Writes new email address to database 158 * 159 * @param $user_id int user id 160 * @param $new_user_email string new email address 161 * 162 * @return bool 163 */ 164 public static function saveNewEmailAddress($user_id, $new_user_email) 165 { 166 $database = DatabaseFactory::getFactory()->getConnection(); 167 168 $query = $database->prepare("UPDATE users SET user_email = :user_email WHERE user_id = :user_id LIMIT 1"); 169 $query->execute(array(':user_email' => $new_user_email, ':user_id' => $user_id)); 170 $count = $query->rowCount(); 171 if ($count == 1) { 172 return true; 173 } 174 return false; 175 } 176 177 /** 178 * Edit the user's name, provided in the editing form 179 * 180 * @param $new_user_name string The new username 181 * 182 * @return bool success status 183 */ 184 public static function editUserName($new_user_name) 185 { 186 // new username same as old one ? 187 if ($new_user_name == Session::get('user_name')) { 188 Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_SAME_AS_OLD_ONE')); 189 return false; 190 } 191 192 // username cannot be empty and must be azAZ09 and 2-64 characters 193 if (!preg_match("/^[a-zA-Z0-9]{2,64}$/", $new_user_name)) { 194 Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_DOES_NOT_FIT_PATTERN')); 195 return false; 196 } 197 198 // clean the input, strip usernames longer than 64 chars (maybe fix this ?) 199 $new_user_name = substr(strip_tags($new_user_name), 0, 64); 200 201 // check if new username already exists 202 if (self::doesUsernameAlreadyExist($new_user_name)) { 203 Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_ALREADY_TAKEN')); 204 return false; 205 } 206 207 $status_of_action = self::saveNewUserName(Session::get('user_id'), $new_user_name); 208 if ($status_of_action) { 209 Session::set('user_name', $new_user_name); 210 Session::add('feedback_positive', Text::get('FEEDBACK_USERNAME_CHANGE_SUCCESSFUL')); 211 return true; 212 } else { 213 Session::add('feedback_negative', Text::get('FEEDBACK_UNKNOWN_ERROR')); 214 return false; 215 } 216 } 217 218 /** 219 * Edit the user's email 220 * 221 * @param $new_user_email 222 * 223 * @return bool success status 224 */ 225 public static function editUserEmail($new_user_email) 226 { 227 // email provided ? 228 if (empty($new_user_email)) { 229 Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_FIELD_EMPTY')); 230 return false; 231 } 232 233 // check if new email is same like the old one 234 if ($new_user_email == Session::get('user_email')) { 235 Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_SAME_AS_OLD_ONE')); 236 return false; 237 } 238 239 // user's email must be in valid email format, also checks the length 240 // @see http://stackoverflow.com/questions/21631366/php-filter-validate-email-max-length 241 // @see http://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address 242 if (!filter_var($new_user_email, FILTER_VALIDATE_EMAIL)) { 243 Session::add('feedback_negative', Text::get('FEEDBACK_EMAIL_DOES_NOT_FIT_PATTERN')); 244 return false; 245 } 246 247 // strip tags, just to be sure 248 $new_user_email = substr(strip_tags($new_user_email), 0, 254); 249 250 // check if user's email already exists 251 if (self::doesEmailAlreadyExist($new_user_email)) { 252 Session::add('feedback_negative', Text::get('FEEDBACK_USER_EMAIL_ALREADY_TAKEN')); 253 return false; 254 } 255 256 // write to database, if successful ... 257 // ... then write new email to session, Gravatar too (as this relies to the user's email address) 258 if (self::saveNewEmailAddress(Session::get('user_id'), $new_user_email)) { 259 Session::set('user_email', $new_user_email); 260 Session::set('user_gravatar_image_url', AvatarModel::getGravatarLinkByEmail($new_user_email)); 261 Session::add('feedback_positive', Text::get('FEEDBACK_EMAIL_CHANGE_SUCCESSFUL')); 262 return true; 263 } 264 265 Session::add('feedback_negative', Text::get('FEEDBACK_UNKNOWN_ERROR')); 266 return false; 267 } 268 269 /** 270 * Gets the user's id 271 * 272 * @param $user_name 273 * 274 * @return mixed 275 */ 276 public static function getUserIdByUsername($user_name) 277 { 278 $database = DatabaseFactory::getFactory()->getConnection(); 279 280 $sql = "SELECT user_id FROM users WHERE user_name = :user_name AND user_provider_type = :provider_type LIMIT 1"; 281 $query = $database->prepare($sql); 282 283 // DEFAULT is the marker for "normal" accounts (that have a password etc.) 284 // There are other types of accounts that don't have passwords etc. (FACEBOOK) 285 $query->execute(array(':user_name' => $user_name, ':provider_type' => 'DEFAULT')); 286 287 // return one row (we only have one result or nothing) 288 return $query->fetch()->user_id; 289 } 290 291 /** 292 * Gets the user's data 293 * 294 * @param $user_name string User's name 295 * 296 * @return mixed Returns false if user does not exist, returns object with user's data when user exists 297 */ 298 public static function getUserDataByUsername($user_name) 299 { 300 $database = DatabaseFactory::getFactory()->getConnection(); 301 302 $sql = "SELECT user_id, user_name, user_email, user_password_hash, user_active,user_deleted, user_suspension_timestamp, user_account_type, 303 user_failed_logins, user_last_failed_login 304 FROM users 305 WHERE (user_name = :user_name OR user_email = :user_name) 306 AND user_provider_type = :provider_type 307 LIMIT 1"; 308 $query = $database->prepare($sql); 309 310 // DEFAULT is the marker for "normal" accounts (that have a password etc.) 311 // There are other types of accounts that don't have passwords etc. (FACEBOOK) 312 $query->execute(array(':user_name' => $user_name, ':provider_type' => 'DEFAULT')); 313 314 // return one row (we only have one result or nothing) 315 return $query->fetch(); 316 } 317 318 /** 319 * Gets the user's data by user's id and a token (used by login-via-cookie process) 320 * 321 * @param $user_id 322 * @param $token 323 * 324 * @return mixed Returns false if user does not exist, returns object with user's data when user exists 325 */ 326 public static function getUserDataByUserIdAndToken($user_id, $token) 327 { 328 $database = DatabaseFactory::getFactory()->getConnection(); 329 330 // get real token from database (and all other data) 331 $query = $database->prepare("SELECT user_id, user_name, user_email, user_password_hash, user_active, 332 user_account_type, user_has_avatar, user_failed_logins, user_last_failed_login 333 FROM users 334 WHERE user_id = :user_id 335 AND user_remember_me_token = :user_remember_me_token 336 AND user_remember_me_token IS NOT NULL 337 AND user_provider_type = :provider_type LIMIT 1"); 338 $query->execute(array(':user_id' => $user_id, ':user_remember_me_token' => $token, ':provider_type' => 'DEFAULT')); 339 340 // return one row (we only have one result or nothing) 341 return $query->fetch(); 342 } 343 }