0

I've created a term for the Product_Type taxonomy called "stock_records". And I'd like it to be visible admin only. But they show on front end.

Eventually other posts will refer to the stock_records to show info - but I don't want them to show ANYWHERE frontend - not in catalogue pages, not in search, not in catalogue post counts etc.

Here's the working code to create the custom product type.

/**
 * Register the custom product type stock_record after init
 */
function register_stock_record_product_type() {
    class WC_Product_Stock_Record extends WC_Product {
        public function __construct( $product ) {
            $this->product_type = 'stock_record';
            parent::__construct( $product );
        }
        public function get_type() {
            return 'stock_record';
        }
    }
}
add_action( 'plugins_loaded', 'register_stock_record_product_type' );

/**
 * Add to product type drop down.
 */
function add_stock_record_product( $types ){
    // Key should be exactly the same as in the class
    $types[ 'stock_record' ] = __( 'Stock Record' );
    return $types;
}
add_filter( 'product_type_selector', 'add_stock_record_product' );

/**
 * Show pricing fields for stock record product.
 */
function stock_record_custom_js() {
    if ( 'product' != get_post_type() ) :
        return;
    endif;
    ?><script type='text/javascript'>
        jQuery( document ).ready( function() {
            jQuery( '.options_group.pricing' ).addClass( 'show_if_stock_record' ).show();
            jQuery('.inventory_options').addClass('show_if_stock_record').show();
            jQuery('#inventory_product_data ._manage_stock_field').addClass('show_if_stock_record').show();
            jQuery('#inventory_product_data ._sold_individually_field').parent().addClass('show_if_stock_record').show();
            jQuery('#inventory_product_data ._sold_individually_field').addClass('show_if_stock_record').show();

        });
    </script><?php
}
add_action( 'admin_footer', 'stock_record_custom_js' );

I can hide from catalogue page with this:

function stock_record_is_visible( $variable , $id) {
    $_product = wc_get_product( $id );
    if( $_product->is_type( 'stock_record' ) ) {
        return false;
    }
    return $variable;
}
add_filter( 'woocommerce_product_is_visible', 'stock_record_is_visible',10,2 );

But that still shows in searches.

Here's my latest FAIL to limit using pre_get_posts:

function kisska_query_fix( $query = false ) {
    if(!is_admin()) {   
        $tax_query = $query->get('tax_query', array());

        $tax_query[] = array(
            'taxonomy' => 'product_type',
            'field' => 'slug',
            'terms' => 'stock_record',
            'operator' => 'NOT'
        );

        $query->set('tax_query', $tax_query);
    }
}

add_action( 'pre_get_posts', 'kisska_query_fix' );

How can I best make the taxonomy product_type term stock_record invisible to users? :)

closed as off-topic by Max Yudin, Jacob Peattie, bueltge, Christine Cooper, Jack Johansson Dec 16 '17 at 11:48

This question appears to be off-topic. The users who voted to close gave this specific reason:

If this question can be reworded to fit the rules in the help center, please edit the question.

  • Edit : Can you give a try with woocommerce_product_query instead of pre_get_posts ? – Elex Dec 10 '17 at 13:02
  • Yeah tried woocommerce_product_query - just doesn't seem to change anything. Chanqgeing NOT into 'NOT IN' as Oleg suggested fixed most of it - just the Category post counts to find now! – Sablednah Dec 10 '17 at 15:27
1

First what i see in your "latest FAIL" code you use wrong "operator" (or maybe is just typo). It sholuld work if you change "operator" to 'operator' => 'NOT IN' tax query parameters

UPDATE: for Sablednah comment

You can try to hide this term (and "count") completely by modify WP_Term_Query with something like that:

add_action('pre_get_terms', 'my_pre_get_terms');
function my_pre_get_terms( $query ) {
    if (is_admin())
        return;

    //if you know term_id you can just set it - "$termIdForExclude = 1234567" and skip next piece of code until "if ( isset( $query->query_vars['include'] ) && !empty( $query->query_vars['include'] ) ) {"
    remove_action('pre_get_terms', 'my_pre_get_terms');//avoid infinite loop
    $termForExclude = get_term_by('slug', 'stock_record', 'product_type');
    add_action('pre_get_terms', 'my_pre_get_terms');//avoid infinite loop
    if ( $termForExclude instanceof WP_Term ) {
        $termIdForExclude = $termForExclude->term_id;
    } else {
        return;
    }

    //modify query_vars
    if ( isset( $query->query_vars['include'] ) && !empty( $query->query_vars['include'] ) ) { //if query has include exclude is ignored
        $include = wp_parse_id_list( $query->query_vars['include'] );
        $hasId = array_search( $termIdForExclude, $include );
        if( $hasId ) {
            unset( $include[$hasId] );
        }
        $query->query_vars['include'] = ( is_array($query->query_vars['include']) ) ? $include : implode(', ', $include);
        if( !empty($include) ) {
            return;
        } 
    }

    if ( isset( $query->query_vars['exclude'] ) ) {            
        $exclude = wp_parse_id_list($query->query_vars['exclude']);
        if (!in_array($termIdForExclude, $exclude)) {  
            $exclude[] = $termIdForExclude;
        }
        $query->query_vars['exclude'] = ( is_array($query->query_vars['exclude']) ) ? $exclude : implode(', ', $exclude);
    } else {            
        $query->query_vars['exclude'] = $termIdForExclude;
    }                
}
  • You're right, I thought "not" would work for a single term. Changed to NOT IN and it hides from most places now. But there's one place left... in the Product Categories Widget - It still shows in the category count. I have a category with just one "invisible" in it. The "(1)" shows but the category page shows (correctly) no products. I hoped pre_get_posts would cover "all" checks. – Sablednah Dec 10 '17 at 15:08
  • Please see my update and tell if is work or not – Oleg Dec 10 '17 at 18:46
  • It stopped the previous pre_get_posts from working :/ I'll look around this area for ways to fix tho - it looks like the right area - thanks. – Sablednah Dec 13 '17 at 18:51
  • I apologize. I forgot about the most important add_action('pre_get_terms', 'my_pre_get_terms' ) (See edit). Both hooks should be used - your kisska_query_fix for hide "stock_record" products and this one for hide "stock_record" term in Product Categories Widget and potentially other areas in frontend – Oleg Dec 14 '17 at 1:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.