Set Catalog visibility hidden woo-commerce - wordpress

How to set Catalog visibility hidden in woo-commerce WordPress programmatically?
Like its mentioned here :
https://docs.woothemes.com/document/catalog-visibility-options/
But i can't find any hook or hack, that how to do it in PHP.

I have tried doing this for some days, and there is nothing about it online so I read the woocommerce documentation and discovered that in woocommerce 3.x.x the visibility is a taxonomy called "product_visibility".
To achieve that you should set taxonomy terms, for example:
//Set product hidden:
$terms = array( 'exclude-from-catalog', 'exclude-from-search' );
wp_set_object_terms( $post_id, $terms, 'product_visibility' );
//Set product visible in catalog:
$terms = 'exclude-from-search';
wp_set_object_terms( $post_id, $terms, 'product_visibility' );
//Set product visible in search:
$terms = 'exclude-from-catalog';
wp_set_object_terms( $post_id, $terms, 'product_visibility' );
All possible taxonomy terms:
"exclude-from-catalog"
"exclude-from-search"
"featured"
"outofstock"

The visibility is set in the custom field _visibility. You can change it with update_post_meta():
update_post_meta( $product_id, '_visibility', '_visibility_hidden' );
Possible values:
visible (Catalog & Search)
catalog (Catalog only)
search (Search only)
hidden (nowhere)

Related

How do I remove a taxonomy from one post?

With
wp_set_object_terms($postId, $termsList, $taxonomy, true );
I set taxonomy on my posts (products for woocommerce, from an external feed).
How I can remove the taxonomy for one post, when termsList is empty?
if( empty( $termsList) ){
wp_remove_object_terms( $postId, 'term-to-remove', $taxonomy );
}
https://developer.wordpress.org/reference/functions/wp_remove_object_terms/

How to add another Add To Cart and product variant selection in Woocommerce

How can I add another add to cart button as well as product variant selection above product description in my Woocommerce product page?
This will add another variable product selector above the short description. For simple products they will remain unchanged. This code was taken from the function woocommerce_variable_add_to_cart which I have basically copied and just removed the wp_enqueue_script call as this is already included in the usual variation selector already present. Paste this code into your theme's functions.php file.
function add_product_variation_selector() {
global $product;
// Enqueue variation scripts.
//wp_enqueue_script( 'wc-add-to-cart-variation' );
if( $product->is_type( 'variable' ) ) :
// Get Available variations?
$get_variations = count( $product->get_children() ) <= apply_filters( 'woocommerce_ajax_variation_threshold', 30, $product );
// Load the template.
wc_get_template( 'single-product/add-to-cart/variable.php', array(
'available_variations' => $get_variations ? $product->get_available_variations() : false,
'attributes' => $product->get_variation_attributes(),
'selected_attributes' => $product->get_default_attributes(),
) );
endif;
}
add_action( 'woocommerce_single_product_summary', 'add_product_variation_selector', 9 );
Clone the plugins/woocommerce/templates/content-single-product.php to your theme following the instructions from the file.
Change it according to your needs.

Get WooCommerce products on sale with WC_Query

