Saturday, 19 January 2019

Wordpress - generate random unique number using atomic operation and update database

I have created a table called wp_tickets which contains a range of ticket numbers generated from a custom field set in my wordpress post. The columns in the table are 'id', 'ticket_id', 'lottery_id' and 'used'.

I'm trying to generate a random unique number when a customer purchases the products on my website.

For example, if a customer orders five of the same product. It needs to generate 5 random unique numbers based on the field set in the product meta field, 'maximum_entries' and then mark those numbers as 'used' in the wp_tickets table.

I need to this to be an atomic operation so customers can't have the same number if they order at the same time.

So far, i've created a function to be called on the woocommerce_order_status_processing hook which loops through each product in the cart and gets the product qty. I've then used the range function to turn this into an array of numbers before calling array_rand.

I then use the $ticketallocated in my $wpdb update function.

The problem i have is if the number being generated is already marked as 'used' in the table then it doesn't loop back to the top and try again. I need to somehow setup an if/else statement so if the random number being generated is 5 and there's already a 5 in the database as 'used' then it will try a different number.

add_action('acf/save_post', 'my_acf_save_post', 20);
function my_acf_save_post( $post_id ) {
    global $wpdb;
    $qty = get_field('maximum_entries');
    $array = range(1, $qty);

    foreach ($array as $ticket) {
     $wpdb->insert('wp_tickets', array(
         'ticket_number' => $ticket,
         'lottery_id' => $post_id,
     ));
    }
}


add_action( 'woocommerce_order_status_processing', 'ektgn_meta_to_line_item', 20, 4 );

function ektgn_meta_to_line_item( $order_id )
{

    $order = wc_get_order($order_id);

    foreach( $order->get_items() as $item_id => $item_product ) {
        global $wpdb;

        $product_id = $item_product->get_product_id();
        $qty = get_field('maximum_entries', $product_id, true);
        $ticketOptions = range(1, $qty);
        $ticketAllocated = array_rand($ticketOptions, 1);

        $wpdb->query(
            "
            UPDATE wp_tickets 
            SET used = 1
            WHERE ticket_number= ".$ticketAllocated." AND lottery_id = ".$product_id." AND used = 0
            "
);     

}             

}



from Wordpress - generate random unique number using atomic operation and update database

No comments:

Post a Comment