diff --git a/inc/checkout/class-checkout.php b/inc/checkout/class-checkout.php index 2ba02b359..f21b58916 100644 --- a/inc/checkout/class-checkout.php +++ b/inc/checkout/class-checkout.php @@ -1717,18 +1717,19 @@ public function validation_rules() { * First, let's set upm the general rules: */ $rules = [ - 'email_address' => 'required_without:user_id|email|unique:\WP_User,email', - 'username' => 'required_without:user_id|alpha_dash|min:4|lowercase|unique:\WP_User,login', - 'password' => 'required_without:user_id|min:6', - 'password_conf' => 'same:password', - 'template_id' => 'integer|site_template', - 'products' => 'products', - 'gateway' => '', - 'valid_password' => 'accepted', - 'billing_country' => 'country|required_with:billing_country', - 'billing_zip_code' => 'required_with:billing_zip_code', - 'billing_state' => 'state', - 'billing_city' => 'city', + 'email_address' => 'required_without:user_id|email|unique:\WP_User,email', + 'email_address_confirmation' => 'same:email_address', + 'username' => 'required_without:user_id|alpha_dash|min:4|lowercase|unique:\WP_User,login', + 'password' => 'required_without:user_id|min:6', + 'password_conf' => 'same:password', + 'template_id' => 'integer|site_template', + 'products' => 'products', + 'gateway' => '', + 'valid_password' => 'accepted', + 'billing_country' => 'country|required_with:billing_country', + 'billing_zip_code' => 'required_with:billing_zip_code', + 'billing_state' => 'state', + 'billing_city' => 'city', ]; /* @@ -1859,11 +1860,12 @@ public function validate($rules = null) { // Add some hidden or compound fields ids $validation_aliases = array_merge( [ - 'password_conf' => __('Password confirmation', 'multisite-ultimate'), - 'template_id' => __('Template ID', 'multisite-ultimate'), - 'valid_password' => __('Valid password', 'multisite-ultimate'), - 'products' => __('Products', 'multisite-ultimate'), - 'gateway' => __('Payment Gateway', 'multisite-ultimate'), + 'password_conf' => __('Password confirmation', 'multisite-ultimate'), + 'email_address_confirmation' => __('Email confirmation', 'multisite-ultimate'), + 'template_id' => __('Template ID', 'multisite-ultimate'), + 'valid_password' => __('Valid password', 'multisite-ultimate'), + 'products' => __('Products', 'multisite-ultimate'), + 'gateway' => __('Payment Gateway', 'multisite-ultimate'), ], $base_aliases ); diff --git a/inc/checkout/signup-fields/class-signup-field-email-confirmation.php b/inc/checkout/signup-fields/class-signup-field-email-confirmation.php new file mode 100644 index 000000000..69bba49d6 --- /dev/null +++ b/inc/checkout/signup-fields/class-signup-field-email-confirmation.php @@ -0,0 +1,332 @@ + true, + 'confirmation_label' => __('Confirm Email Address', 'multisite-ultimate'), + 'confirmation_placeholder' => __('Re-enter your email address', 'multisite-ultimate'), + ]; + } + + /** + * List of keys of the default fields we want to display on the builder. + * + * @since 2.0.0 + * @return array + */ + public function default_fields() { + + return [ + 'name', + 'placeholder', + 'tooltip', + ]; + } + + /** + * If you want to force a particular attribute to a value, declare it here. + * + * @since 2.0.0 + * @return array + */ + public function force_attributes() { + + return [ + 'id' => 'email_address', + 'required' => true, + ]; + } + + /** + * Returns the list of additional fields specific to this type. + * + * @since 2.0.0 + * @return array + */ + public function get_fields() { + + return [ + 'display_notices' => [ + 'type' => 'toggle', + 'title' => __('Display Notices', 'multisite-ultimate'), + 'desc' => __('When the customer is already logged in, a box with the customer\'s username and a link to logout is displayed instead of the email fields. Disable this option if you do not want that box to show up.', 'multisite-ultimate'), + 'tooltip' => '', + 'value' => 1, + 'html_attr' => [ + 'v-model' => 'display_notices', + ], + ], + 'confirmation_label' => [ + 'type' => 'text', + 'title' => __('Confirmation Field Label', 'multisite-ultimate'), + 'placeholder' => __('e.g. Confirm Email Address', 'multisite-ultimate'), + 'desc' => __('This is the label for the email confirmation field.', 'multisite-ultimate'), + 'tooltip' => '', + 'value' => __('Confirm Email Address', 'multisite-ultimate'), + 'html_attr' => [ + 'v-model' => 'confirmation_label', + ], + ], + 'confirmation_placeholder' => [ + 'type' => 'text', + 'title' => __('Confirmation Field Placeholder', 'multisite-ultimate'), + 'placeholder' => __('e.g. Re-enter your email address', 'multisite-ultimate'), + 'desc' => __('This value appears inside the confirmation field as placeholder text.', 'multisite-ultimate'), + 'tooltip' => '', + 'value' => __('Re-enter your email address', 'multisite-ultimate'), + 'html_attr' => [ + 'v-model' => 'confirmation_placeholder', + ], + ], + ]; + } + + /** + * Returns the field/element actual field array to be used on the checkout form. + * + * @since 2.0.0 + * + * @param array $attributes Attributes saved on the editor form. + * @return array An array of fields, not the field itself. + */ + public function to_fields_array($attributes) { + + $checkout_fields = []; + + if (is_user_logged_in()) { + if ($attributes['display_notices']) { + $checkout_fields['login_note'] = [ + 'type' => 'note', + 'title' => __('Not you?', 'multisite-ultimate'), + 'desc' => [$this, 'render_not_you_customer_message'], + 'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''), + 'wrapper_html_attr' => [ + 'style' => $this->calculate_style_attr(), + ], + ]; + } + } else { + if ($attributes['display_notices']) { + $checkout_fields['login_note'] = [ + 'type' => 'note', + 'title' => __('Existing customer?', 'multisite-ultimate'), + 'desc' => [$this, 'render_existing_customer_message'], + 'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''), + 'wrapper_html_attr' => [ + 'style' => $this->calculate_style_attr(), + ], + ]; + } + + $checkout_fields['email_address'] = [ + 'type' => 'email', + 'id' => 'email_address', + 'name' => $attributes['name'], + 'placeholder' => $attributes['placeholder'], + 'tooltip' => $attributes['tooltip'], + 'value' => $this->get_value(), + 'required' => true, + 'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''), + 'classes' => wu_get_isset($attributes, 'element_classes', ''), + 'wrapper_html_attr' => [ + 'style' => $this->calculate_style_attr(), + ], + ]; + + $checkout_fields['email_address_confirmation'] = [ + 'type' => 'email', + 'id' => 'email_address_confirmation', + 'name' => wu_get_isset($attributes, 'confirmation_label', __('Confirm Email Address', 'multisite-ultimate')), + 'placeholder' => wu_get_isset($attributes, 'confirmation_placeholder', __('Re-enter your email address', 'multisite-ultimate')), + 'tooltip' => __('Please re-enter your email address to confirm it matches.', 'multisite-ultimate'), + 'value' => '', + 'required' => true, + 'wrapper_classes' => wu_get_isset($attributes, 'wrapper_element_classes', ''), + 'classes' => wu_get_isset($attributes, 'element_classes', ''), + 'wrapper_html_attr' => [ + 'style' => $this->calculate_style_attr(), + ], + 'html_attr' => [ + 'data-confirm-email' => 'email_address', + ], + ]; + } + + return $checkout_fields; + } + + /** + * Renders the login message for users that are not logged in. + * + * @since 2.0.0 + * @return string + */ + public function render_existing_customer_message() { + + $login_url = wp_login_url(add_query_arg('logged', '1')); + + ob_start(); ?> + +
+ Log in using your account.', 'multisite-ultimate')), esc_html(wp_get_current_user()->display_name), esc_attr($login_url)); + + ?> +
+ + [$this, 'render_orphaned_users_delete_modal'], + 'handler' => [$this, 'handle_orphaned_users_delete_modal'], + 'capability' => 'manage_network', + ] + ); + } + + /** + * Register settings field for orphaned users cleanup. + * + * @since 2.0.0 + * @return void + */ + public function register_settings_field(): void { + wu_register_settings_field( + 'other', + 'cleanup_orphaned_users', + [ + 'title' => __('Cleanup Orphaned User Accounts', 'multisite-ultimate'), + 'desc' => __('Remove user accounts that are not members of any site and are not super administrators.', 'multisite-ultimate'), + 'type' => 'link', + 'display_value' => __('Check for Orphaned Users', 'multisite-ultimate'), + 'classes' => 'button button-secondary wu-ml-0 wubox', + 'wrapper_html_attr' => [ + 'style' => 'margin-bottom: 20px;', + ], + 'html_attr' => [ + 'href' => wu_get_form_url('orphaned_users_delete'), + 'wu-tooltip' => __('Scan and cleanup user accounts with no site memberships', 'multisite-ultimate'), + ], + ] + ); + } + + /** + * Renders the orphaned users deletion confirmation modal. + * + * @since 2.0.0 + * @return void + */ + public function render_orphaned_users_delete_modal(): void { + + $orphaned_users = $this->find_orphaned_users(); + + $user_count = count($orphaned_users); + if (! $user_count) { + printf( + '%s
+%s
+ %s ++ %s %s +
+