I know there are plenty of solutions on the internet about how to get WooCommerce products on sale, by doing a WP_Query. However, WooCommerce doesn't seem to work fully if it's WC_Query object is not populated. For example: filter or sorting
Both these templates call:
woocommerce_products_will_display()
Which check's to see if the page is a taxonomy page (obvious false if you're using your own custom template):
if ( ! is_product_taxonomy() ) return false;
This is an example of a simple solution if you just want the products: WooCommerce: Display ONLY on-sale products in Shop
So, I there seems to be a couple of issues I need to solve here:
1) How to tell WC that my "Sale" page is a taxonomy page? Is there some sort of trick I need to do to force it into a taxonomy?
2) How do I get get WC_Query filled with the sales query (rather than just the WP_Query)
I have plugins that depend on:
$woocommerce->query->layered_nav_product_ids
being populated.
Any help is appreciated!
Thanks!!!
Well woocommerce_products_will_display() is pluggable, meaning you can define it in your own functions.php (or site-specific plugin) and alter it, having it return true for your specific template/page.
I think it could stand for some tweaking and a filter.
EDIT
I played around with this a bit more. Typically changing the posts that you want to retrieve is done in the pre_get_posts hook. I took a look at what WooCommerce is doing. They are adding something to the pre_get_posts hook and calling their special query stuff from there.
But their special query stuff dies if you aren't on a WooCommerce page. So, it made me thing that maybe we could just call it ourselves from our own function. I put this together and coupled with a special page template for a page called "on-sale" (basically just a copy of the shop template), seems to show just the for sale items with proper sorting and pagination.
Your mileage may vary, but I hope it helps.
function kia_pre_get_posts( $q ){
// We only want to affect the main query
if ( ! $q->is_main_query() ) {
return;
}
// Fix for verbose page rules
if ( is_page('on-sale') ) {
$q->set( 'post_type', 'product' );
$q->set( 'page_id', '' );
$q->set( 'page', '' );
$q->set( 'pagename', '' );
$meta_query = array( array(
'key' => '_sale_price',
'value' => 0,
'compare' => '>'
) );
$q->set( 'meta_query', $meta_query );
if ( isset( $q->query['paged'] ) ) {
$q->set( 'paged', $q->query['paged'] );
}
// Fix conditional Functions
$q->is_archive = true;
$q->is_post_type_archive = true;
$q->is_singular = false;
$q->is_page = false;
}
$wc_query = WC()->query;
$wc_query->product_query( $q );
if ( is_search() ) {
add_filter( 'posts_where', array( $wc_query, 'search_post_excerpt' ) );
add_filter( 'wp', array( $wc_query, 'remove_posts_where' ) );
}
add_filter( 'posts_where', array( $wc_query, 'exclude_protected_products' ) );
// We're on a shop page so queue the woocommerce_get_products_in_view function
add_action( 'wp', array( $wc_query, 'get_products_in_view' ), 2);
// And remove the pre_get_posts hook
$wc_query->remove_product_query();
}
add_action( 'pre_get_posts', 'kia_pre_get_posts' );

Woocommerce remove meta boxes

