Installer
3 years ago
AdminNotices.php
2 months 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
4 hours 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
RegistrationAuth.php
460 lines
| 1 | <?php |
| 2 | |
| 3 | namespace ProfilePress\Core\Classes; |
| 4 | |
| 5 | use ProfilePress\Libsodium\UserModeration\UserModeration; |
| 6 | use ProfilePress\Libsodium\UserModeration\UserModerationNotification; |
| 7 | use WP_Error; |
| 8 | |
| 9 | class RegistrationAuth |
| 10 | { |
| 11 | /** |
| 12 | * Wrapper function for call to the welcome email class |
| 13 | * |
| 14 | * @param int $user_id |
| 15 | * @param string $password |
| 16 | * @param string $form_id |
| 17 | */ |
| 18 | public static function send_welcome_email($user_id, $password = '', $form_id = '') |
| 19 | { |
| 20 | $status = apply_filters('ppress_activate_send_welcome_email', ppress_get_setting('welcome_message_email_enabled', 'on'), $user_id, $form_id); |
| 21 | |
| 22 | if ($status == 'on') { |
| 23 | |
| 24 | do_action('ppress_before_send_welcome_mail', $user_id, $form_id); |
| 25 | |
| 26 | new WelcomeEmailAfterSignup($user_id, $password); |
| 27 | |
| 28 | do_action('ppress_after_send_welcome_mail', $user_id, $form_id); |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | /** |
| 33 | * |
| 34 | * Wrapper function for call to the automatic login after reg function |
| 35 | * |
| 36 | * @param int $user_id |
| 37 | * @param int $form_id |
| 38 | * @param string $redirect redirect url after registration |
| 39 | * |
| 40 | * @return mixed |
| 41 | */ |
| 42 | public static function auto_login_after_reg($user_id, $form_id, $redirect) |
| 43 | { |
| 44 | if (!empty($redirect)) { |
| 45 | return Autologin::initialize($user_id, $form_id, $redirect); |
| 46 | } |
| 47 | |
| 48 | $auto_login_option = apply_filters('ppress_activate_auto_login_after_signup', ppress_get_setting('set_auto_login_after_reg', ''), $form_id, $user_id); |
| 49 | |
| 50 | if ($auto_login_option == 'on') { |
| 51 | return Autologin::initialize($user_id, $form_id); |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | /** |
| 56 | * Perform redirect after registration without logging the user in. |
| 57 | * |
| 58 | * @param int $form_id |
| 59 | * @param string $no_login_redirect URL to redirect to. |
| 60 | * |
| 61 | * @return array |
| 62 | */ |
| 63 | public static function no_login_redirect_after_reg($form_id, $no_login_redirect) |
| 64 | { |
| 65 | esc_url_raw($no_login_redirect); |
| 66 | |
| 67 | do_action('ppress_before_no_login_redirect_after_reg', $no_login_redirect, $form_id); |
| 68 | if (wp_doing_ajax()) { |
| 69 | // we are returning array to uniquely identify redirect. |
| 70 | return [$no_login_redirect]; |
| 71 | } |
| 72 | |
| 73 | nocache_headers(); |
| 74 | |
| 75 | wp_safe_redirect($no_login_redirect); |
| 76 | exit; |
| 77 | } |
| 78 | |
| 79 | /** |
| 80 | * Register new users |
| 81 | * |
| 82 | * @param array $post user form submitted data |
| 83 | * @param int $form_id Registration builder ID |
| 84 | * @param string $redirect URL to redirect to after registration. |
| 85 | * |
| 86 | * @param bool $is_melange |
| 87 | * @param string $no_login_redirect |
| 88 | * |
| 89 | * @return string|mixed|void |
| 90 | */ |
| 91 | public static function register_new_user($post, $form_id = 0, $redirect = '', $is_melange = false, $no_login_redirect = '') |
| 92 | { |
| 93 | if (!get_option('users_can_register')) return; |
| 94 | |
| 95 | $files = $_FILES; |
| 96 | |
| 97 | // create an array of acceptable userdata for use by wp_insert_user |
| 98 | $valid_userdata = array( |
| 99 | 'reg_username', |
| 100 | 'reg_password', |
| 101 | 'reg_password2', |
| 102 | 'reg_email2', |
| 103 | 'reg_password_present', |
| 104 | 'reg_email', |
| 105 | 'reg_website', |
| 106 | 'reg_nickname', |
| 107 | 'reg_display_name', |
| 108 | 'reg_first_name', |
| 109 | 'reg_last_name', |
| 110 | 'reg_bio', |
| 111 | 'reg_select_role', |
| 112 | ); |
| 113 | |
| 114 | // get the data for userdata |
| 115 | $segregated_userdata = array(); |
| 116 | |
| 117 | // loop over the $_POST data and create an array of the wp_insert_user userdata |
| 118 | foreach ($post as $key => $value) { |
| 119 | if ($key == 'reg_submit') { |
| 120 | continue; |
| 121 | } |
| 122 | |
| 123 | if (in_array($key, $valid_userdata)) { |
| 124 | |
| 125 | if (in_array($key, ['reg_email', 'reg_email2'])) { |
| 126 | $segregated_userdata[$key] = sanitize_email($value); |
| 127 | continue; |
| 128 | } |
| 129 | |
| 130 | // sanitize_textarea_field is used to preserve any line breaks |
| 131 | $segregated_userdata[$key] = strip_shortcodes(sanitize_textarea_field($value)); |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | $email = $segregated_userdata['reg_email'] ?? ''; |
| 136 | |
| 137 | $email2 = $segregated_userdata['reg_email2'] ?? null; |
| 138 | |
| 139 | // get convert the form post data to userdata for use by wp_insert_users |
| 140 | $username = $segregated_userdata['reg_username'] ?? ''; |
| 141 | |
| 142 | // Handle username creation when username requirement is disabled. |
| 143 | if (ppress_is_signup_form_username_disabled($form_id, $is_melange)) { |
| 144 | $username = sanitize_user(current(explode('@', $email)), true); |
| 145 | // Ensure username is unique. |
| 146 | $append = 1; |
| 147 | $o_username = $username; |
| 148 | while (username_exists($username)) { |
| 149 | $username = $o_username . $append; |
| 150 | $append++; |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | $username = apply_filters('ppress_registration_username_value', $username, $form_id); |
| 155 | |
| 156 | $password = apply_filters('ppress_registration_password_value', $segregated_userdata['reg_password'] ?? '', $form_id); |
| 157 | |
| 158 | $flag_to_send_password_reset = false; |
| 159 | |
| 160 | // if the reg_password field isn't present in registration, generate a password for the user and set a flag to send a password reset message |
| 161 | if (empty($password) && (empty($segregated_userdata['reg_password_present']) || $segregated_userdata['reg_password_present'] != 'true')) { |
| 162 | $password = wp_generate_password(24); |
| 163 | $flag_to_send_password_reset = apply_filters('ppress_enable_auto_send_password_reset_flag', true, $form_id); |
| 164 | } |
| 165 | |
| 166 | $password2 = $segregated_userdata['reg_password2'] ?? null; |
| 167 | $website = $segregated_userdata['reg_website'] ?? ''; |
| 168 | $nickname = $segregated_userdata['reg_nickname'] ?? ''; |
| 169 | $display_name = $segregated_userdata['reg_display_name'] ?? ''; |
| 170 | $first_name = $segregated_userdata['reg_first_name'] ?? ''; |
| 171 | $last_name = $segregated_userdata['reg_last_name'] ?? ''; |
| 172 | $bio = $segregated_userdata['reg_bio'] ?? ''; |
| 173 | $role = $segregated_userdata['reg_select_role'] ?? ''; |
| 174 | |
| 175 | // real uer data |
| 176 | $real_userdata = array( |
| 177 | 'user_login' => $username, |
| 178 | 'user_pass' => $password, |
| 179 | 'user_email' => apply_filters('ppress_registration_email_value', $email, $form_id), |
| 180 | 'user_url' => apply_filters('ppress_registration_website_value', $website, $form_id), |
| 181 | 'nickname' => apply_filters('ppress_registration_nickname_value', $nickname, $form_id), |
| 182 | 'display_name' => apply_filters('ppress_registration_display_name_value', $display_name, $form_id), |
| 183 | 'first_name' => apply_filters('ppress_registration_first_name_value', $first_name, $form_id), |
| 184 | 'last_name' => apply_filters('ppress_registration_last_name_value', $last_name, $form_id), |
| 185 | 'description' => apply_filters('ppress_registration_bio_value', $bio, $form_id), |
| 186 | ); |
| 187 | |
| 188 | if (!empty($role)) { |
| 189 | // acceptable defined roles in reg-select-role shortcode. |
| 190 | $accepted_role = (array)self::acceptable_defined_roles($form_id); |
| 191 | |
| 192 | if ($role != 'administrator' && in_array($role, $accepted_role)) { |
| 193 | $real_userdata['role'] = $role; |
| 194 | } |
| 195 | } else { |
| 196 | |
| 197 | $builder_role = FormRepository::get_form_meta($form_id, FormRepository::REGISTRATION_TYPE, FormRepository::REGISTRATION_USER_ROLE); |
| 198 | |
| 199 | if (!empty($builder_role)) { |
| 200 | // only set user role if the registration form has one set |
| 201 | // otherwise no role is set for the user thus wp_insert_user will use the default user role set in Settings > General |
| 202 | $real_userdata['role'] = $builder_role; |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | /* start filter Hook */ |
| 207 | $reg_errors = new WP_Error(); |
| 208 | |
| 209 | // --------START --------- validation for required fields ----------------------// |
| 210 | // loop through required fields and throw error if any is empty |
| 211 | if (!empty($_POST['required-fields']) && is_array($_POST['required-fields'])) { |
| 212 | foreach ($_POST['required-fields'] as $key => $value) { |
| 213 | |
| 214 | // ppressPOST_var($key) === 'false' for checkbox field because if unchecked, default value is "false". |
| 215 | if ((empty($_POST[$key]) || ppressPOST_var($key) === 'false') && empty($_FILES[$key])) { |
| 216 | $reg_errors->add('required_field_empty', sprintf(__('%s field is required', 'wp-user-avatar'), sanitize_text_field($value))); |
| 217 | // stop looping if a required field is found empty. |
| 218 | break; |
| 219 | } |
| 220 | } |
| 221 | } |
| 222 | // --------END --------- validation for required fields ----------------------// |
| 223 | |
| 224 | if (!validate_username($username)) { |
| 225 | $reg_errors->add('invalid_username', esc_html__('<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.', 'wp-user-avatar')); |
| 226 | } |
| 227 | |
| 228 | if (!is_email($real_userdata['user_email'])) { |
| 229 | $reg_errors->add('invalid_email', esc_html__('Email address is not valid', 'wp-user-avatar')); |
| 230 | } |
| 231 | |
| 232 | if (isset($password2) && ($password != $password2)) { |
| 233 | $reg_errors->add('password_mismatch', esc_html__('Passwords do not match', 'wp-user-avatar')); |
| 234 | } |
| 235 | |
| 236 | if (isset($email2) && ($email != $email2)) { |
| 237 | $reg_errors->add('email_mismatch', esc_html__('Email addresses do not match', 'wp-user-avatar')); |
| 238 | } |
| 239 | |
| 240 | if (isset($post['pp_enforce_password_meter']) && ($post['pp_enforce_password_meter'] != '1')) { |
| 241 | $reg_errors->add('password_weak', esc_html__('Password is not strong', 'wp-user-avatar')); |
| 242 | } |
| 243 | |
| 244 | // get the data for use by update_meta |
| 245 | $custom_usermeta = array(); |
| 246 | |
| 247 | if (ExtensionManager::is_premium()) { |
| 248 | // loop over the $_POST data and create an array of the invalid userdata/ custom usermeta |
| 249 | foreach ($post as $key => $value) { |
| 250 | |
| 251 | if ($key == 'reg_submit' || in_array($key, ppress_reserved_field_keys())) continue; |
| 252 | |
| 253 | if (!in_array($key, $valid_userdata)) { |
| 254 | |
| 255 | if (in_array($key, array_keys(ppress_custom_fields_key_value_pair(true)))) { |
| 256 | $custom_usermeta[$key] = is_array($value) ? array_map('sanitize_textarea_field', $value) : sanitize_textarea_field($value); |
| 257 | } |
| 258 | } |
| 259 | } |
| 260 | } |
| 261 | |
| 262 | // merge real data(for use by wp_insert_user()) and custom fields data |
| 263 | // $real_userdata comes second so custom user meta won't override it. |
| 264 | $user_data = array_merge($custom_usermeta, $real_userdata); |
| 265 | |
| 266 | /* Begin Filter Hook */ |
| 267 | // call validate reg from function |
| 268 | $reg_form_errors = apply_filters('ppress_registration_validation', $reg_errors, $form_id, $user_data, $is_melange); |
| 269 | if (is_wp_error($reg_form_errors) && $reg_form_errors->get_error_code() != '') { |
| 270 | return '<div class="profilepress-reg-status">' . $reg_form_errors->get_error_message() . '</div>'; |
| 271 | } |
| 272 | /* End Filter Hook */ |
| 273 | |
| 274 | // --------START --------- validation for file upload ----------------------// |
| 275 | $uploads = FileUploader::init(); |
| 276 | $upload_errors = ''; |
| 277 | if (!empty($uploads)) { |
| 278 | foreach ($uploads as $field_key => $uploaded_filename_or_wp_error) { |
| 279 | if (is_wp_error($uploaded_filename_or_wp_error)) { |
| 280 | $upload_errors .= $uploaded_filename_or_wp_error->get_error_message() . '<br/>'; |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | if (!empty($upload_errors)) { |
| 285 | return "<div class='profilepress-reg-status'>$upload_errors</div>"; |
| 286 | } |
| 287 | } |
| 288 | // --------END --------- validation for file upload ----------------------// |
| 289 | |
| 290 | |
| 291 | // --------START --------- validation for avatar upload ----------------------// |
| 292 | if (!empty($files['reg_avatar']['name'])) { |
| 293 | $upload_avatar = ImageUploader::process($files['reg_avatar']); |
| 294 | |
| 295 | if (is_wp_error($upload_avatar)) { |
| 296 | return "<div class='profilepress-reg-status'>" . $upload_avatar->get_error_message() . "</div>"; |
| 297 | } |
| 298 | } |
| 299 | // --------END --------- validation for avatar upload ----------------------// |
| 300 | |
| 301 | |
| 302 | // --------START --------- validation for cover photo upload ----------------------// |
| 303 | if (!empty($files['reg_cover_image']['name'])) { |
| 304 | |
| 305 | $upload_cover_image = ImageUploader::process($files['reg_cover_image'], ImageUploader::COVER_IMAGE, PPRESS_COVER_IMAGE_UPLOAD_DIR); |
| 306 | |
| 307 | if (is_wp_error($upload_cover_image)) { |
| 308 | return "<div class='profilepress-reg-status'>" . $upload_cover_image->get_error_message() . "</div>"; |
| 309 | } |
| 310 | } |
| 311 | // --------END --------- validation for cover photo upload ----------------------// |
| 312 | |
| 313 | do_action('ppress_before_registration', $form_id, $user_data); |
| 314 | |
| 315 | // proceed to registration using wp_insert_user method which return the new user id |
| 316 | $user_id = wp_insert_user(apply_filters('ppress_registration_real_userdata', $real_userdata, $form_id, $post)); |
| 317 | |
| 318 | if (is_wp_error($user_id)) { |
| 319 | return '<div class="profilepress-reg-status">' . $user_id->get_error_message() . '</div>'; |
| 320 | } |
| 321 | |
| 322 | // --------START --------- register custom field ----------------------// |
| 323 | |
| 324 | $custom_usermeta['pp_profile_avatar'] = $upload_avatar ?? null; |
| 325 | $custom_usermeta['pp_profile_cover_image'] = $upload_cover_image ?? null; |
| 326 | |
| 327 | // if we get to this point, it means the files pass validation defined above. |
| 328 | // array of files uploaded. Array key is the "custom field key" and the filename as the array value. |
| 329 | $custom_usermeta['pp_uploaded_files'] = $uploads; |
| 330 | |
| 331 | $custom_usermeta = apply_filters('ppress_registration_custom_usermeta', $custom_usermeta, $user_id, $form_id, $post); |
| 332 | |
| 333 | // if $user_id is no WP_Error, add the extra user profile field |
| 334 | if (is_array($custom_usermeta)) { |
| 335 | |
| 336 | foreach ($custom_usermeta as $key => $value) { |
| 337 | |
| 338 | if (!empty($value)) { |
| 339 | |
| 340 | update_user_meta($user_id, $key, $value); |
| 341 | // the 'edit_profile' parameter is used to distinguish it from same action hook in RegistrationAuth |
| 342 | do_action('ppress_after_custom_field_update', $key, $value, $user_id, 'registration'); |
| 343 | } |
| 344 | } |
| 345 | } |
| 346 | // --------END --------- register custom field ----------------------// |
| 347 | |
| 348 | if ($flag_to_send_password_reset === true) { |
| 349 | PasswordReset::retrieve_password_func($username); |
| 350 | } |
| 351 | |
| 352 | // record signup via |
| 353 | if ($is_melange) { |
| 354 | add_user_meta($user_id, '_pp_signup_melange_via', $form_id); |
| 355 | } else { |
| 356 | add_user_meta($user_id, '_pp_signup_via', $form_id); |
| 357 | } |
| 358 | |
| 359 | $should_send_welcome_email = true; |
| 360 | |
| 361 | // if moderation is active, set new registered users as pending |
| 362 | if (class_exists('ProfilePress\Libsodium\UserModeration\UserModeration') && UserModeration::moderation_is_active()) { |
| 363 | |
| 364 | if (apply_filters('ppress_user_moderation_make_pending', true, $form_id, $user_data)) { |
| 365 | |
| 366 | $should_send_welcome_email = false; |
| 367 | |
| 368 | UserModeration::make_pending($user_id); |
| 369 | UserModerationNotification::pending($user_id); |
| 370 | UserModerationNotification::pending_admin_notification($user_id); |
| 371 | } |
| 372 | } |
| 373 | |
| 374 | if (apply_filters('ppress_registration_should_send_welcome_email', $should_send_welcome_email, $user_id, $user_data)) { |
| 375 | self::send_welcome_email($user_id, $password, $form_id); |
| 376 | } |
| 377 | |
| 378 | if (is_int($user_id)) { |
| 379 | ppress_wp_new_user_notification($user_id, null, 'admin'); |
| 380 | } |
| 381 | |
| 382 | /** |
| 383 | * Fires after a user registration is completed. |
| 384 | * |
| 385 | * @param int $form_id ID of the registration form. |
| 386 | * @param mixed $user_data array of registered user info. |
| 387 | * @param int $user_id ID of the registered user. |
| 388 | * @param bool $is_melange |
| 389 | */ |
| 390 | do_action('ppress_after_registration', $form_id, $user_data, $user_id, $is_melange); |
| 391 | /* End Action Hook */ |
| 392 | |
| 393 | if (!empty($no_login_redirect)) { |
| 394 | $response = self::no_login_redirect_after_reg($form_id, $no_login_redirect); |
| 395 | } else { |
| 396 | /** |
| 397 | * call auto-login |
| 398 | * |
| 399 | * @param int $user_id registered user ID |
| 400 | * @param int $form_id registration form ID |
| 401 | * @param string $redirect redirect url after login |
| 402 | */ |
| 403 | $response = self::auto_login_after_reg($user_id, $form_id, $redirect); |
| 404 | } |
| 405 | |
| 406 | if (wp_doing_ajax() && isset($response) && !empty($response) && is_array($response)) { |
| 407 | // $response should be an array containing the url to redirect to. |
| 408 | return $response; |
| 409 | } |
| 410 | |
| 411 | $success_message = FormRepository::get_form_meta($form_id, FormRepository::REGISTRATION_TYPE, FormRepository::SUCCESS_MESSAGE); |
| 412 | if ($is_melange) { |
| 413 | $success_message = FormRepository::get_form_meta($form_id, FormRepository::MELANGE_TYPE, FormRepository::MELANGE_REGISTRATION_SUCCESS_MESSAGE); |
| 414 | } |
| 415 | |
| 416 | $default_success_message = '<div class="profilepress-reg-status success">' . esc_html__('Registration successful.', 'wp-user-avatar') . '</div>'; |
| 417 | |
| 418 | if (FormRepository::is_drag_drop($form_id, FormRepository::REGISTRATION_TYPE)) { |
| 419 | // Drag and drop signup pages do not allow the use of div wrapper. only the message to be shown is entered. |
| 420 | // so here, we are wrapping it in reg status div. |
| 421 | if (!empty($success_message)) { |
| 422 | $success_message = '<div class="profilepress-reg-status success">' . $success_message . '</div>'; |
| 423 | } |
| 424 | } |
| 425 | |
| 426 | return apply_filters('ppress_registration_success_message', !empty($success_message) ? wp_kses_post($success_message) : $default_success_message, $user_id, $form_id, $user_data); |
| 427 | } |
| 428 | |
| 429 | /** |
| 430 | * Array list of acceptable defined roles. |
| 431 | * |
| 432 | * @param int $form_id ID of registration form |
| 433 | * |
| 434 | * @return array |
| 435 | */ |
| 436 | public static function acceptable_defined_roles($form_id) |
| 437 | { |
| 438 | if (FormRepository::is_drag_drop($form_id, FormRepository::REGISTRATION_TYPE)) { |
| 439 | $settings = FormRepository::form_builder_fields_settings($form_id, FormRepository::REGISTRATION_TYPE); |
| 440 | $found_field = wp_list_filter($settings, ['fieldType' => 'reg-select-role']); |
| 441 | if (empty($found_field)) return []; |
| 442 | $reg_select_field_options = array_values(wp_list_pluck($found_field, 'options')); |
| 443 | $options = $reg_select_field_options[0] ?? []; |
| 444 | } else { |
| 445 | $registration_structure = FormRepository::get_form_meta($form_id, FormRepository::REGISTRATION_TYPE, FormRepository::FORM_STRUCTURE); |
| 446 | preg_match('/\[reg-select-role.*\]/', $registration_structure, $matches); |
| 447 | if (empty($matches[0])) return []; |
| 448 | $options = []; |
| 449 | if (strpos($matches[0], 'options') !== false) { |
| 450 | preg_match('/options=["\']([,\s\w-]+)["\']/', $matches[0], $matches2); |
| 451 | if (empty($matches2[1])) return []; |
| 452 | $options = $matches2[1]; |
| 453 | } |
| 454 | } |
| 455 | |
| 456 | $acceptable_user_role = empty($options) ? array_keys(ppress_get_editable_roles()) : array_map('trim', explode(',', $options)); |
| 457 | |
| 458 | return apply_filters('ppress_acceptable_user_role', $acceptable_user_role, $form_id); |
| 459 | } |
| 460 | } |