1

I'm trying to generate a unique random value from an array and store it in another array so it can't be used again.

I've managed to generate the random value based on a meta field but I'm not sure how I would go about making this unique and ensuring the same values aren't being generated again. I've created an empty array $tickethistory to save the values into. Is it possible the next time it runs to run a validation check so the $lottery_max_tickets don't include the $tickethistory values?

I'm using the function below which returns the number and I', calling it when customers purchase a product in Woocommerce.

function add_lottery_ticket_number( $postid ) {
    $tickethistory = array();
    $lottery_max_tickets = get_post_meta( $postid, '_max_tickets', true );
    $max_tickets = range(1, $lottery_max_tickets);

    $ticketallocated = array_rand($max_tickets, 1);
    $tickethistory[] = $ticketallocated;

    return $ticketallocated;
}


for ( $i = 0; $i < $item_meta['_qty'][0]; $i++ ) {
    add_post_meta( $product_id, '_participant_id', $order->get_user_id() );
    $participants = get_post_meta( $product_id, '_lottery_participants_count', true ) ? get_post_meta( $product_id, '_lottery_participants_count', true ) : 0;
    update_post_meta( $product_id, '_lottery_participants_count', intval( $participants ) + 1 );
    $this->add_lottery_to_user_metafield( $product_id, $order->get_user_id() );
    $ticketnumber = $this->add_lottery_ticket_number($product_id);
    $log_ids[] = $this->log_participant( $product_id, $order->get_user_id(), $ticketnumber, $order_id, $item );
}
4
  • Can you save the history in the for-loop scope? I mean - do you want it to be unique for each i or for bigger scope? Commented Jan 8, 2019 at 17:30
  • Hi David, I want it to be unique for each i and the bigger scope. So when a new customer purchases the same product, they won't be able to have numbers which are already allocated to a different customer. They also need to be unique for an individual purchase so if they have 10 items, it will generate 10 unique numbers. Does that make sense? Commented Jan 8, 2019 at 17:57
  • I think I got it - Did my post answer your question? Commented Jan 9, 2019 at 6:48
  • Hi David, I haven't been able to test it yet but looks like it will work. Thanks so much Commented Jan 9, 2019 at 10:43

1 Answer 1

1

As you can see here, you can use storing array in the metadata - in your case, the tickethistory array.

But, for your case I would take different approach - create ticket options once and assign the first element each time.

Consider the following:

function add_lottery_ticket_number( $postId ) {
    if (metadata_exists('post', $postId, 'optionsToGive')) {
        $ticketOptions = get_post_meta( $postId, 'optionsToGive', true );
    } else {
        $lottery_max_tickets = get_post_meta( $postid, '_max_tickets', true );
        $ticketOptions = range(1, $lottery_max_tickets);
        shuffle($ticketOptions ); //random order of all number
    }
    $ticketAllocated = array_shift($ticketOptions); //take the first element
    update_post_meta( $postId, 'optionsToGive', $ticketOptions ); //update all the rest
    return $ticketAllocated;
}

Notice, if all numbers has been assign this will return null.

As I never tested this code please consider it as pseudo.

Sign up to request clarification or add additional context in comments.

2 Comments

Just a quick question - What benefits does metadeta_exists have over empty or isset?
I have no huge experience in metadata method but it seems good practice to check exist then to use get_post_meta and check if empty

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.