Wordpress - генерирует случайное уникальное число с помощью атомарной операции и обновляет базу данных - PullRequest
0 голосов
/ 16 января 2019

Я создал таблицу с именем wp_tickets, которая содержит диапазон номеров билетов, сгенерированных из настраиваемого поля, установленного в моем посте WordPress. Столбцы в таблице: 'id', 'ticket_id', 'lottery_id' и 'used'.

Я пытаюсь сгенерировать случайное уникальное число, когда покупатель покупает товары на моем сайте.

Например, если клиент заказывает пять одинаковых товаров. Необходимо сгенерировать 5 случайных уникальных чисел на основе поля, установленного в метаполе продукта 'maximum_entries', а затем пометить эти числа как «использованные» в таблице wp_tickets.

Мне нужно, чтобы это была атомарная операция, чтобы у клиентов не было одинакового номера, если они заказывают в одно и то же время.

До сих пор я создал функцию, которая будет вызываться на крюке woocommerce_order_status_processing, который перебирает каждый товар в корзине и получает количество товара. Затем я использовал функцию диапазона, чтобы превратить это в массив чисел перед вызовом array_rand.

Затем я использую $ticketallocated в моей функции $wpdb update.

Проблема, с которой я столкнулся, заключается в том, что генерируемый номер уже помечен в таблице как «используемый», после чего он не возвращается к началу и пытается снова. Мне нужно как-то настроить оператор if / else, чтобы, если генерируемое случайное число равнялось 5, а в базе данных уже было 5 как «использованное», оно будет пытаться использовать другое число.

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
            "
);     

}             

}

1 Ответ

0 голосов
/ 17 января 2019

Мне удалось заставить его работать, создав две функции. Один отвечает за получение всех доступных номеров из таблицы wp_tickets, где used = 0 и lottery_id = $postID, которая возвращает одно случайное число из доступных номеров билетов.

Вторая функция отвечает за обновление таблицы wp_tickets номером заявки, сгенерированным из функции get_available_numbers.

Обе эти функции затем выполняются на хуке woocommerce_order_status_processing при заказе клиента и запускаются для каждого товара, найденного в его корзине.

Пока что, когда я это проверил, похоже, это работает. Однако трудно сказать, как это происходит с несколькими заказчиками одновременно.

function get_available_numbers($postID) {
            global $wpdb;
                $result = $wpdb->get_results(
                    "
                    SELECT ticket_number
                    FROM wp_tickets
                    WHERE lottery_id = ".$postID." AND used = 0
                    ORDER BY RAND()
                    LIMIT 1
                    "
                    );
            return $result[0]->ticket_number;
}


function add_ticket_number($postID, $order_id, $number, $user_id) {
        global $wpdb;

        $wpdb->query(
            "
            UPDATE wp_tickets
            SET used = 1, order_id = ".$order_id.", user_id = ".$user_id."
            WHERE ticket_number= ".$number." AND lottery_id = ".$postID." AND used = 0
            "
                    );
}


for ( $i = 0; $i < $item_meta['_qty'][0]; $i++ ) {
                        $number = $this->get_available_numbers($product_id);
                        $this->add_ticket_number($product_id, $order_id, $number, $order->get_user_id());
                    }

UPDATE

Мне действительно удалось сократить это до одной функции, установив used=1 в столбце lottery_id и назначив обновление случайным и ограниченное единицей.

function add_ticket_number($postID, $order_id, $user_id) {
        global $wpdb;

        $wpdb->query(
            "
            UPDATE wp_tickets
            SET used = 1, order_id = ".$order_id.", user_id = ".$user_id."
            WHERE lottery_id = ".$postID." AND used = 0
                        ORDER BY RAND()
                        LIMIT 1
            "
                    );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...