Home > OS >  Display how many people have a product in their WooCommerce cart but add a (temporarily) random numb
Display how many people have a product in their WooCommerce cart but add a (temporarily) random numb

Time:02-24

Similar to what you see on stores like Etsy, I would like to display the number of people that have a product in their cart.

Via Show how many people have added a product in their current cart, I was able to achieve it.

But my website is still under construction, and when I start it, I would like to make it look like 2-4 people already have the product in their cart.

So I made an adjustment to that existing code, I added $in_basket = rand(2, 4); which gives as complete result:

function show_no_of_people_added_in_cart() {
    global $wpdb, $product;
    
    $in_basket = rand(2, 4);
    
    $wc_session_data = $wpdb->get_results( "SELECT session_key FROM {$wpdb->prefix}woocommerce_sessions" );
    $wc_session_keys = wp_list_pluck( $wc_session_data, 'session_key' );
    
    if ( $wc_session_keys ) {
        foreach ( $wc_session_keys as $key => $_customer_id ) { 
            // if you want to skip current viewer cart item in counts or else can remove belows checking
            if( WC()->session->get_customer_id() == $_customer_id ) continue;
            
            $session_contents = WC()->session->get_session( $_customer_id, array() );
            $cart_contents = maybe_unserialize( $session_contents['cart'] );
            
            if ( $cart_contents ) {
                foreach ( $cart_contents as $cart_key => $item ) {
                    if( $item['product_id'] == $product->get_id() ) {
                        $in_basket  = 1;
                    }
                }
            }
        }
    }

    if ( $in_basket ) 
        echo '<div >' . sprintf( __( 'Hurry! %d people have this in their cart!', 'text-domain' ), $in_basket ) . '</div>';

}
add_action( 'woocommerce_after_shop_loop_item_title', 'show_no_of_people_added_in_cart', 11 );
add_action( 'woocommerce_single_product_summary', 'show_no_of_people_added_in_cart', 21 );

But the problem with is that at every refresh the number changes. How can I keep that random number for a while? Any advice?

CodePudding user response:

I would use sessions to store the number of people who have the product in their cart.

In the example below, I am gonna keep the same number in the session for 1 minute (60 seconds).

First, enable sessions in Wordpress - at the beginning of function.php put this code:

if (!session_id()) {
    session_start();

    // create a session 'randinbasket' containing an empty array if it doesnt exist
    if (!isset($_SESSION['randinbasket'])) $_SESSION['randinbasket'] = array();
}

Then, create a function which either gets a number from the session or generates a new one:

/**
 * Generates a random number, stores it in a session
 * @param integer $minCount - minimal number
 * @param integer $maxCount - maximal number 
 * @param integer $prodId - product ID
 * @param integer $expiresAfter - session expiry in seconds 
 */
function get_random_in_basket($minCount, $maxCount, $prodId, $expiresAfter) {
    $inBasketData = $_SESSION['randinbasket'];
    $prodKey = 'product_' . $prodId;
    $timeNow = time(); // current timestamp
    $randomCount = rand($minCount, $maxCount);

    if (isset($inBasketData[$prodKey])) { // If product data exists in the session
        $inBasketProductData = $inBasketData[$prodKey];

        // If current time is within expiration time
        if ($timeNow <= $inBasketProductData['time']   $expiresAfter) {
            return $inBasketData[$prodKey]['count'];
        }
    }

    $inBasketData[$prodKey] = array(
        'time' => $timeNow,
        'count' => $randomCount
    );

    $_SESSION['randinbasket'] = $inBasketData;
    return $randomCount;
}

Finally, slightly modify your show_no_of_people_added_in_cart() function:

function show_no_of_people_added_in_cart() {
    global $wpdb, $product;
    
    $in_basket = get_random_in_basket(2, 4, $product->get_id(), 60);

    $wc_session_data = $wpdb->get_results( "SELECT session_key FROM {$wpdb->prefix}woocommerce_sessions" );
    ...

If the code above works for your WP, consider increasing the session expiry time from 60 seconds to 86400 seconds (equals 1 day):

$in_basket = get_random_in_basket(2, 4, $product->get_id(), 86400);

UPDATE

There seems to be an error in the code of your function show_no_of_people_added_in_cart() which causes Wordpress to not add/substract 1 from the randomly generated number after you add/remove a product to/from your basket.

In short, this line:

$cart_contents = maybe_unserialize( $session_contents['cart'] );

should store the contents of your basket into a variable, BUT IT STORES NOTHING AT ALL.

To fix this issue we have to replace line above with these 2 lines which actually get the contents of your cart:

global $woocommerce;
$cart_contents = $woocommerce->cart->get_cart();

  • Related