Search code examples
phparrayswordpresswoocommercewordpress-shortcode

Preventing the display of duplicate products in the WordPress shortcode and requesting code correction


I have a question following my previous questions: Problem in displaying the WordPress shortcode function randomly and Calling multiple variables integrated with HTML in PHP arrays

As I asked in my previous question, I want to prevent duplicate shortcode content from appearing on my content page (for example, I may use this shortcode 5 times in an article and I don't want to have duplicate content in those 5 times. And Even if I had a total of 4 products and had used this shortcode 5 times and one less product would display an alternative text instead of displaying a duplicate product) and the codes of my previous question were correct, but now I want to integrate the values of the products in my previous code and the code What I wrote below is not correct because sometimes it displays duplicate products (I use these short codes in WordPress posts)

My code:

function get_product_id() {
    $args = array(
        'limit' => -1,
        'status' => 'publish',
        'return' => 'ids',
    );
    $all_products = wc_get_products( $args );
    $key = array_rand($all_products);
    $products_id = $all_products[$key];
    return $products_id;
}

function my_shortcode() {
    $products_id = get_product_id();
    $product = wc_get_product( $products_id );
    $product_price = $product->get_price();           
    $product_sale_price = $product->get_sale_price(); 
    $product_regular_price = $product->get_regular_price();
    if (isset($product_price) && $product_price > 0) {
        $product_price = number_format($product_price);  
    }
    if (isset($product_sale_price) && $product_sale_price > 0) {
        $product_sale_price = number_format($product_sale_price);  
    }
    if (isset($product_regular_price) && $product_regular_price > 0) {
        $product_regular_price = number_format($product_regular_price); 
    }
    $product_price_currency_symbol = get_woocommerce_currency_symbol();
    $image_id  = $product->get_image_id();
    $product_image = wp_get_attachment_image_url( $image_id, 'full' );  
    $product_title = $product->get_title();
    $product_link = $product->get_permalink();
    $discount = '';
    if ( $product->is_on_sale() ) {
        $max_percentage = 0;

        $percentage = 0;

        $price = $product->get_regular_price();
        $sale = $product->get_sale_price();

        if ( $price != 0 && ! empty( $sale ) ) {
            $percentage = ( $price - $sale ) / $price * 100;
        }
        if ( $percentage > $max_percentage ) {
            $max_percentage = $percentage;
        }
        
        if ($max_percentage <> 0) {
            $discount = '<div class="saved-sale">-' . round($max_percentage) . '% Off</div>';
        }
    } else {
        $product_regular_price = '';
    }
    
    
    $values = [
        '1' => '
            <a href="' . $product_link . '">
                <img src="' . $product_image . '">
                <span> '. $discount .' </span>
                <span> ' . $product_title . ' </span>
            </a>    
        ',
    ];

    if ( ! isset( $GLOBALS['my_shortcode_used'] ) ) {
        $GLOBALS['my_shortcode_used'] = [];
    }

    $post_id = get_the_ID();

    if ( ! isset( $GLOBALS['my_shortcode_used'][ $post_id ] ) || ! is_array( $GLOBALS['my_shortcode_used'][ $post_id ] ) ) {
        $GLOBALS['my_shortcode_used'][ $post_id ] = [];
    }

    $unused_values = array_diff( $values, $GLOBALS['my_shortcode_used'][ $post_id ] );

    if ( empty( $unused_values ) ) {
        $GLOBALS['my_shortcode_used'][ $post_id ] = [];
        $unused_values = $values;
    }

    $key = array_rand( $unused_values );

    $GLOBALS['my_shortcode_used'][ $post_id ][] = $unused_values[ $key ];

    return $unused_values[ $key ];
}
add_shortcode('jock', 'my_shortcode');

Is this code correct and standard? If not, please tell me where the problem is and what changes should I make.

Is there a solution that does not require me to repeat the arrays inside $values several times?


Solution

  • I have reviewed your code and you maintain a global array $GLOBALS['my_shortcode_used'] to track which products have already been shown in the post.

    I have revised your code please check:

    function get_product_id() {
        $args = array(
            'limit' => -1,
            'status' => 'publish',
            'return' => 'ids',
        );
        $all_products = wc_get_products( $args );
    
        $post_id = get_the_ID();
        $used_products = isset($GLOBALS['my_shortcode_used'][$post_id]) ? $GLOBALS['my_shortcode_used'][$post_id] : [];
    
        $unused_products = array_diff($all_products, $used_products);
    
        if(empty($unused_products)) {
            return null;
        }
    
        $key = array_rand($unused_products);
        $product_id = $unused_products[$key];
    
        $GLOBALS['my_shortcode_used'][$post_id][] = $product_id;
    
        return $product_id;
    }
    
    function my_shortcode() {
        $products_id = get_product_id();
        
        if(!$products_id) {
            return "All products ";  
        }
    
        $product = wc_get_product( $products_id );
        $product_price = $product->get_price();           
        $product_sale_price = $product->get_sale_price(); 
        $product_regular_price = $product->get_regular_price();
        
        if (isset($product_price) && $product_price > 0) {
            $product_price = number_format($product_price);  
        }
        if (isset($product_sale_price) && $product_sale_price > 0) {
            $product_sale_price = number_format($product_sale_price);  
        }
        if (isset($product_regular_price) && $product_regular_price > 0) {
            $product_regular_price = number_format($product_regular_price); 
        }
        
        $product_price_currency_symbol = get_woocommerce_currency_symbol();
        $image_id  = $product->get_image_id();
        $product_image = wp_get_attachment_image_url( $image_id, 'full' );  
        $product_title = $product->get_title();
        $product_link = $product->get_permalink();
        $discount = '';
        
        if ($product->is_on_sale()) {
            $max_percentage = 0;
            $percentage = 0;
            $price = $product->get_regular_price();
            $sale = $product->get_sale_price();
            if ($price != 0 && ! empty($sale)) {
                $percentage = ($price - $sale) / $price * 100;
            }
            if ($percentage > $max_percentage) {
                $max_percentage = $percentage;
            }
            if ($max_percentage <> 0) {
                $discount = '<div class="saved-sale">-' . round($max_percentage) . '% Off</div>';
            }
        } else {
            $product_regular_price = '';
        }
        
        $output = '
            <a href="' . $product_link . '">
                <img src="' . $product_image . '">
                <span> '. $discount .' </span>
                <span> ' . $product_title . ' </span>
            </a>';
    
        if ( ! isset( $GLOBALS['my_shortcode_used'] ) ) {
            $GLOBALS['my_shortcode_used'] = [];
        }
    
        $post_id = get_the_ID();
    
        if ( ! isset( $GLOBALS['my_shortcode_used'][ $post_id ] ) || ! is_array( $GLOBALS['my_shortcode_used'][ $post_id ] ) ) {
            $GLOBALS['my_shortcode_used'][ $post_id ] = [];
        }
    
        $values = ['1' => $output]; 
    
        $unused_values = array_diff( $values, $GLOBALS['my_shortcode_used'][ $post_id ] );
    
        if ( empty( $unused_values ) ) {
            return "Alternative text";
        }
    
        $key = array_rand( $unused_values );
    
        $GLOBALS['my_shortcode_used'][ $post_id ][] = $unused_values[ $key ];
    
        return $unused_values[ $key ];
    }
    add_shortcode('jock', 'my_shortcode');