0

I have created a custom field true/false, and I want when true is selected in a product not to be displayed in the eshop. I want to insert the code inside the functions.php

example

if ( in_array( 'subscriber', (array) $user->roles ) || !is_user_logged_in()  ) {

$postid = get_the_ID();
$prd_only_for_Customers = get_field('prd_clients', $postid); // The ACF true/false field }

Can anyone help ?

  • Your question is incomplete. Can you include more details on your variables and more of the function, so that someone could recreate this on a test environment? [mre] – Howard E Apr 14 '22 at 09:41

2 Answers2

0

As Howard said your question is incomplete but you can use the following method to set product hidden.

You can use pre_get_posts hook in your functions.php. Since Woocommerce 3 the products visibility is now handled by the 'product_visibility' custom taxonomy for the terms 'exclude-from-catalog' and 'exclude-from-search'… See this thread or this one too.

So you should use instead the WC_Product CRUD setter methods set_catalog_visibility() this way:

function get_post_ids_by_meta_key_and_value($key, $value) {
    global $wpdb;

    $meta = $wpdb->get_results("SELECT post_id FROM `".$wpdb->postmeta."` WHERE meta_key='".$wpdb->escape($key)."' AND meta_value='".$wpdb->escape($value)."'");

    $post_ids = [];
    foreach( $meta as $m ) {
        $post_ids[] = $m->post_id;
    }

    return $post_ids;
}


add_action('pre_get_posts', function( $query ){
    if ( $query->is_main_query() && is_woocommerce() && !is_user_logged_in() ) {
        $product_ids = get_post_ids_by_meta_key_and_value('prd_clients', 1);
        foreach($product_ids as $id){
            // Get an instance of the product
            $product = wc_get_product($id);
            // Change the product visibility
            $product->set_catalog_visibility('hidden');
            // Save and sync the product visibility
            $product->save();
        }
    }
});

This code isn't tested, let me know if it worked or you faced any problem.

Muhammad Ahmad
  • 191
  • 1
  • 7
  • I think the code you've written is what I'm looking for. But the problem is that the product that has prd_clients set as true still appears in the directory. Also i checked to find why its not hiding it and i found that inside the if statement when i echo $prd_only_for_Customers; i dont get back anything –  Apr 14 '22 at 12:08
  • Outside of the second if statement when i make `echo '
    ';
    var_dump($postid);
    var_dump($prd_only_for_Customers);
    echo '
    '; ` i get : `bool(false) NULL`
    –  Apr 14 '22 at 12:41
  • The issues was in `$postid`. I updated the code please check. – Muhammad Ahmad Apr 14 '22 at 17:37
0

This is my final code if anyone needs something like this

// Specific products show only for Customer and administrator role
add_action('pre_get_posts', function( $query ){
    
    $user = wp_get_current_user();

    if ( $query->is_main_query() && is_woocommerce()) {
        if (!check_user_role(array('customer','administrator')) || !is_user_logged_in() ) {
            $product_ids = get_post_ids_by_meta_key_and_value('prd_clients', 1);
            foreach($product_ids as $id){
                // Get an instance of the product
                $product = wc_get_product($id);
                // Change the product visibility
                $product->set_catalog_visibility('hidden');
                // Save and sync the product visibility
                $product->save();
            }
        }
        else{
            $product_ids = get_post_ids_by_meta_key_and_value('prd_clients', 1);
            foreach($product_ids as $id){
                // Get an instance of the product
                $product = wc_get_product($id);
                // Change the product visibility
                $product->set_catalog_visibility('visible');
                // Save and sync the product visibility
                $product->save();
            }
        }
        
    }
    
});