Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update customer password in WooCommerce admin orders dashboard

We have a pretty specific situation and I wonder anyone already make something similar. On Woocommerce order we generate user in WP with order mail. Then our agents need to change their password manually because this password is like a PIN code to their content. We ship these PIN numbers by classic mail in an envelope. The problem is that agents need to manually go from order dashboard to Users - find the right user and change their password. Is there any way to make an input field on the order dashboard to set a password for the user linked to this order?

like image 824
Karnak Avatar asked Jan 16 '21 16:01

Karnak


1 Answers

Here is a complete solution that will add in admin orders list a custom column with a button (in each row) allowing editing the user password via Ajax.

enter image description here

Then when shop manager will click on the button of the desired order, an input text field will appear where the new password can be updated via Ajax.

enter image description here

A message will be shortly displayed showing if this update has succeeded or not.

So here is the complete code:

// Add a column to admin orders list
add_filter( 'manage_edit-shop_order_columns', 'add_edit_password_orders_column' );
function add_edit_password_orders_column( $columns ) {
    if( current_user_can( 'edit_shop_orders' ) ) {
        $sorted_columns = [];

        foreach ( $columns as $key => $value ) {
            if ( $key === 'order_total') {
                $sorted_columns[ 'edit_password' ] = __('Edit password', 'woocommerce');
            }
            $sorted_columns[$key] = $columns[$key];
        }

        return $sorted_columns;
    }
    return $columns;
}

// Column content
add_action( 'manage_shop_order_posts_custom_column', 'edit_password_orders_column_row_content' );
function edit_password_orders_column_row_content( $column ) {
    if ( 'edit_password' === $column ) {
        global $post, $the_order;

        $user = $the_order->get_user();

        if( is_a($user, 'WP_User') && $user->ID > 0 ) {
            echo '<div class="edit_password userid-' . $user->ID . '" data-user_id="' . $user->ID . '">
                <a class="button user-login" style="text-align:center; display:block;">' . __('Edit', 'woocommerce') . '</a>
                <div  class="hidden-fields" style="display:none;">
                    <input type="text" name="customer-password" class="customer-password" value="" style="width:auto; max-width:120px; margin-bottom: 6px;">
                    <input type="hidden" name="customer-id" class="customer-id" value="' . $user->ID . '">
                    <a class="button submit-password" style="text-align:center;">' . __('Ok', 'woocommerce') . '</a>
                </div>
                <div class="message-response" style="display:none;">Message</div>
            </div>';
        } else {
            echo __("Guest user", "woocommerce");
        }
    }
}

// Jquery Ajax
add_action( 'admin_footer', 'edit_password_orders_column_js' );
function edit_password_orders_column_js() {
    global $pagenow;

    if ( $pagenow === 'edit.php' && isset($_GET['post_type']) && 'shop_order' === $_GET['post_type'] ) :
    ?>
    <script type="text/javascript">
    jQuery( function($){
        $('div.edit_password > .button.user-login').on('click', function(e){
            e.preventDefault();

            $(this).hide('fast');
            $(this).parent().find('.hidden-fields').show('slow');
        });

        $(document.body).on('click focus focusin', 'div.edit_password input.customer-password', function(e){
            e.stopImmediatePropagation();
        });

        $('div.edit_password .button.submit-password').on('click', function(e){
            e.preventDefault();
            e.stopImmediatePropagation();

            var $this = $(this),
                $parent = $this.parent(),
                password = $parent.find('input.customer-password').val(),
                user_id  = $parent.find('input.customer-id').val(),
                text = '',
                color = 'red';

            $.ajax({
                type: 'POST',
                url: '<?php echo admin_url('/admin-ajax.php'); ?>',
                data: {
                    'action'           : 'updating_customer_password',
                    'customer-password': password,
                    'customer-id'      : user_id
                },
                success: function (response) {
                    if ( response === 'empty' ) {
                        text  = '<?php echo __('Empty input, retry…', 'woocommerce'); ?>';
                    } else if ( response === 'whitespace' ) {
                        text  = '<?php echo __('No white spaces…', 'woocommerce'); ?>';
                    } else {
                        text  = '<?php echo __('Updating password!', 'woocommerce'); ?>';
                        color = 'green';
                    }
                    $parent.find('input.customer-password').val('');
                    $parent.parent().find('.hidden-fields').hide('fast');
                    $parent.parent().find('div.message-response').css('color',color).html('<small>'+text+'<small>').show();
                    setTimeout(function(){
                        $parent.parent().find('div.message-response').css('color','black').html('').hide();
                        $parent.parent().find('a.user-login').show();
                    }, 2000);

                    console.log(response); // For testing (to be removed)
                },
                error: function (error) {
                    $this.parent().parent().find('.hidden-fields').hide('fast');
                    $this.parent().parent().find('div.message-response').html('Error!').css('color',color).show();
                    setTimeout(function(){
                        $parent.parent().find('div.message-response').css('color','black').html('').hide();
                        $parent.parent().find('a.user-login').show();
                    }, 2000);

                    console.log(error); // For testing (to be removed)
                }
            });
        });
    });
    </script>
    <?php
    endif;
}

// PHP Ajax receiver
add_action('wp_ajax_updating_customer_password', 'action_ajax_updating_customer_password');
function action_ajax_updating_customer_password() {
    if ( isset($_POST['customer-password']) && isset($_POST['customer-id']) ) {
        $password = sanitize_text_field( $_POST['customer-password'] );
        $user_id  = intval( esc_attr( $_POST['customer-id'] ) );

        if ( ! $password ) {
            echo 'empty'; // empty input
        } elseif ( strpos($password, ' ') !== false ) {
            echo 'whitespace'; // empty input
        } else {

            wp_set_password( $password, $user_id ); // Set new password
        }
        wp_die();
    }
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

like image 172
LoicTheAztec Avatar answered Sep 19 '22 00:09

LoicTheAztec