From 7fafa3a4b33cdba622a555f4e57a9d0f46299a23 Mon Sep 17 00:00:00 2001 From: Mykyta Synelnikov Date: Fri, 30 Jun 2023 21:55:59 +0300 Subject: [PATCH] - fix for registration form; --- includes/core/class-form.php | 59 ++++- includes/core/class-gdpr.php | 72 ++--- includes/core/class-login.php | 1 + includes/core/class-register.php | 72 ++--- includes/core/class-user.php | 142 ++++------ includes/core/class-validation.php | 13 +- includes/core/um-actions-account.php | 1 + includes/core/um-actions-profile.php | 49 ++-- includes/core/um-actions-register.php | 367 +++++++++++++------------- 9 files changed, 373 insertions(+), 403 deletions(-) diff --git a/includes/core/class-form.php b/includes/core/class-form.php index 7a55db89..41fe3550 100644 --- a/includes/core/class-form.php +++ b/includes/core/class-form.php @@ -62,7 +62,7 @@ if ( ! class_exists( 'um\core\Form' ) ) { * * @var array */ - private $usermeta_whitelist = array(); + public $usermeta_whitelist = array(); /** * Form constructor. @@ -393,7 +393,7 @@ if ( ! class_exists( 'um\core\Form' ) ) { */ public function clean_submitted_data( $submitted ) { foreach ( $submitted as $metakey => $value ) { - if ( UM()->user()->is_metakey_banned( $metakey ) ) { + if ( UM()->user()->is_metakey_banned( $metakey/*, 'submission'*/ ) ) { unset( $submitted[ $metakey ] ); } } @@ -442,11 +442,19 @@ if ( ! class_exists( 'um\core\Form' ) ) { return; } + $ignore_keys = array(); + $field_types_without_metakey = UM()->builtin()->get_fields_without_metakey(); foreach ( $custom_fields as $cf_k => $cf_data ) { if ( ! array_key_exists( 'type', $cf_data ) || in_array( $cf_data['type'], $field_types_without_metakey, true ) ) { unset( $custom_fields[ $cf_k ] ); } + + if ( ! array_key_exists( 'type', $cf_data ) || 'password' === $cf_data['type'] ) { + $ignore_keys[] = $cf_k; + $ignore_keys[] = 'confirm_' . $cf_k; + } + if ( ! array_key_exists( 'metakey', $cf_data ) || empty( $cf_data['metakey'] ) ) { unset( $custom_fields[ $cf_k ] ); } @@ -455,18 +463,46 @@ if ( ! class_exists( 'um\core\Form' ) ) { $all_cf_metakeys = $cf_metakeys; // The '_um_last_login' cannot be updated through UM form. - $cf_metakeys = array_values( array_diff( $cf_metakeys, array( 'role_select', 'role_radio', 'role', '_um_last_login' ) ) ); - // Column names from wp_users table. - $cf_metakeys = array_values( array_diff( $cf_metakeys, UM()->user()->update_user_keys ) ); + $cf_metakeys = array_values( array_diff( $cf_metakeys, array( 'role_select', 'role_radio', 'role', '_um_last_login', 'user_pass', 'user_password', 'confirm_user_password' ) ) ); + if ( ! empty( $ignore_keys ) ) { + $cf_metakeys = array_values( array_diff( $cf_metakeys, $ignore_keys ) ); + } // Remove restricted fields when edit profile. if ( 'profile' === $this->form_data['mode'] ) { + // Column names from wp_users table. + $cf_metakeys = array_values( array_diff( $cf_metakeys, array( 'user_login' ) ) ); + // Hidden for edit fields $cf_metakeys = array_values( array_diff( $cf_metakeys, UM()->fields()->get_restricted_fields_for_edit() ) ); } // Add required usermeta for register. if ( 'register' === $this->form_data['mode'] ) { - $cf_metakeys[] = 'submitted'; + $cf_metakeys[] = 'form_id'; + $cf_metakeys[] = 'timestamp'; } + /** + * Filters whitelisted usermeta keys that can be stored inside DB after UM Form submission. + * + * @param {array} $whitelisted_metakeys Whitelisted usermeta keys. + * @param {array} $form_data UM form data. + * + * @return {array} Whitelisted usermeta keys. + * + * @since 2.6.7 + * @hook um_whitelisted_metakeys + * + * @example Extends whitelisted usermeta keys. + * function my_um_whitelisted_metakeys( $metakeys, $form_data ) { + * $metakeys[] = 'some_key'; + * return $metakeys; + * } + * add_filter( 'um_whitelisted_metakeys', 'my_um_whitelisted_metakeys', 10, 2 ); + */ + $cf_metakeys = apply_filters( 'um_whitelisted_metakeys', $cf_metakeys, $this->form_data ); + + // Important variable to prevent save unnecessary data to wp_usermeta. + $this->usermeta_whitelist = $cf_metakeys; + /** * Fires before UM login, registration or profile form submission. * @@ -558,7 +594,7 @@ if ( ! class_exists( 'um\core\Form' ) ) { } // @todo REMOVE THAT !!! AND SEPARATE FORM DATA AND SUBMISSION DATA. MAY AFFECT TO EXTENSIONS - $this->post_form = array_merge( $this->form_data, $this->post_form ); + //$this->post_form = array_merge( $this->form_data, $this->post_form ); // Remove role from post_form at first if role ! empty and there aren't custom fields with role name // if ( ! empty( $this->post_form['role'] ) ) { @@ -660,7 +696,7 @@ if ( ! class_exists( 'um\core\Form' ) ) { * add_action( 'um_submit_form_errors_hook', 'my_custom_submit_form_errors_hook', 10, 2 ); */ do_action( 'um_submit_form_errors_hook', $this->post_form, $this->form_data ); - if ( 'login' !== $this->form_data['mode'] ) { + if ( 'profile' === $this->form_data['mode'] ) { var_dump( $this->post_form ); var_dump( $this->form_data ); var_dump( '------------------------------------------------------------' ); @@ -678,7 +714,12 @@ if ( ! class_exists( 'um\core\Form' ) ) { * * 1 - `UM()->login()->verify_nonce()` Verify nonce. * * 10 - `um_submit_form_login()` Login form main handler. * ### um_submit_form_register: + * * 1 - `UM()->register()->verify_nonce()` Verify nonce. + * * 9 - `UM()->agreement_validation()` GDPR Agreement. + * * 9 - `UM()->terms_conditions()->agreement_validation()` Terms & Conditions Agreement. + * * 10 - `um_submit_form_register()` Register form main handler. * ### um_submit_form_profile: + * * 10 - `um_submit_form_profile()` Profile form main handler. * * @since 1.3.x * @hook um_submit_form_errors_hook @@ -692,7 +733,7 @@ if ( ! class_exists( 'um\core\Form' ) ) { * } * add_action( 'um_submit_form_errors_hook', 'my_custom_submit_form_errors_hook', 10, 2 ); */ - do_action( "um_submit_form_{$this->post_form['mode']}", $this->post_form, $this->form_data ); + do_action( "um_submit_form_{$this->form_data['mode']}", $this->post_form, $this->form_data ); } } diff --git a/includes/core/class-gdpr.php b/includes/core/class-gdpr.php index 28be93ca..21397af4 100644 --- a/includes/core/class-gdpr.php +++ b/includes/core/class-gdpr.php @@ -1,71 +1,78 @@ form()->add_error( 'use_gdpr_agreement', isset( $args['use_gdpr_error_text'] ) ? $args['use_gdpr_error_text'] : '' ); + if ( $gdpr_enabled && ! isset( $submitted_data['submitted']['use_gdpr_agreement'] ) ) { + UM()->form()->add_error( 'use_gdpr_agreement', $use_gdpr_error_text ); } } + /** + * @param array $metakeys + * @param array $form_data + */ + public function extend_whitelisted( $metakeys, $form_data ) { + $gdpr_enabled = get_post_meta( $form_data['form_id'], '_um_register_use_gdpr', true ); + if ( ! empty( $gdpr_enabled ) ) { + $metakeys[] = 'use_gdpr_agreement'; + } + return $metakeys; + } /** * @param $submitted - * @param $args * * @return mixed */ - function add_agreement_date( $submitted, $args ) { + public function add_agreement_date( $submitted ) { if ( isset( $submitted['use_gdpr_agreement'] ) ) { $submitted['use_gdpr_agreement'] = time(); } @@ -73,21 +80,18 @@ if ( ! class_exists( 'um\core\GDPR' ) ) { return $submitted; } - /** * @param $submitted * * @return mixed */ - function email_registration_data( $submitted ) { + public function email_registration_data( $submitted ) { if ( ! empty( $submitted['use_gdpr_agreement'] ) ) { - $submitted['GDPR Applied'] = date( "d M Y H:i", $submitted['use_gdpr_agreement'] ); + $submitted['GDPR Applied'] = wp_date( get_option( 'date_format', 'Y-m-d' ) . ' ' . get_option( 'time_format', 'H:i:s' ), $submitted['use_gdpr_agreement'] ); unset( $submitted['use_gdpr_agreement'] ); } return $submitted; } - } - -} \ No newline at end of file +} diff --git a/includes/core/class-login.php b/includes/core/class-login.php index 115afbee..10e857f7 100644 --- a/includes/core/class-login.php +++ b/includes/core/class-login.php @@ -61,6 +61,7 @@ if ( ! class_exists( 'um\core\Login' ) ) { } if ( empty( $args['_wpnonce'] ) || ! wp_verify_nonce( $args['_wpnonce'], 'um_login_form' ) ) { + // @todo add hookdocs $url = apply_filters( 'um_login_invalid_nonce_redirect_url', add_query_arg( array( 'err' => 'invalid_nonce' ) ) ); wp_safe_redirect( $url ); exit; diff --git a/includes/core/class-register.php b/includes/core/class-register.php index 4e42938c..833c2b28 100644 --- a/includes/core/class-register.php +++ b/includes/core/class-register.php @@ -1,29 +1,26 @@ - * @example - * + * @param {bool} $allow_nonce Is allowed verify nonce on register. By default, allowed = `true`. + * @param {array} $form_data Form's metakeys. Since 2.6.7. + * + * @return {bool} Is allowed verify. + * + * @since 2.0 + * @hook um_register_allow_nonce_verification + * + * @example Disable verifying nonce on the register page. + * add_filter( 'um_login_allow_nonce_verification', '__return_false' ); */ - $allow_nonce_verification = apply_filters( 'um_register_allow_nonce_verification', true ); - - if ( ! $allow_nonce_verification ) { - return $args; + $allow_nonce_verification = apply_filters( 'um_register_allow_nonce_verification', true, $form_data ); + if ( ! $allow_nonce_verification ) { + return; } - if ( ! wp_verify_nonce( $args['_wpnonce'], 'um_register_form' ) || empty( $args['_wpnonce'] ) || ! isset( $args['_wpnonce'] ) ) { - $url = apply_filters( 'um_register_invalid_nonce_redirect_url', add_query_arg( [ 'err' => 'invalid_nonce' ] ) ); - exit( wp_redirect( $url ) ); + if ( empty( $args['_wpnonce'] ) || ! wp_verify_nonce( $args['_wpnonce'], 'um_register_form' ) ) { + // @todo add hookdocs + $url = apply_filters( 'um_register_invalid_nonce_redirect_url', add_query_arg( array( 'err' => 'invalid_nonce' ) ) ); + wp_safe_redirect( $url ); + exit; } - - return $args; } - } -} \ No newline at end of file +} diff --git a/includes/core/class-user.php b/includes/core/class-user.php index 926433e5..28ee975e 100644 --- a/includes/core/class-user.php +++ b/includes/core/class-user.php @@ -175,7 +175,7 @@ if ( ! class_exists( 'um\core\User' ) ) { * @param string $meta_key Usermeta key. * @return bool */ - public function is_metakey_banned( $meta_key ) { + public function is_metakey_banned( $meta_key, $context = '' ) { $is_banned = false; foreach ( $this->banned_keys as $ban ) { if ( is_numeric( $meta_key ) || false !== stripos( $meta_key, $ban ) || false !== stripos( remove_accents( $meta_key ), $ban ) ) { @@ -184,6 +184,10 @@ if ( ! class_exists( 'um\core\User' ) ) { } } + if ( ! $is_banned && 'submission' === $context && ! in_array( $meta_key, UM()->form()->usermeta_whitelist, true ) ) { + $is_banned = true; + } + return $is_banned; } @@ -192,9 +196,9 @@ if ( ! class_exists( 'um\core\User' ) ) { * * @since 2.6.4 * - * @param null|bool $check Whether to allow updating metadata for the given type. - * @param int $object_id ID of the object metadata is for. - * @param string $meta_key Metadata key. + * @param null|bool $check Whether to allow updating metadata for the given type. + * @param int $object_id ID of the object metadata is for. + * @param string $meta_key Metadata key. * * @return null|bool */ @@ -203,7 +207,7 @@ if ( ! class_exists( 'um\core\User' ) ) { return $check; } - if ( $this->is_metakey_banned( $meta_key ) ) { + if ( $this->is_metakey_banned( $meta_key, 'submission' ) ) { $check = false; } @@ -854,28 +858,8 @@ if ( ! class_exists( 'um\core\User' ) ) { UM()->user()->profile['role'] = sanitize_key( $_POST['um-role'] ); UM()->user()->update_usermeta_info( 'role' ); } - - /** - * UM hook - * - * @type action - * @title um_user_register - * @description Action on user registration - * @input_vars - * [{"var":"$user_id","type":"int","desc":"User ID"}, - * {"var":"$submitted","type":"array","desc":"Registration form submitted"}] - * @change_log - * ["Since: 2.0"] - * @usage add_action( 'um_user_register', 'function_name', 10, 2 ); - * @example - * - */ - do_action( 'um_user_register', $user_id, $_POST ); + /** This action is documented in ultimate-member/includes/common/um-actions-register.php */ + do_action( 'um_user_register', $user_id, $_POST, null ); } delete_transient( 'um_count_users_unassigned' ); @@ -1363,15 +1347,14 @@ if ( ! class_exists( 'um\core\User' ) ) { } - /** * Set user's registration details * * @param array $submitted * @param array $args + * @param array $form_data */ - function set_registration_details( $submitted, $args ) { - + public function set_registration_details( $submitted, $args, $form_data ) { if ( isset( $submitted['user_pass'] ) ) { unset( $submitted['user_pass'] ); } @@ -1387,7 +1370,7 @@ if ( ! class_exists( 'um\core\User' ) ) { //remove all password field values from submitted details $password_fields = array(); foreach ( $submitted as $k => $v ) { - if ( UM()->fields()->get_field_type( $k ) == 'password' ) { + if ( 'password' === UM()->fields()->get_field_type( $k ) ) { $password_fields[] = $k; $password_fields[] = 'confirm_' . $k; } @@ -1397,81 +1380,67 @@ if ( ! class_exists( 'um\core\User' ) ) { unset( $submitted[ $pw_field ] ); } - /** - * UM hook + * Filters submitted data before save usermeta "submitted" on registration process. * - * @type filter - * @title um_before_save_filter_submitted - * @description Change submitted data before save usermeta "submitted" on registration process - * @input_vars - * [{"var":"$submitted","type":"array","desc":"Submitted data"}, - * {"var":"$args","type":"array","desc":"Form Args"}] - * @change_log - * ["Since: 2.0"] - * @usage - * - * @example - * Change submitted data before save usermeta "submitted" on registration process. + * function my_before_save_filter_submitted( $submitted, $form_submitted_data, $form_data ) { * // your code here * return $submitted; * } - * ?> + * add_filter( 'um_before_save_filter_submitted', 'my_before_save_filter_submitted', 10, 3 ); */ - $submitted = apply_filters( 'um_before_save_filter_submitted', $submitted, $args ); + $submitted = apply_filters( 'um_before_save_filter_submitted', $submitted, $args, $form_data ); /** - * UM hook + * Fires before save registration details to the user. * - * @type action - * @title um_before_save_registration_details - * @description Action on user registration before save details - * @input_vars - * [{"var":"$user_id","type":"int","desc":"User ID"}, - * {"var":"$submitted","type":"array","desc":"Registration form submitted"}] - * @change_log - * ["Since: 2.0"] - * @usage add_action( 'um_before_save_registration_details', 'function_name', 10, 2 ); - * @example - * Make any custom action before save registration details to the user. + * function my_before_save_registration_details( $user_id, $submitted_data ) { * // your code here * } - * ?> + * add_action( 'um_before_save_registration_details', 'my_before_save_registration_details', 10, 2 ); */ do_action( 'um_before_save_registration_details', $this->id, $submitted ); update_user_meta( $this->id, 'submitted', $submitted ); $this->update_profile( $submitted ); + /** - * UM hook + * Fires after save registration details to the user. * - * @type action - * @title um_after_save_registration_details - * @description Action on user registration after save details - * @input_vars - * [{"var":"$user_id","type":"int","desc":"User ID"}, - * {"var":"$submitted","type":"array","desc":"Registration form submitted"}] - * @change_log - * ["Since: 2.0"] - * @usage add_action( 'um_after_save_registration_details', 'function_name', 10, 2 ); - * @example - * Make any custom action after save registration details to the user. + * function my_after_save_registration_details( $user_id, $submitted_data, $form_data ) { * // your code here * } - * ?> + * add_action( 'um_after_save_registration_details', 'my_after_save_registration_details', 10, 3 ); */ - do_action( 'um_after_save_registration_details', $this->id, $submitted ); - + do_action( 'um_after_save_registration_details', $this->id, $submitted, $form_data ); } - /** * Set last login for new registered users */ @@ -2177,9 +2146,8 @@ if ( ! class_exists( 'um\core\User' ) ) { * add_filter( 'um_before_update_profile', 'my_custom_before_update_profile', 10, 2 ); */ $changes = apply_filters( 'um_before_update_profile', $changes, $args['ID'] ); - foreach ( $changes as $key => $value ) { - if ( $this->is_metakey_banned( $key ) ) { + if ( $this->is_metakey_banned( $key, 'submission' ) ) { continue; } @@ -2194,9 +2162,11 @@ if ( ! class_exists( 'um\core\User' ) ) { } } + $this->updating_process = false; + // update user if ( count( $args ) > 1 ) { - //if isset roles argument validate role to properly for security reasons + // If isset roles argument validate role to properly for security reasons if ( isset( $args['role'] ) ) { global $wp_roles; @@ -2208,10 +2178,8 @@ if ( ! class_exists( 'um\core\User' ) ) { wp_update_user( $args ); } - $this->updating_process = false; } - /** * User exists by meta key and value * diff --git a/includes/core/class-validation.php b/includes/core/class-validation.php index 9a5c54b2..dcef592e 100644 --- a/includes/core/class-validation.php +++ b/includes/core/class-validation.php @@ -33,7 +33,7 @@ if ( ! class_exists( 'um\core\Validation' ) ) { */ public function __construct() { add_filter( 'um_user_pre_updating_files_array', array( $this, 'validate_files' ), 10, 1 ); - add_filter( 'um_before_save_filter_submitted', array( $this, 'validate_fields_values' ), 10, 2 ); + add_filter( 'um_before_save_filter_submitted', array( $this, 'validate_fields_values' ), 10, 3 ); } @@ -56,13 +56,8 @@ if ( ! class_exists( 'um\core\Validation' ) ) { return $files; } - - - function validate_fields_values( $changes, $args ) { - $fields = array(); - if ( ! empty( $args['custom_fields'] ) ) { - $fields = unserialize( $args['custom_fields'] ); - } + public function validate_fields_values( $changes, $args, $form_data ) { + $fields = maybe_unserialize( $form_data['custom_fields'] ); foreach ( $changes as $key => $value ) { if ( ! isset( $fields[ $key ] ) ) { @@ -124,13 +119,11 @@ if ( ! class_exists( 'um\core\Validation' ) ) { $value = array_map( 'stripslashes', array_map( 'trim', $value ) ); $changes[ $key ] = array_intersect( $value, array_map( 'trim', $fields[ $key ]['options'] ) ); } - } return $changes; } - /** * Removes html from any string * diff --git a/includes/core/um-actions-account.php b/includes/core/um-actions-account.php index 44ef426d..350d44cf 100644 --- a/includes/core/um-actions-account.php +++ b/includes/core/um-actions-account.php @@ -540,6 +540,7 @@ add_action( 'um_before_account_notifications', 'um_before_account_notifications' */ function um_after_user_account_updated_permalink( $user_id, $changes ) { if ( isset( $changes['first_name'] ) || isset( $changes['last_name'] ) ) { + /** This action is documented in ultimate-member/includes/core/um-actions-register.php */ do_action( 'um_update_profile_full_name', $user_id, $changes ); } } diff --git a/includes/core/um-actions-profile.php b/includes/core/um-actions-profile.php index f2512b0b..2e5ba747 100644 --- a/includes/core/um-actions-profile.php +++ b/includes/core/um-actions-profile.php @@ -184,10 +184,11 @@ add_action( 'um_profile_content_main', 'um_profile_content_main' ); * Update user's profile * * @param array $args + * @param array $form_data */ -function um_user_edit_profile( $args ) { +function um_user_edit_profile( $args, $form_data ) { $to_update = null; - $files = array(); + $files = array(); $user_id = null; if ( isset( $args['user_id'] ) ) { @@ -225,9 +226,8 @@ function um_user_edit_profile( $args ) { */ do_action( 'um_user_before_updating_profile', $userinfo ); - if ( ! empty( $args['custom_fields'] ) ) { - $fields = apply_filters( 'um_user_edit_profile_fields', unserialize( $args['custom_fields'] ), $args ); - } + $fields = maybe_unserialize( $form_data['custom_fields'] ); + $fields = apply_filters( 'um_user_edit_profile_fields', $fields, $args, $form_data ); // loop through fields if ( ! empty( $fields ) ) { @@ -375,7 +375,6 @@ function um_user_edit_profile( $args ) { $to_update[ $description_key ] = $args['submitted'][ $description_key ]; } - // Secure selected role if ( is_admin() ) { @@ -554,26 +553,7 @@ function um_user_edit_profile( $args ) { */ do_action( 'um_user_after_updating_profile', $to_update, $user_id, $args ); - /** - * UM hook - * - * @type action - * @title um_update_profile_full_name - * @description On update user profile change full name - * @input_vars - * [{"var":"$user_id","type":"int","desc":"User ID"}, - * {"var":"$args","type":"array","desc":"Form data"}] - * @change_log - * ["Since: 2.0"] - * @usage add_action( 'um_update_profile_full_name', 'function_name', 10, 2 ); - * @example - * - */ + /** This action is documented in ultimate-member/includes/core/um-actions-register.php */ do_action( 'um_update_profile_full_name', $user_id, $to_update ); if ( ! isset( $args['is_signup'] ) ) { @@ -582,7 +562,7 @@ function um_user_edit_profile( $args ) { exit( wp_redirect( um_edit_my_profile_cancel_uri( $url ) ) ); } } -add_action( 'um_user_edit_profile', 'um_user_edit_profile', 10 ); +add_action( 'um_user_edit_profile', 'um_user_edit_profile', 10, 2 ); /** @@ -601,7 +581,7 @@ add_action( 'um_submit_form_errors_hook__profile', 'um_profile_validate_nonce', add_filter( 'um_user_pre_updating_files_array', array( UM()->validation(), 'validate_files' ), 10, 1 ); -add_filter( 'um_before_save_filter_submitted', array( UM()->validation(), 'validate_fields_values' ), 10, 2 ); +add_filter( 'um_before_save_filter_submitted', array( UM()->validation(), 'validate_fields_values' ), 10, 3 ); /** * Leave roles for User, which are not in the list of update profile (are default WP or 3rd plugins roles) @@ -1542,15 +1522,16 @@ add_action( 'um_main_profile_fields', 'um_add_profile_fields', 100 ); /** * Form processing * - * @param $args + * @param array $args + * @param array $form_data */ -function um_submit_form_profile( $args ) { +function um_submit_form_profile( $args, $form_data ) { if ( isset( UM()->form()->errors ) ) { return; } - UM()->fields()->set_mode = 'profile'; - UM()->fields()->editing = true; + UM()->fields()->set_mode = 'profile'; + UM()->fields()->editing = true; if ( ! empty( $args['submitted'] ) ) { $args['submitted'] = UM()->form()->clean_submitted_data( $args['submitted'] ); @@ -1575,9 +1556,9 @@ function um_submit_form_profile( $args ) { * } * ?> */ - do_action( 'um_user_edit_profile', $args ); + do_action( 'um_user_edit_profile', $args, $form_data ); } -add_action( 'um_submit_form_profile', 'um_submit_form_profile', 10 ); +add_action( 'um_submit_form_profile', 'um_submit_form_profile', 10, 2 ); /** diff --git a/includes/core/um-actions-register.php b/includes/core/um-actions-register.php index 9d35811e..d70f0ada 100644 --- a/includes/core/um-actions-register.php +++ b/includes/core/um-actions-register.php @@ -6,124 +6,121 @@ if ( ! defined( 'ABSPATH' ) ) { /** * Account automatically approved. * - * @param int $user_id - * @param array $args + * @param int $user_id */ -function um_post_registration_approved_hook( $user_id, $args ) { +function um_post_registration_approved_hook( $user_id ) { um_fetch_user( $user_id ); UM()->user()->approve(); } -add_action( 'um_post_registration_approved_hook', 'um_post_registration_approved_hook', 10, 2 ); +add_action( 'um_post_registration_approved_hook', 'um_post_registration_approved_hook' ); /** * Account needs email validation. * - * @param int $user_id - * @param array $args + * @param int $user_id */ -function um_post_registration_checkmail_hook( $user_id, $args ) { +function um_post_registration_checkmail_hook( $user_id ) { um_fetch_user( $user_id ); UM()->user()->email_pending(); } -add_action( 'um_post_registration_checkmail_hook', 'um_post_registration_checkmail_hook', 10, 2 ); +add_action( 'um_post_registration_checkmail_hook', 'um_post_registration_checkmail_hook' ); /** * Account needs admin review. * - * @param int $user_id - * @param array $args + * @param int $user_id */ -function um_post_registration_pending_hook( $user_id, $args ) { +function um_post_registration_pending_hook( $user_id ) { um_fetch_user( $user_id ); UM()->user()->pending(); } -add_action( 'um_post_registration_pending_hook', 'um_post_registration_pending_hook', 10, 2 ); +add_action( 'um_post_registration_pending_hook', 'um_post_registration_pending_hook' ); /** - * After insert a new user - * run at frontend and backend + * After insert a new user run at frontend and backend. * - * @param $user_id - * @param $args + * @param int|WP_Error $user_id + * @param array $args + * @param null|array $form_data It's null in case when posted from wp-admin > Add user */ -function um_after_insert_user( $user_id, $args ) { - if ( empty( $user_id ) || ( is_object( $user_id ) && is_a( $user_id, 'WP_Error' ) ) ) { +function um_after_insert_user( $user_id, $args, $form_data = null ) { + if ( empty( $user_id ) || is_wp_error( $user_id ) ) { return; } + // Set usermeta from submission. um_fetch_user( $user_id ); if ( ! empty( $args['submitted'] ) ) { - UM()->user()->set_registration_details( $args['submitted'], $args ); + // It's only frontend case. + UM()->user()->set_registration_details( $args['submitted'], $args, $form_data ); } + // Set user status. $status = um_user( 'status' ); if ( empty( $status ) ) { um_fetch_user( $user_id ); $status = um_user( 'status' ); } - - /* save user status */ UM()->user()->set_status( $status ); - /* create user uploads directory */ + // Create user uploads directory. UM()->uploader()->get_upload_user_base_dir( $user_id, true ); /** - * UM hook + * Fires after insert user to DB and there you can set any extra details. * - * @type action - * @title um_registration_set_extra_data - * @description Hook that runs after insert user to DB and there you can set any extra details - * @input_vars - * [{"var":"$user_id","type":"int","desc":"User ID"}, - * {"var":"$args","type":"array","desc":"Form data"}] - * @change_log - * ["Since: 2.0"] - * @usage add_action( 'um_registration_set_extra_data', 'function_name', 10, 2 ); - * @example - * Callback name -> Excerpt): + * 10 - `um_registration_save_files()` Save registration files. + * 100 - `um_registration_set_profile_full_name()` Set user's full name. + * + * @since 2.0 + * @hook um_registration_set_extra_data + * + * @param {int} $user_id User ID. + * @param {array} $submitted_data $_POST Submission array. + * @param {array} $form_data UM form data. Since 2.6.7 + * + * @example Make any custom action after insert user to DB. + * function my_registration_set_extra_data( $user_id, $submitted_data, $form_data ) { * // your code here * } - * ?> + * add_action( 'um_registration_set_extra_data', 'my_registration_set_extra_data', 10, 3 ); */ - do_action( 'um_registration_set_extra_data', $user_id, $args ); - + do_action( 'um_registration_set_extra_data', $user_id, $args, $form_data ); /** - * UM hook + * Fires after complete UM user registration. + * Note: Native redirects handlers at 100 priority, you can add some info before redirects. * - * @type action - * @title um_registration_complete - * @description After complete UM user registration. Redirects handlers at 100 priority, you can add some info before redirects - * @input_vars - * [{"var":"$user_id","type":"int","desc":"User ID"}, - * {"var":"$args","type":"array","desc":"Form data"}] - * @change_log - * ["Since: 2.0"] - * @usage add_action( 'um_registration_complete', 'function_name', 10, 2 ); - * @example - * Callback name -> Excerpt): + * 10 - `um_send_registration_notification()` Send notifications. + * 100 - `um_check_user_status()` Redirect after registration based on user status. + * + * @since 2.0 + * @hook um_registration_complete + * + * @param {int} $user_id User ID. + * @param {array} $submitted_data $_POST Submission array. + * @param {array} $form_data UM form data. Since 2.6.7 + * + * @example Make any common action after complete UM user registration. + * function my_registration_complete( $user_id, $submitted_data, $form_data ) { * // your code here * } - * ?> + * add_action( 'um_registration_complete', 'my_registration_complete', 10, 3 ); */ - do_action( 'um_registration_complete', $user_id, $args ); + do_action( 'um_registration_complete', $user_id, $args, $form_data ); } -add_action( 'um_user_register', 'um_after_insert_user', 1, 2 ); +add_action( 'um_user_register', 'um_after_insert_user', 1, 3 ); /** * Send notification about registration * * @param $user_id - * @param $args */ -function um_send_registration_notification( $user_id, $args ) { +function um_send_registration_notification( $user_id ) { um_fetch_user( $user_id ); $emails = um_multi_admin_email(); @@ -137,17 +134,17 @@ function um_send_registration_notification( $user_id, $args ) { } } } -add_action( 'um_registration_complete', 'um_send_registration_notification', 10, 2 ); +add_action( 'um_registration_complete', 'um_send_registration_notification' ); /** * Check user status and redirect it after registration * - * @param $user_id - * @param $args + * @param int $user_id + * @param array $args + * @param null|array $form_data */ -function um_check_user_status( $user_id, $args ) { +function um_check_user_status( $user_id, $args, $form_data = null ) { $status = um_user( 'account_status' ); - /** * UM hook * @@ -170,102 +167,102 @@ function um_check_user_status( $user_id, $args ) { */ do_action( "um_post_registration_{$status}_hook", $user_id, $args ); - if ( ! is_admin() ) { + if ( is_null( $form_data ) || is_admin() ) { + return; + } - do_action( "track_{$status}_user_registration" ); + do_action( "track_{$status}_user_registration" ); - if ( $status == 'approved' ) { - // Check if user is logged in because there can be the customized way when through 'um_registration_for_loggedin_users' hook the registration is enabled for the logged in users (e.g. Administrator). - if ( ! is_user_logged_in() ) { - // Custom way if 'um_registration_for_loggedin_users' hook after custom callbacks returns true. Then don't make auto-login because user is already logged-in. - UM()->user()->auto_login( $user_id ); - } - UM()->user()->generate_profile_slug( $user_id ); + if ( 'approved' === $status ) { + // Check if user is logged in because there can be the customized way when through 'um_registration_for_loggedin_users' hook the registration is enabled for the logged-in users (e.g. Administrator). + if ( ! is_user_logged_in() ) { + // Custom way if 'um_registration_for_loggedin_users' hook after custom callbacks returns true. Then don't make auto-login because user is already logged-in. + UM()->user()->auto_login( $user_id ); + } + UM()->user()->generate_profile_slug( $user_id ); + /** + * UM hook + * + * @type action + * @title um_registration_after_auto_login + * @description After complete UM user registration and autologin. + * @input_vars + * [{"var":"$user_id","type":"int","desc":"User ID"}] + * @change_log + * ["Since: 2.0"] + * @usage add_action( 'um_registration_after_auto_login', 'function_name', 10, 1 ); + * @example + * + */ + do_action( 'um_registration_after_auto_login', $user_id ); + + // Priority redirect + if ( isset( $args['redirect_to'] ) ) { + wp_safe_redirect( urldecode( $args['redirect_to'] ) ); + exit; + } + + um_fetch_user( $user_id ); + + if ( 'redirect_url' === um_user( 'auto_approve_act' ) && '' !== um_user( 'auto_approve_url' ) ) { + wp_safe_redirect( um_user( 'auto_approve_url' ) ); + exit; + } + + if ( 'redirect_profile' === um_user( 'auto_approve_act' ) ) { + wp_safe_redirect( um_user_profile_url() ); + exit; + } + } else { + if ( 'redirect_url' === um_user( $status . '_action' ) && '' !== um_user( $status . '_url' ) ) { /** * UM hook * - * @type action - * @title um_registration_after_auto_login - * @description After complete UM user registration and autologin. + * @type filter + * @title um_registration_pending_user_redirect + * @description Change redirect URL for pending user after registration * @input_vars - * [{"var":"$user_id","type":"int","desc":"User ID"}] + * [{"var":"$url","type":"string","desc":"Redirect URL"}, + * {"var":"$status","type":"string","desc":"User status"}, + * {"var":"$user_id","type":"int","desc":"User ID"}] * @change_log * ["Since: 2.0"] - * @usage add_action( 'um_registration_after_auto_login', 'function_name', 10, 1 ); + * @usage + * * @example * */ - do_action( 'um_registration_after_auto_login', $user_id ); - - // Priority redirect - if ( isset( $args['redirect_to'] ) ) { - exit( wp_safe_redirect( urldecode( $args['redirect_to'] ) ) ); - } - - um_fetch_user( $user_id ); - - if ( um_user( 'auto_approve_act' ) == 'redirect_url' && um_user( 'auto_approve_url' ) !== '' ) { - exit( wp_redirect( um_user( 'auto_approve_url' ) ) ); - } - - if ( um_user( 'auto_approve_act' ) == 'redirect_profile' ) { - exit( wp_redirect( um_user_profile_url() ) ); - } - - } else { - - if ( um_user( $status . '_action' ) == 'redirect_url' && um_user( $status . '_url' ) != '' ) { - /** - * UM hook - * - * @type filter - * @title um_registration_pending_user_redirect - * @description Change redirect URL for pending user after registration - * @input_vars - * [{"var":"$url","type":"string","desc":"Redirect URL"}, - * {"var":"$status","type":"string","desc":"User status"}, - * {"var":"$user_id","type":"int","desc":"User ID"}] - * @change_log - * ["Since: 2.0"] - * @usage - * - * @example - * - */ - $redirect_url = apply_filters( 'um_registration_pending_user_redirect', um_user( $status . '_url' ), $status, um_user( 'ID' ) ); - - exit( wp_redirect( $redirect_url ) ); - } - - if ( um_user( $status . '_action' ) == 'show_message' && um_user( $status . '_message' ) != '' ) { - - $url = UM()->permalinks()->get_current_url(); - $url = add_query_arg( 'message', esc_attr( $status ), $url ); - //add only priority role to URL - $url = add_query_arg( 'um_role', esc_attr( um_user( 'role' ) ), $url ); - $url = add_query_arg( 'um_form_id', esc_attr( $args['form_id'] ), $url ); - - exit( wp_redirect( $url ) ); - } + $redirect_url = apply_filters( 'um_registration_pending_user_redirect', um_user( $status . '_url' ), $status, um_user( 'ID' ) ); + wp_safe_redirect( $redirect_url ); + exit; } - } + if ( 'show_message' === um_user( $status . '_action' ) && '' !== um_user( $status . '_message' ) ) { + $url = UM()->permalinks()->get_current_url(); + $url = add_query_arg( 'message', esc_attr( $status ), $url ); + // Add only priority role to URL. + $url = add_query_arg( 'um_role', esc_attr( um_user( 'role' ) ), $url ); + $url = add_query_arg( 'um_form_id', esc_attr( $form_data['form_id'] ), $url ); + wp_safe_redirect( $url ); + exit; + } + } } -add_action( 'um_registration_complete', 'um_check_user_status', 100, 2 ); +add_action( 'um_registration_complete', 'um_check_user_status', 100, 3 ); /** * Validate user password field on registration. @@ -284,8 +281,9 @@ add_action( 'um_submit_form_errors_hook__registration', 'um_submit_form_errors_h * Registration form submit handler. * * @param array $args + * @param array $form_data */ -function um_submit_form_register( $args ) { +function um_submit_form_register( $args, $form_data ) { if ( isset( UM()->form()->errors ) ) { return; } @@ -299,17 +297,18 @@ function um_submit_form_register( $args ) { * @hook um_add_user_frontend_submitted * * @param {array} $submitted Submitted registration data. + * @param {array} $form_data UM form data. Since 2.6.7 * * @return {array} Extended registration data. * * @example Extends registration data. - * function my_add_user_frontend_submitted( $submitted ) { + * function my_add_user_frontend_submitted( $submitted, $form_data ) { * // your code here * return $submitted; * } - * add_filter( 'um_add_user_frontend_submitted', 'my_add_user_frontend_submitted' ); + * add_filter( 'um_add_user_frontend_submitted', 'my_add_user_frontend_submitted', 10, 2 ); */ - $args = apply_filters( 'um_add_user_frontend_submitted', $args ); + $args = apply_filters( 'um_add_user_frontend_submitted', $args, $form_data ); if ( ! empty( $args['user_login'] ) ) { $user_login = $args['user_login']; @@ -411,6 +410,7 @@ function um_submit_form_register( $args ) { 'user_email' => trim( $user_email ), ); + // @todo test when ready maybe remove if ( ! empty( $args['submitted'] ) ) { $args['submitted'] = UM()->form()->clean_submitted_data( $args['submitted'] ); } @@ -446,17 +446,18 @@ function um_submit_form_register( $args ) { * * @param {string} $user_role User role. * @param {array} $args Registration data. + * @param {array} $form_data UM form data. Since 2.6.7 * * @return {string} User role. * * @example Change user role on registration process. - * function my_registration_user_role( $user_role, $args ) { + * function my_registration_user_role( $user_role, $args, $form_data ) { * // your code here * return $user_role; * } - * add_filter( 'um_registration_user_role', 'my_registration_user_role', 10, 2 ); + * add_filter( 'um_registration_user_role', 'my_registration_user_role', 10, 3 ); */ - $user_role = apply_filters( 'um_registration_user_role', $user_role, $args ); + $user_role = apply_filters( 'um_registration_user_role', $user_role, $args, $form_data ); $userdata = array( 'user_login' => $user_login, @@ -466,25 +467,32 @@ function um_submit_form_register( $args ) { ); $user_id = wp_insert_user( $userdata ); + if ( is_wp_error( $user_id ) ) { + return; + } /** * Fires after complete UM user registration. * + * Internal Ultimate Member callbacks (Priority -> Callback name -> Excerpt): + * 1 - `um_after_insert_user()` Make all Ultimate Member data set and actions after user registration|added via wp-admin. + * * @since 2.0 * @hook um_user_register * - * @param {int} $user_id User ID. - * @param {array} $args Form data. + * @param {int} $user_id User ID. + * @param {array} $args Form data. + * @param {array} $form_data UM form data. Since 2.6.7 * * @example Make any custom action after complete UM user registration. - * function my_um_user_register( $user_id, $args ) { + * function my_um_user_register( $user_id, $args, $form_data ) { * // your code here * } - * add_action( 'um_user_register', 'my_um_user_register', 10, 2 ); + * add_action( 'um_user_register', 'my_um_user_register', 10, 3 ); */ - do_action( 'um_user_register', $user_id, $args ); + do_action( 'um_user_register', $user_id, $args, $form_data ); } -add_action( 'um_submit_form_register', 'um_submit_form_register' ); +add_action( 'um_submit_form_register', 'um_submit_form_register', 10, 2 ); /** * Show the submit button @@ -615,36 +623,29 @@ function um_add_register_fields( $args ){ } add_action( 'um_main_register_fields', 'um_add_register_fields', 100 ); - /** - * Saving files to register a new user, if there are fields with files + * Saving files to register a new user, if there are fields with files. * * @param $user_id * @param $args + * @param $form_data */ -function um_registration_save_files( $user_id, $args ) { - - if ( empty( $args['custom_fields'] ) ) { +function um_registration_save_files( $user_id, $args, $form_data ) { + if ( empty( $args['submitted'] ) ) { + // It's only frontend case. return; } $files = array(); - $fields = unserialize( $args['custom_fields'] ); - - // loop through fields - if ( isset( $fields ) && is_array( $fields ) ) { - + $fields = maybe_unserialize( $form_data['custom_fields'] ); + if ( ! empty( $fields ) && is_array( $fields ) ) { foreach ( $fields as $key => $array ) { - if ( isset( $args['submitted'][ $key ] ) ) { - - if ( isset( $fields[ $key ]['type'] ) && in_array( $fields[ $key ]['type'], array( 'image', 'file' ) ) && - ( um_is_temp_file( $args['submitted'][ $key ] ) || $args['submitted'][ $key ] == 'empty_file' ) + if ( isset( $array['type'] ) && in_array( $array['type'], array( 'image', 'file' ), true ) && + ( um_is_temp_file( $args['submitted'][ $key ] ) || 'empty_file' === $args['submitted'][ $key ] ) ) { - $files[ $key ] = $args['submitted'][ $key ]; - } } } @@ -679,7 +680,7 @@ function um_registration_save_files( $user_id, $args ) { UM()->uploader()->replace_upload_dir = false; } } -add_action( 'um_registration_set_extra_data', 'um_registration_save_files', 10, 2 ); +add_action( 'um_registration_set_extra_data', 'um_registration_save_files', 10, 3 ); /** @@ -692,35 +693,29 @@ add_action( 'um_registration_set_extra_data', 'um_registration_save_files', 10, */ function um_registration_set_profile_full_name( $user_id, $args ) { /** - * UM hook + * Fires for updating user profile full name. * - * @type action - * @title um_update_profile_full_name - * @description On update user profile change full name - * @input_vars - * [{"var":"$user_id","type":"int","desc":"User ID"}, - * {"var":"$args","type":"array","desc":"Form data"}] - * @change_log - * ["Since: 2.0"] - * @usage add_action( 'um_update_profile_full_name', 'function_name', 10, 2 ); - * @example - * Make any custom action when updating user profile full name. + * function my_registration_set_extra_data( $user_id, $submitted_data ) { * // your code here * } - * ?> + * add_action( 'um_update_profile_full_name', 'my_update_profile_full_name', 10, 2 ); */ do_action( 'um_update_profile_full_name', $user_id, $args ); } add_action( 'um_registration_set_extra_data', 'um_registration_set_profile_full_name', 10, 2 ); - /** * Redirect from default registration to UM registration page */ function um_form_register_redirect() { - $page_id = UM()->options()->get( UM()->options()->get_core_page_id( 'register' ) ); + $page_id = UM()->options()->get( UM()->options()->get_core_page_id( 'register' ) ); $register_post = get_post( $page_id ); if ( ! empty( $register_post ) ) { wp_safe_redirect( get_permalink( $page_id ) );