Add to category but keep current primary category using wp_set_object_terms - woocommerce

I'm using wp_set_object_terms to add product to a category. But the newly added category gets set as primary category which I don't want – this also means that the breadcrumb is changed to contain the new category instead of the old primary category.
My code is like:
wp_set_object_terms( $product_id, $new_category_id, 'product_cat', true);
I did try to remove and re-add the old primary category which I wanted to keep for the breadcrumb:
wp_set_object_terms( $product_id, $new_category_id, 'product_cat', true);
wp_remove_object_terms( $product_id, $old_primary_cat, 'product_cat' );
wp_set_object_terms( $product_id, $old_primary_cat, 'product_cat', true);
But that did not work
How do I add a category but without changing the primary category?
Thanks!

Related

Custom product_cat data

I need to create product_cat with custom data (originalID), so I can identify categories (to add parent later).
I'm trien to create woocommerce categories like this:
$term = wp_insert_term( $name, 'product_cat', array() );
$term = update_term_meta( $term->term_id, 'originalID', $internalID );
Categories are created successful but update_term_meta just returns false and I dont know why.
What am I missing?

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/

Exclude Product Categories from Woocommerce widget

We want to hide/exclude a few specific woocommerce category from the woocommerce shop as well as all pages.
So far we managed to achieve this using code I found on the internet.
The code bellow hide the correct category from the shop page but when we do a search using the woocommerve search, the category are not hidden in the result page.
//Insert excluded category ids here
$excludes = array(3380,3308);
$includes = explode(",",$widget_args['include']);
$includes = array_filter($includes, function($value) use ($excludes) {
return !in_array($value, $excludes);
});
$widget_args["include"] = implode(",", $includes);
return $widget_args;
}
add_filter( 'woocommerce_product_categories_widget_dropdown_args', 'exclude_woocommerce_widget_product_categories');
add_filter( 'woocommerce_product_categories_widget_args', 'exclude_woocommerce_widget_product_categories');
The code bellow does hide the category from the search page but not from the shop page
add_filter( 'woocommerce_product_categories_widget_dropdown_args', 'organicweb_exclude_widget_category');
add_filter( 'woocommerce_product_categories_widget_args', 'organicweb_exclude_widget_category' );
function organicweb_exclude_widget_category( $args ) {
$args['exclude'] = array('15', '3380', '3308' ); // Enter the id of the category you want to exclude in place of '30'
return $args;
}
Could anyone please help me merge the 2 pieces of code together?
Thank you in advance.
Both of the code snippets you posted only hide categories from the widget, it has no effect on hiding the category otherwise. Not 100% on what your goal is, two things seem likely to me:
If you want to Exclude products from a particular category on the shop page do it with below code (does not hide the category, if you selected to show them under Design > Customizer > WooCommerce > Product Catalogue in the backend) as seen in the WooCommerce docs.
/**
* Exclude products from a particular category on the shop page
*/
function custom_pre_get_posts_query( $q ) {
$tax_query = (array) $q->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'clothing' ), // Don't display products in the clothing category on the shop page.
'operator' => 'NOT IN'
);
$q->set( 'tax_query', $tax_query );
}
add_action( 'woocommerce_product_query', 'custom_pre_get_posts_query' );
To actually hide the category itself, do the following as documented here Hide a WooCommerce Category from Shop Page, which does not hide the products of this category.
/**
* Show products only of selected category.
*/
function get_subcategory_terms( $terms, $taxonomies, $args ) {
$new_terms = array();
$hide_category = array( 126 ); // Ids of the category you don't want to display on the shop page
// if a product category and on the shop page
if ( in_array( 'product_cat', $taxonomies ) && !is_admin() && is_shop() ) {
foreach ( $terms as $key => $term ) {
if ( ! in_array( $term->term_id, $hide_category ) ) {
$new_terms[] = $term;
}
}
$terms = $new_terms;
}
return $terms;
}
add_filter( 'get_terms', 'get_subcategory_terms', 10, 3 );

Set Catalog visibility hidden woo-commerce

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)

Categories not appearing in correct hierarchy

When I create a post and try to assign the post to categories, the widget on the right-hand side shows the categories mixed up. For example, when I created the categories, I had the "accessories" category under the parent category "Men", but in the widget it doesn't appear under it; only when I go to category on the left-hand side menu does it appear in the correct order. What is wrong?
In categories I have this hierarchy
but when I assign a post to but when I assign a post to categories for example Men-Accesories-Ties, Men appears second in categories and not first thus messing up the breadcrumbs too
I'll leave the first version of this Answer at the bottom, as it may be useful.
There is no way of organizing that column in a hierarchical way. The solution is to make a custom column and use this Codex snippet:
// Change "post_" for the desired post type
add_filter( 'manage_edit-post_columns', 'custom_categories_register_so_15813936', 20, 1 );
add_action( 'manage_post_posts_custom_column', 'custom_categories_display_so_15813936', 20, 2 );
function custom_categories_register_so_15813936( $columns )
{
$columns[ 'custom-cat' ] = 'Categories';
return $columns;
}
function custom_categories_display_so_15813936( $column_name, $post_id )
{
if ( 'custom-cat' != $column_name )
return;
// get the category IDs assigned to post
$categories = wp_get_post_categories( $post_id, array( 'fields' => 'ids' ) );
// separator between links
$separator = ', ';
if ( $categories ) {
$cat_ids = implode( ',' , $categories );
$cats = wp_list_categories( 'title_li=&style=none&echo=0&include=' . $cat_ids );
$cats = rtrim( trim( str_replace( '<br />', $separator, $cats ) ), $separator );
$cats = str_replace( site_url('category/'), admin_url('edit.php?category_name='), $cats );
echo str_replace( '/" title', '" title', $cats );
}
}
At the left, the default column, and at the right, the custom one.
[first version]
I suppose you are talking about the back-end (/wp-admin). And the behavior you see is WordPress default. To get rid of that "feature", you need the plugin Category Checklist Tree:
On the post editing screen, after saving a post, you will notice that
the checked categories are displayed on top, breaking the category
hierarchy. This plugin removes that "feature".
Additionally, it automatically scrolls to the first checked category.
Works with custom taxonomies too.

Resources