Installer
3 years ago
AdminNotices.php
1 month ago
AjaxHandler.php
1 year ago
Autologin.php
9 months ago
BlockRegistrations.php
10 months ago
BuddyPressBbPress.php
3 years ago
DisableConcurrentLogins.php
2 years ago
EditUserProfile.php
5 months ago
ExtensionManager.php
1 month ago
FileUploader.php
3 months ago
FormPreviewHandler.php
5 months ago
FormRepository.php
1 year ago
FormShortcodeDefaults.php
1 month ago
GDPR.php
3 years ago
Geolocation.php
3 years ago
GlobalSiteAccess.php
3 years ago
ImageUploader.php
1 year ago
LoginAuth.php
1 year ago
Miscellaneous.php
3 years ago
ModifyRedirectDefaultLinks.php
5 months ago
PPRESS_Session.php
1 year ago
PROFILEPRESS_sql.php
1 year ago
PasswordReset.php
1 year ago
ProfileUrlRewrite.php
4 years ago
RegistrationAuth.php
1 week ago
SendEmail.php
3 years ago
ShortcodeThemeFactory.php
5 years ago
UserAvatar.php
1 year ago
UserSignupLocationListingPage.php
3 years ago
UsernameEmailRestrictLogin.php
4 years ago
WPProfileFieldParserTrait.php
1 year ago
WelcomeEmailAfterSignup.php
1 year ago
default-email-template.php
1 year ago
index.php
3 years ago
EditUserProfile.php
470 lines
| 1 | <?php |
| 2 | |
| 3 | namespace ProfilePress\Core\Classes; |
| 4 | |
| 5 | class EditUserProfile |
| 6 | { |
| 7 | public static function get_success_message($form_id = 0, $is_melange = false) |
| 8 | { |
| 9 | $success_message = FormRepository::get_form_meta($form_id, FormRepository::EDIT_PROFILE_TYPE, FormRepository::SUCCESS_MESSAGE); |
| 10 | |
| 11 | if ($is_melange) { |
| 12 | $success_message = FormRepository::get_form_meta($form_id, FormRepository::EDIT_PROFILE_TYPE, FormRepository::MELANGE_EDIT_PROFILE_SUCCESS_MESSAGE); |
| 13 | } |
| 14 | |
| 15 | if (FormRepository::is_drag_drop($form_id, FormRepository::EDIT_PROFILE_TYPE)) { |
| 16 | // Drag and drop do not allow the use of div wrapper. only the message to be shown is entered. |
| 17 | // so here, we are wrapping it in edit profile status div. |
| 18 | if ( ! empty($success_message)) { |
| 19 | $success_message = '<div class="profilepress-edit-profile-status success">' . $success_message . '</div>'; |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | $success_message = ! empty($success_message) ? $success_message : '<div class="profilepress-edit-profile-status success">' . esc_html__('Account was updated successfully.', 'wp-user-avatar') . '</div>'; |
| 24 | |
| 25 | return apply_filters('ppress_edit_profile_success_message', $success_message); |
| 26 | } |
| 27 | |
| 28 | /** |
| 29 | * @param $form_id |
| 30 | * @param $redirect |
| 31 | * @param bool $is_melange |
| 32 | * |
| 33 | * @return mixed|void the edit profile response be it error or success message |
| 34 | */ |
| 35 | public static function process_func($form_id, $redirect, $is_melange = false) |
| 36 | { |
| 37 | $success_message = self::get_success_message($form_id, $is_melange); |
| 38 | |
| 39 | $edit_profile_response = self::update_user_profile($form_id, $redirect); |
| 40 | |
| 41 | if ( ! empty($edit_profile_response) && wp_doing_ajax()) { |
| 42 | $ajax_response = []; |
| 43 | |
| 44 | if (is_string($edit_profile_response)) { |
| 45 | $ajax_response['message'] = '<div class="profilepress-edit-profile-status">' . $edit_profile_response . '</div>'; |
| 46 | } |
| 47 | |
| 48 | if (is_array($edit_profile_response) && $edit_profile_response['status'] == 'success') { |
| 49 | $ajax_response['message'] = wp_kses_post(html_entity_decode($success_message)); |
| 50 | |
| 51 | if ( ! empty($edit_profile_response['avatar_url'])) { |
| 52 | $ajax_response['avatar_url'] = $edit_profile_response['avatar_url']; |
| 53 | } |
| 54 | |
| 55 | if ( ! empty($edit_profile_response['cover_image_url'])) { |
| 56 | $ajax_response['cover_image_url'] = $edit_profile_response['cover_image_url']; |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | if ( ! empty($redirect)) { |
| 61 | $ajax_response['redirect'] = esc_url_raw($redirect); |
| 62 | } |
| 63 | |
| 64 | return $ajax_response; |
| 65 | } |
| 66 | |
| 67 | if ( ! empty($edit_profile_response)) { |
| 68 | return '<div class="profilepress-edit-profile-status">' . $edit_profile_response . '</div>'; |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | public static function get_current_user_id() |
| 73 | { |
| 74 | return get_current_user_id(); |
| 75 | } |
| 76 | |
| 77 | /** |
| 78 | * Update user profile. |
| 79 | * |
| 80 | * @param int $form_id ID of edit profile form |
| 81 | * @param string $redirect URL to redirect to after edit profile. |
| 82 | * |
| 83 | * @return mixed |
| 84 | */ |
| 85 | public static function update_user_profile($form_id, $redirect = '') |
| 86 | { |
| 87 | if (wp_doing_ajax()) { |
| 88 | ppress_verify_ajax_nonce(); |
| 89 | } else { |
| 90 | ppress_verify_nonce(); |
| 91 | } |
| 92 | |
| 93 | $post = $_POST; |
| 94 | |
| 95 | $old_user_data = get_userdata(self::get_current_user_id()); |
| 96 | |
| 97 | /* Validate and add custom validation to edit profile */ |
| 98 | $validation_errors = apply_filters('ppress_edit_profile_validation', '', $form_id); |
| 99 | |
| 100 | if (is_wp_error($validation_errors)) { |
| 101 | return $validation_errors->get_error_message(); |
| 102 | } |
| 103 | |
| 104 | // create an array of acceptable userdata for use by wp_update_user |
| 105 | $valid_userdata = array( |
| 106 | 'eup_username', |
| 107 | 'eup_password', |
| 108 | 'eup_email', |
| 109 | 'eup_email2', |
| 110 | 'eup_website', |
| 111 | 'eup_nickname', |
| 112 | 'eup_display_name', |
| 113 | 'eup_first_name', |
| 114 | 'eup_last_name', |
| 115 | 'eup_bio' |
| 116 | ); |
| 117 | |
| 118 | if (isset($post['eup_email']) && ! is_email($post['eup_email'])) { |
| 119 | return esc_html__('Email address is invalid. Please try again', 'wp-user-avatar'); |
| 120 | } |
| 121 | |
| 122 | if (isset($post['eup_email2']) && ! is_email($post['eup_email2'])) { |
| 123 | return esc_html__('Email address confirmation is invalid. Please try again', 'wp-user-avatar'); |
| 124 | } |
| 125 | |
| 126 | if (isset($post['eup_email2']) && ($post['eup_email'] != $post['eup_email2'])) { |
| 127 | return esc_html__('Email addresses do not match. Please try again', 'wp-user-avatar'); |
| 128 | } |
| 129 | |
| 130 | if (isset($post['eup_password2'])) { |
| 131 | |
| 132 | // if set to true, empty password and empty confirm password field will cause password not to be changed. |
| 133 | if (apply_filters('ppress_allow_empty_password_unchanged', false)) { |
| 134 | if ( ! empty($post['eup_password']) && ! empty($post['eup_password2'])) { |
| 135 | if (($post['eup_password'] != $post['eup_password2'])) { |
| 136 | return esc_html__('Password do not match. Please try again.', 'wp-user-avatar'); |
| 137 | } |
| 138 | } |
| 139 | } else { |
| 140 | if (empty($post['eup_password']) || empty($post['eup_password2'])) { |
| 141 | return esc_html__('Password is empty or do not match. Please try again.', 'wp-user-avatar'); |
| 142 | } |
| 143 | |
| 144 | if (($post['eup_password'] != $post['eup_password2'])) { |
| 145 | return esc_html__('Password do not match. Please try again.', 'wp-user-avatar'); |
| 146 | } |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | // get the escaped data for userdata |
| 151 | $escaped_post_data = self::escaped_post_data($post); |
| 152 | |
| 153 | // get the data for use by update_user_meta |
| 154 | $custom_usermeta = apply_filters('ppress_edit_profile_custom_usermeta', self::custom_usermeta_data($escaped_post_data, $valid_userdata), $form_id); |
| 155 | |
| 156 | // convert the form post data to userdata for use by wp_update_users |
| 157 | $real_userdata = array(); |
| 158 | |
| 159 | $real_userdata['ID'] = self::get_current_user_id(); |
| 160 | |
| 161 | // only process password change if it is specified. |
| 162 | if ( ! empty($post['eup_password'])) { |
| 163 | // never escape password. |
| 164 | $real_userdata['user_pass'] = $post['eup_password']; |
| 165 | } |
| 166 | |
| 167 | if (isset($post['eup_email'])) { |
| 168 | $real_userdata['user_email'] = $escaped_post_data['eup_email']; |
| 169 | } |
| 170 | |
| 171 | if (isset($post['eup_website'])) { |
| 172 | $real_userdata['user_url'] = $escaped_post_data['eup_website']; |
| 173 | } |
| 174 | |
| 175 | if (isset($post['eup_nickname'])) { |
| 176 | $real_userdata['nickname'] = $escaped_post_data['eup_nickname']; |
| 177 | } |
| 178 | |
| 179 | if (isset($post['eup_display_name'])) { |
| 180 | $real_userdata['display_name'] = $escaped_post_data['eup_display_name']; |
| 181 | } |
| 182 | |
| 183 | if (isset($post['eup_first_name'])) { |
| 184 | $real_userdata['first_name'] = $escaped_post_data['eup_first_name']; |
| 185 | } |
| 186 | |
| 187 | if (isset($post['eup_last_name'])) { |
| 188 | $real_userdata['last_name'] = $escaped_post_data['eup_last_name']; |
| 189 | } |
| 190 | |
| 191 | if (isset($post['eup_bio'])) { |
| 192 | $real_userdata['description'] = $escaped_post_data['eup_bio']; |
| 193 | } |
| 194 | |
| 195 | // merge real data(for use by wp_insert_user()) and custom fields data |
| 196 | $user_data = apply_filters('ppress_edit_profile_user_data', array_merge($real_userdata, $custom_usermeta), $form_id); |
| 197 | |
| 198 | /** |
| 199 | * Fires before profile is updated |
| 200 | * |
| 201 | * @param $user_data array user_data of user being updated |
| 202 | * @param $form_id int builder ID |
| 203 | */ |
| 204 | do_action('ppress_before_profile_update', $user_data, $form_id); |
| 205 | |
| 206 | $ajax_response = array(); |
| 207 | |
| 208 | if (isset($_FILES['eup_avatar']['name']) && ! empty($_FILES['eup_avatar']['name'])) { |
| 209 | $upload_avatar = ImageUploader::process($_FILES['eup_avatar']); |
| 210 | |
| 211 | if (is_wp_error($upload_avatar)) { |
| 212 | return $upload_avatar->get_error_message(); |
| 213 | } |
| 214 | |
| 215 | // update custom field |
| 216 | $custom_usermeta['pp_profile_avatar'] = $upload_avatar; |
| 217 | |
| 218 | /** WP User Avatar Adapter STARTS */ |
| 219 | self::delete_deprecated_wp_user_avatar_image(); |
| 220 | /** WP User Avatar Adapter ENDS */ |
| 221 | |
| 222 | if (wp_doing_ajax()) { |
| 223 | $ajax_response['avatar_url'] = PPRESS_AVATAR_UPLOAD_URL . $upload_avatar; |
| 224 | } |
| 225 | } |
| 226 | |
| 227 | if (isset($_FILES['eup_cover_image']['name']) && ! empty($_FILES['eup_cover_image']['name'])) { |
| 228 | |
| 229 | $upload_cover_image = ImageUploader::process($_FILES['eup_cover_image'], ImageUploader::COVER_IMAGE, PPRESS_COVER_IMAGE_UPLOAD_DIR); |
| 230 | |
| 231 | if (is_wp_error($upload_cover_image)) { |
| 232 | return $upload_cover_image->get_error_message(); |
| 233 | } |
| 234 | |
| 235 | $custom_usermeta['pp_profile_cover_image'] = $upload_cover_image; |
| 236 | |
| 237 | if (wp_doing_ajax()) { |
| 238 | $ajax_response['cover_image_url'] = PPRESS_COVER_IMAGE_UPLOAD_URL . $upload_cover_image; |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | // update file uploads |
| 243 | $uploads = FileUploader::init(); |
| 244 | $upload_errors = ''; |
| 245 | foreach ($uploads as $field_key => $uploaded_filename_or_wp_error) { |
| 246 | if (is_wp_error($uploaded_filename_or_wp_error)) { |
| 247 | $upload_errors .= $uploaded_filename_or_wp_error->get_error_message() . '<br/>'; |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | if ( ! empty($upload_errors)) return $upload_errors; |
| 252 | |
| 253 | // we get the old array of stored file for the user |
| 254 | $old = get_user_meta(self::get_current_user_id(), 'pp_uploaded_files', true); |
| 255 | $old = ! empty($old) ? $old : array(); |
| 256 | |
| 257 | // we loop through the array of newly uploaded files and remove any file (un-setting the file array key) |
| 258 | // that isn't be updated i.e if the field is left empty, un-setting it prevent update_user_meta |
| 259 | // fom overriding it. |
| 260 | // we then merge the old and new uploads before saving the data to user meta table. |
| 261 | foreach ($uploads as $key => $value) { |
| 262 | if (empty($value)) { |
| 263 | unset($uploads[$key]); |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | update_user_meta(self::get_current_user_id(), 'pp_uploaded_files', array_merge($old, $uploads)); |
| 268 | |
| 269 | if (is_array($custom_usermeta)) { |
| 270 | |
| 271 | $user_id = self::get_current_user_id(); |
| 272 | |
| 273 | foreach ($custom_usermeta as $key => $value) { |
| 274 | |
| 275 | update_user_meta($user_id, $key, $value); |
| 276 | |
| 277 | // the 'edit_profile' parameter is used to distinguish it from same action hook in RegistrationAuth |
| 278 | do_action('ppress_after_custom_field_update', $key, $value, $user_id, 'edit_profile'); |
| 279 | } |
| 280 | } |
| 281 | |
| 282 | // proceed to profile edit using wp_update_user method which return the new user id |
| 283 | $update_user = wp_update_user($real_userdata); |
| 284 | |
| 285 | if (is_wp_error($update_user)) { |
| 286 | return $update_user->get_error_message(); |
| 287 | } |
| 288 | |
| 289 | if ( ! is_wp_error($update_user)) { |
| 290 | |
| 291 | /** |
| 292 | * Fires after profile is updated |
| 293 | * |
| 294 | * @param array $user_data |
| 295 | * @param int $form_id |
| 296 | * @param \WP_User $old_user_data |
| 297 | */ |
| 298 | do_action('ppress_after_profile_update', $user_data, $form_id, $old_user_data); |
| 299 | |
| 300 | // success flag is used by ajax mode. see self::process_func() |
| 301 | if (wp_doing_ajax()) { |
| 302 | $ajax_response['status'] = 'success'; |
| 303 | |
| 304 | return $ajax_response; |
| 305 | } |
| 306 | |
| 307 | $url = apply_filters('ppress_redirect_after_profile_edit', esc_url_raw(add_query_arg('edit', 'true'))); |
| 308 | |
| 309 | if ( ! empty($redirect)) { |
| 310 | $url = esc_url_raw($redirect); |
| 311 | } |
| 312 | |
| 313 | wp_safe_redirect($url); |
| 314 | exit; |
| 315 | } |
| 316 | |
| 317 | return esc_html__('Something unexpected happened. Please try again', 'wp-user-avatar'); |
| 318 | } |
| 319 | |
| 320 | /** |
| 321 | * Escaped the POST data |
| 322 | * |
| 323 | * @param $post_data array raw post data |
| 324 | * |
| 325 | * @return array |
| 326 | */ |
| 327 | public static function escaped_post_data($post_data) |
| 328 | { |
| 329 | $escaped_post_data = array(); |
| 330 | |
| 331 | foreach ($post_data as $key => $value) { |
| 332 | if ($key == 'eup_submit') { |
| 333 | continue; |
| 334 | } |
| 335 | |
| 336 | if ('eup_bio' == $key) { |
| 337 | $escaped_post_data[$key] = wp_kses_post($value); |
| 338 | } elseif (is_array($value)) { |
| 339 | $escaped_post_data[$key] = array_map('sanitize_text_field', $value); |
| 340 | } else { |
| 341 | $escaped_post_data[$key] = sanitize_textarea_field($value); |
| 342 | } |
| 343 | } |
| 344 | |
| 345 | return $escaped_post_data; |
| 346 | } |
| 347 | |
| 348 | /** |
| 349 | * @param $post_data array escaped $_POST Data @see self::escaped_post_data |
| 350 | * |
| 351 | * @param $valid_userdata array userdata valid for wp_update_user |
| 352 | * |
| 353 | * @return array |
| 354 | */ |
| 355 | public static function custom_usermeta_data($post_data, $valid_userdata) |
| 356 | { |
| 357 | $custom_usermeta = array(); |
| 358 | |
| 359 | $valid_custom_usermeta = array_keys(ppress_custom_fields_key_value_pair(true)); |
| 360 | |
| 361 | foreach ($post_data as $key => $value) { |
| 362 | |
| 363 | if ($key == 'eup_submit' || in_array($key, ppress_reserved_field_keys()) || ! in_array($key, $valid_custom_usermeta)) continue; |
| 364 | |
| 365 | if ( ! in_array($key, $valid_userdata)) { |
| 366 | $custom_usermeta[$key] = $value; |
| 367 | } |
| 368 | } |
| 369 | |
| 370 | return $custom_usermeta; |
| 371 | } |
| 372 | |
| 373 | /** |
| 374 | * Remove user avatar and redirect. Triggered when JS is disabled. |
| 375 | */ |
| 376 | public static function remove_user_avatar() |
| 377 | { |
| 378 | self::remove_avatar_core(); |
| 379 | |
| 380 | wp_safe_redirect(esc_url_raw(add_query_arg('edit', 'true'))); |
| 381 | exit; |
| 382 | } |
| 383 | |
| 384 | /** |
| 385 | * Remove user cover photo and redirect. Triggered when JS is disabled. |
| 386 | */ |
| 387 | public static function remove_user_cover_image() |
| 388 | { |
| 389 | self::remove_cover_image(); |
| 390 | wp_safe_redirect(esc_url_raw(add_query_arg('edit', 'true'))); |
| 391 | exit; |
| 392 | } |
| 393 | |
| 394 | /** |
| 395 | * Core function that removes/delete the user's avatar |
| 396 | */ |
| 397 | public static function remove_avatar_core() |
| 398 | { |
| 399 | $avatar_slug = get_user_meta(self::get_current_user_id(), 'pp_profile_avatar', true); |
| 400 | |
| 401 | do_action('ppress_before_avatar_removal', $avatar_slug); |
| 402 | |
| 403 | unlink(PPRESS_AVATAR_UPLOAD_DIR . $avatar_slug); |
| 404 | |
| 405 | $user_id = self::get_current_user_id(); |
| 406 | |
| 407 | // delete the record from DB |
| 408 | delete_user_meta($user_id, 'pp_profile_avatar'); |
| 409 | |
| 410 | /** WP User Avatar Adapter STARTS */ |
| 411 | self::delete_deprecated_wp_user_avatar_image(); |
| 412 | /** WP User Avatar Adapter ENDS */ |
| 413 | |
| 414 | do_action('ppress_after_avatar_removal'); |
| 415 | } |
| 416 | |
| 417 | private static function delete_deprecated_wp_user_avatar_image() |
| 418 | { |
| 419 | /** WP User Avatar Adapter STARTS */ |
| 420 | global $wpdb, $blog_id, $post, $wp_user_avatar; |
| 421 | |
| 422 | $user_id = self::get_current_user_id(); |
| 423 | |
| 424 | if ( ! $wp_user_avatar->wpua_is_author_or_above()) { |
| 425 | // Delete other uploads by user |
| 426 | $q = array( |
| 427 | 'author' => $user_id, |
| 428 | 'post_type' => 'attachment', |
| 429 | 'post_status' => 'inherit', |
| 430 | 'posts_per_page' => '-1', |
| 431 | 'meta_query' => array( |
| 432 | array( |
| 433 | 'key' => '_wp_attachment_wp_user_avatar', |
| 434 | 'value' => "", |
| 435 | 'compare' => '!=' |
| 436 | ) |
| 437 | ) |
| 438 | ); |
| 439 | $avatars_wp_query = new \WP_Query($q); |
| 440 | while ($avatars_wp_query->have_posts()) : $avatars_wp_query->the_post(); |
| 441 | wp_delete_attachment($post->ID); |
| 442 | endwhile; |
| 443 | } |
| 444 | |
| 445 | delete_metadata('post', null, '_wp_attachment_wp_user_avatar', $user_id, true); |
| 446 | delete_user_meta($user_id, $wpdb->get_blog_prefix($blog_id) . 'user_avatar'); |
| 447 | /** WP User Avatar Adapter ENDS */ |
| 448 | } |
| 449 | |
| 450 | /** |
| 451 | * Core function that removes/delete the user's cover photo |
| 452 | * |
| 453 | * @param int $user_id |
| 454 | */ |
| 455 | public static function remove_cover_image($user_id = 0) |
| 456 | { |
| 457 | $user_id = is_int($user_id) && $user_id > 0 ? $user_id : self::get_current_user_id(); |
| 458 | |
| 459 | $slug = get_user_meta($user_id, 'pp_profile_cover_image', true); |
| 460 | |
| 461 | do_action('ppress_before_cover_image_removal', $slug); |
| 462 | |
| 463 | unlink(PPRESS_COVER_IMAGE_UPLOAD_DIR . $slug); |
| 464 | |
| 465 | // delete the record from DB |
| 466 | delete_user_meta($user_id, 'pp_profile_cover_image'); |
| 467 | |
| 468 | do_action('ppress_after_cover_image_removal'); |
| 469 | } |
| 470 | } |