I want to remove some meta boxes like:
Product Short description,
Reviews
I can remove default metaboxes:
function remove_metaboxes() {
remove_meta_box( 'postcustom' , 'product' , 'normal' );
remove_meta_box( 'postexcerpt' , 'product' , 'normal' );
remove_meta_box( 'commentsdiv' , 'product' , 'normal' );
remove_meta_box( 'tagsdiv-product_tag' , 'product' , 'normal' );
}
add_action( 'admin_menu' , 'remove_metaboxes' );
But I cant remove "postexcerpt" - Product Short description and "commentsdiv" - Reviews, because they are loaded in add_filter - add_meta_boxes
Is there any other hook after this to apply my script ? Or maybe there is another method ?
Thank you!
WooCommerce removes the default postexcerpts and replaces it with its own version (the 'Product Short Description' meta box) (class-wc-admin-meta-boxes.php)
So like user1139767 said, you have to alter the priority. However when I tried 11, it didn't work, neither did 20. But 50 seems to do the trick:
function remove_metaboxes() {
remove_meta_box( 'postcustom' , 'product' , 'normal' );
remove_meta_box( 'postexcerpt' , 'product' , 'normal' );
remove_meta_box( 'commentsdiv' , 'product' , 'normal' );
remove_meta_box( 'tagsdiv-product_tag' , 'product' , 'normal' );
}
add_action( 'add_meta_boxes' , 'remove_metaboxes', 50 );
function remove_my_metaboxes() {
remove_meta_box( 'categorydiv','post','normal' ); // Categories Metabox
remove_meta_box( 'submitdiv','post','normal' ); // Categories Metabox
remove_meta_box( 'postcustom','page','normal' ); // Custom Fields Metabox
remove_meta_box( 'postcustom','post','normal' ); // Custom Fields Metabox
remove_meta_box( 'commentstatusdiv','page','normal' ); // Comments Metabox
remove_meta_box( 'commentsdiv','post','normal' ); // Comments Metabox
remove_meta_box( 'trackbacksdiv','page','normal' ); // Talkback Metabox
remove_meta_box( 'trackbacksdiv','post','normal' ); // Trackback Metabox
remove_meta_box( 'authordiv','page','normal' ); // Author Metabox
remove_meta_box( 'authordiv','post','normal' ); // Author Metabox
remove_meta_box( 'postexcerpt','post','normal' ); // Excerpt Metabox
remove_meta_box( 'postexcerpt','page','normal' ); // Excerpt Metabox
remove_meta_box( 'revisionsdiv','post','normal' ); // Revisions Metabox
remove_meta_box( 'slugdiv','page','normal' ); // Slug Metabox
remove_meta_box( 'slugdiv','post','normal' ); // Slug Metabox
remove_meta_box( 'formatdiv','post','normal' ); // Formats Metabox
remove_meta_box( 'postimagediv','post','normal' ); // Featured Image Metabox
remove_meta_box( 'tagsdiv-post_tag','post','normal' ); // Tags Metabox
remove_meta_box( 'commentstatusdiv','post','normal' ); // Comments Status Metabox
}
add_action('admin_menu','remove_my_metaboxes');
just comment out "remove_meta_box" what you want to display in your page/posts.
Also we able to remove the meta boxes by changing on your custom post types name into the remove_meta_box function instead of "post" or "page".
remove_meta_box( 'tagsdiv-product_tag' , 'product' , 'normal' );
isn't correct, use instead :
remove_meta_box( 'tagsdiv-product_tag','product','side' );
to remove the box 'keywords product'
just added priority to add_action:
add_action( 'add_meta_boxes' , 'remove_metaboxes', 11 );
The default priority is 10, so I added 11 to make action after 10.
To remove WooCommerce product categories metabox, add this to functions.php:
add_action('add_meta_boxes_product', 'bbloomer_remove_metaboxes_edit_product', 9999);
function bbloomer_remove_metaboxes_edit_product()
{
// e.g. Remove WooCommerce product categories metabox
remove_meta_box('product_catdiv', 'product', 'normal');
}
I spent hours on this to remove the WooCommerce short description metabox (and then add it up above the main content editor). I could ONLY get rid of the postexcerpt by using the add_meta_boxes hook. admin_menu and adminhead ran too early. So I removed everything else at the same time.
function WH_remove_meta_boxes() {
remove_meta_box( 'postexcerpt', 'product', 'normal' );
remove_meta_box( 'tagsdiv-product_tag', 'product', 'side' );
remove_meta_box( 'tagsdiv-yith_shop_vendor', 'product', 'side' );
remove_meta_box( 'tagsdiv-product_tag', 'product', 'side' );
remove_meta_box( 'wpseo_meta', 'product', 'normal');
}
add_action( 'add_meta_boxes', 'WH_remove_meta_boxes', 99 );

Display custom meta box to the admin sidebar not working

I created a custom meta box to display some content inside the post display in the admin area and want it to show in the sidebar instead of below the wysiwyg editor. I added "side" to the context but nothing happens! I've been playing with this for many hours and haven't had any luck.
This is my code:
function add_custom_meta_box() {
add_meta_box (
'custom_meta_box',
'Custom Meta Box Title',
'show_custom_meta_box',
'post',
'side',
'high'
);
}
add_action('add_meta_boxes', 'add_custom_meta_box');
function show_custom_meta_box() {
// here i have all the code
}
Adapted from this Q&A, the following will force the custom meta box into the second position in the side column.
Check the comments and note the caveat for admin_init.
It only works if the user hasn't rearranged the positions himself. When registering a new user, the position is set for him, as the hooks admin_init and user_register are attached to the same callback function.
// This fires at **every** page load, a better hook must be found
add_action( 'admin_init', 'set_user_metaboxes_so_14183498' );
// This fires when a new user is created
add_action( 'user_register', 'set_user_metaboxes_so_14183498' );
function set_user_metaboxes_so_14183498( $user_id = null )
{
// This is the metakey we will need to update
$meta_key = 'meta-box-order_post';
// So this can be used without hooking into user_register
if( !$user_id )
$user_id = get_current_user_id();
// Set the default order if it has not been set yet by the user.
// These are WP handles, PLUS our custom meta box handle
if ( ! get_user_meta( $user_id, $meta_key, true ) )
{
$meta_value = array(
'side' => 'submitdiv,custom_meta_box,formatdiv,postimagediv',
'normal' => 'postcustom,commentsdiv,slugdiv,revisionsdiv',
'advanced' => '',
);
update_user_meta( $user_id, $meta_key, $meta_value );
}
}

Resources