is it possible to add a category to a woocommerce post?
I am creating my products as follows:
// creates woocommerce product
$product = array(
'post_title' => $name,
'post_content' => '',
'post_status' => 'publish',
'post_author' => $current_user->ID,
'post_type' =>'product'
);
// Insert the post into the database
$product_ID = wp_insert_post($product);
I have a category called "Tree" where I have to add the above product to.
I have tried the following but without succes. Is there some special way
to add a category?
wp_set_object_terms($productID, array('Tree'), 'product_cat');
After some trial and error I solved it the following way:
// Creates woocommerce product
$product = array(
'post_title' => $name,
'post_content' => '',
'post_status' => 'publish',
'post_author' => $current_user->ID,
'post_type' =>'product'
);
// Insert the post into the database
$product_ID = wp_insert_post($product);
// Gets term object from Tree in the database.
$term = get_term_by('name', 'Tree', 'product_cat');
wp_set_object_terms($product_ID, $term->term_id, 'product_cat');
reference for more information:
How to programatically set the category for a new Woocommerce Product Creation?
http://codex.wordpress.org/Function_Reference/get_term_by
https://wordpress.stackexchange.com/questions/16394/how-to-get-a-taxonomy-term-name-by-the-slug
If you need multiple categories, just pass an array:
$categories = [ 'Some Category', 'Some other Category' ];
// Overwrite any existing term
wp_set_object_terms( $product_id, $categories, 'product_cat' );
// Or, set last argument to true to append to existing terms
wp_set_object_terms( $product_id, $categories, 'product_cat', true );
Related
Iam using woocommerce Plugin and i created a taxonomy called "brand"
I am creating products manually and i need to set product category and brand .. iam using the below code but its not working in adding categories or brands
$post = array(
'post_author' => 1,
'post_content' => '',
'post_status' => "publish",
'post_title' => $product_name,
'post_parent' => '',
'post_type' => "product",
//'post_category' => 17, // Not working after un comment it
);
$post_id = wp_insert_post( $post, $wp_error );
wp_set_post_categories( $post_id, '17', 'brand', true);
wp_set_post_categories( $post_id, '22', 'product_cat', true);
Product created without assigning to any brand or category how can i fix it ?
i ALso tried
wp_set_object_terms( $post_id, 'electronics', 'product_cat' );
and tried
wp_set_post_terms( $post_id, 'electronics', 'product_cat' );
But both not working too
wp_set_post_categories doesn't accept custom taxonomy, it will save to regular post category https://developer.wordpress.org/reference/functions/wp_set_post_categories/#source
This works for saving into Woocommmerce category, I just used it for my needs. Be sure to check that params are integers, not strings like so "10"
$product_id = 10;
$product_category_id = 25;
wp_set_object_terms($product_id, array($product_category_id), 'product_cat')
I'm writing some code to modify the related products section as follows:
If a product has cross sell products, show those first, and fill up to 4 total products with others from the same category*
Or
If a product has no cross sell products, show 4 products from the same category*
Here's my function to filter the related products so far:
add_filter( 'woocommerce_related_products', 'fivem_add_linked_to_related_products', 9999, 3 );
function fivem_add_linked_to_related_products( $related_posts, $product_id, $args ) {
$product = wc_get_product( $product_id );
$cross_sell_ids = $product->get_cross_sell_ids();
$product_categories = $product->get_category_ids();
// Get cross sell products
$cross_sell_products = get_posts( array(
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'post__in' => $cross_sell_ids,
'posts_per_page' => 4,
'exclude' => array( $product_id ),
));
// Calculate how many filler products are needed
$category_product_count = 4 - count( $cross_sell_products );
// Exclude main product and cross sell products
$excluded_products = array_push( $cross_sell_ids, $product_id );
// Get filler products from same category
$category_products = get_posts( array(
'post_type' => 'product',
'post_status' => 'publish',
'orderby' => 'rand',
'fields' => 'ids',
'post__not_in' => $excluded_products,
'posts_per_page' => $category_product_count,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $product_categories,
'operator' => 'IN',
)
)
));
// Merge cross sell products with filler products
$related_products = array_merge( $cross_sell_products, $category_products );
// Return related products
return $related_products;
}
Currently, the above code mostly works.
If cross-sells are set, it only displays those cross-sell products- ie. does not fill out to 4 total
If no cross-sells are set, it displays products from the same category as expected.
There are two problems I'm trying to solve:
Code above doesn't fill with category products. If I remove the post__not_in and tax_query arguments, it fills out, but obviously not with products from the same category.
I want to show cross-sell products first, then the category-related products. There appears to be another randomization somewhere that mixes the order up, and I can't work out where that comes from.
Any ideas how I can fix this? Thanks in advance.
Code contains
If a product has cross sell products, show those first, and fill up to 4 total products with others from the same category
If a product has no cross sell products, show 4 products from the same category
function filter_woocommerce_related_products( $related_posts, $product_id, $args ) {
// Taxonomy
$taxonomy = 'product_cat';
// Show products
$show_products = 4;
// Get product
$product = wc_get_product( $product_id );
// Get cross sell IDs
$cross_sell_ids = $product->get_cross_sell_ids();
// Calculate how many filler products are needed
$category_product_needed_count = $show_products - count( $cross_sell_ids );
// If category product needed
if ( $category_product_needed_count >= 1 ) {
// Retrieves product term ids for a taxonomy.
$product_cats_ids = wc_get_product_term_ids( $product_id, $taxonomy );
// Get product id(s) from a certain category, by category-id
$product_ids_from_cats_ids = get_posts( array(
'post_type' => 'product',
'numberposts' => $category_product_needed_count,
'post_status' => 'publish',
'fields' => 'ids',
'tax_query' => array(
array(
'taxonomy' => $taxonomy,
'field' => 'id',
'terms' => $product_cats_ids,
'operator' => 'IN',
)
),
));
// Merge array
$related_posts = array_merge( $cross_sell_ids, $product_ids_from_cats_ids );
} else {
// Slice array until show products
$related_posts = array_slice( $cross_sell_ids, 0, $show_products );
}
// Return
return $related_posts;
}
add_filter( 'woocommerce_related_products', 'filter_woocommerce_related_products', 10, 3 );
// Order by
function filter_woocommerce_output_related_products_args( $args ) {
$args['orderby'] = 'id';
$args['order'] = 'ASC';
return $args;
}
add_filter( 'woocommerce_output_related_products_args', 'filter_woocommerce_output_related_products_args', 10, 1 );
I want that I have some product categories on one page when I click on them, then I should get her child's categories. and I want that this work should be complete on the single page not more than pages
How can i do this work
Simply add your parent term_id in your get_terms query to fetch all its children as follows -
$cat_args = array(
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false,
'parent' => $parent_term_id, // set your parent term id
);
$child_categories = get_terms( 'product_cat', $cat_args );
// since wordpress 4.5.0
$cat_args = array(
'taxonomy' => "product_cat",
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false,
'parent' => $parent_term_id, // set your parent term id
);
$child_categories = get_terms($cat_args);
It will returns all childs terms objects
You can use WordPress dedicated function get_term_children() from a product category term Id:
$child_terms_ids = get_term_children( $term_id, 'product_cat' );
It return a array of children terms Ids.
For product category archive pages, you can use:
// get the current product category term ID
if ( is_product_category() ) {
$term_id = (int) get_queried_object_id();
}
if ( term_exists( $term_id, 'product_cat' ) ) {
$child_terms_ids = get_term_children( $term_id, 'product_cat' );
// Loop through child terms Ids
foreach ( $child_terms_ids as $child_term_id ) {
$child_term = get_term_by( 'term_id', $child_term_id, 'product_cat' );
// The term name
$child_name = $child_term->name;
// The term link
$child_link = get_term_link( $child_term, 'product_cat' );
}
}
I am trying to add new portfolio pragmatically When I add new category in WooCommerce.
My code is :
function programmatically_create_post() {
$author_id = 1;
$taxonomy = 'product_cat';
$orderby = 'id';
$show_count = 0; // 1 for yes, 0 for no
$pad_counts = 0; // 1 for yes, 0 for no
$hierarchical = 1; // 1 for yes, 0 for no
$title = '';
$empty = 0;
$args = array(
'taxonomy' => $taxonomy,
'orderby' => $orderby,
'show_count' => $show_count,
'pad_counts' => $pad_counts,
'hierarchical' => $hierarchical,
'title_li' => $title,
'hide_empty' => $empty
);
$all_categories = get_categories( $args );
$lastCategory=end($all_categories);
$slug =$lastCategory->slug;
$title=$lastCategory->name;
$thumbnail_id= get_post_thumbnail_id($lastCategory->id );
// If the page doesn't already exist, then create it
if( null == get_page_by_title( $title ) ) {
// Set the post ID so that we know the post was created successfully
$post_id = wp_insert_post(
array(
'post_author' => $author_id,
'post_name' => $slug,
'post_title' => $title,
'post_status' => 'publish',
'post_type' => 'us_portfolio',
'post_parent' =>11,
'page_template' =>'custumcat.php',
'post_slug'=> $slug
)
);
update_post_meta($post_id, '_wp_page_template', 'custumcat.php' );
update_post_meta( $post_id, '_thumbnail_id', $thumbnail_id );
// Otherwise, we'll stop
} else {
// Arbitrarily use -2 to indicate that the page with the title already exists
$post_id = -2;
} // end if
} // end programmatically_create_post
add_action('create_product_cat', 'programmatically_create_post', 10,2);
I want set portfolio thumbnail from category thumbnail, and
I have used $thumbnail_id= get_post_thumbnail_id($lastCategory->id );for get category thumbnail.
After that I used update_post_meta( $post_id, '_thumbnail_id', $thumbnail_id ); to set portfolio's thumbnail.
But it doesn't set anything.
How can I fix it?
Update 2.1
I have been testing the code below and I got the correct $thumbnail_id with no errors:
$categories = get_categories( array(
'taxonomy' => 'product_cat',
'orderby' => 'id',
'show_count' => 0,
'pad_counts' => 0,
'hierarchical' => 1,
'title_li' => '',
'hide_empty' => 0
) );
$last_cat = end($categories); // last category
$last_cat_term_id = $last_cat->term_id; // Value is
$thumbnail_id = get_woocommerce_term_meta( $last_cat_term_id, 'thumbnail_id', true );
echo 'Term ID is: ' . $last_cat_term_id . '<br>';
echo 'Thumbnail ID is: ' . $thumbnail_id;
It displays the last category (with this data related to my product categories settings):
Term ID is: 48
Thumbnail ID is: 443
And here the corresponding screenshot of the DB table "wp_termmeta":
So this is tested and works.
This time, update_post_meta( $post_id, '_thumbnail_id', $thumbnail_id ); will set correctly a value.
…
Update 1:
Product categories are a WordPress custom taxonomy that uses WP_terms…
This doesn't work because $lastCategory->id doesn't exist (and output a null value):
$thumbnail_id= get_post_thumbnail_id($lastCategory->id );
Instead you need to use $lastCategory->term_id that will work with WP_Term object and get_woocommerce_term_meta() this way:
$thumbnail_id= get_woocommerce_term_meta( $lastCategory->term_id, 'thumbnail_id', true );
The WP_Term object properties are:
term_id
name
slug
term_group
term_taxonomy_id
taxonomy
description
parent
count
Related to product category term: WooCommerce get attribute thumbnail - Variation Swatches and Photos plugin
First of all, a WooCommerce product category is a taxonomy, not a post, so you cannot use the function get_post_thumbnail_id() on it.
Instead, you can use something like this:
$thumbnail_id = get_woocommerce_term_meta( $term_id, 'thumbnail_id', true );
Second, since your programmatically_create_post function is a hook for create_product_cat, when invoked, it receives 2 parameters: $term_id and $term_taxonomy_id.
There is no need to look up the just created product category via all these lines (get_categories() shouldn't even work, because you work with product categories here, not regular post categories):
$all_categories = get_categories( $args );
$lastCategory=end($all_categories);
when you can simply declare your function like
function programmatically_create_post($term_id, $tt_id) {...}
then simply make use of the $term_id parameter:
$lastCategory = get_term($term_id, 'product_cat');
Make sure you also use $term_id instead of $lastCategory->id.
get_woocommerce_term_meta is deprecated since version 3.6
`Use get_term_meta instead.
get_term_meta( int $term_id, string $key = '', bool $single = false )
Codex reference documentation
I have the following code and I need to display order data based on seller id or seller name:
$filters = array(
'post_status' => 'published',
'post_type' => 'shop_order',
'posts_per_page' => 200,
'paged' => 1,
'orderby' => 'modified',
'order' => 'ASC',
'author' => $seller_id,
'post_parent' => $order_id
);
$loop = new WP_Query($filters);
while ($loop->have_posts()) {
$loop->the_post();
$order = new WC_Order($loop->post->ID);
foreach ($order->get_items() as $key => $item)
{
$red = $item['product_id'];
$_sku = get_post_meta( $red, '_sku', true );
}
}
The above loop is not showing any sku or price on the invoice section.
How to display order details on author ID (or seller name)?
Thanks
Your main problem is the post_status here: For WooCommerce Orders "published" post_status doesn't exist. The available status for WooCommerce Orders are for example:
'wc-cancelled'
'wc-completed'
'wc-custom-status'
'wc-on-hold'
'wc-pending'
'wc-processing'
'wc-refunded'
You can have different order statuses in an array…
Also 'post_parent' is can't be the order ID as it always have a 0 value
To finish since WooCommerce 3+ Order items are now a WC_Order_Item_Product object (and you need to use available methods to access the properties values).
Last thing, to get the user ID from the user name, you can use WordPress function get_user_by().
So your code will be:
$args = array(
'post_status' => array( 'wc-completed' ), // <=== HERE
'post_type' => 'shop_order',
'posts_per_page' => 200,
'paged' => 1,
'orderby' => 'modified',
'author' => $seller_id
);
$loop = new WP_Query($args);
while ($loop->have_posts()) {
$loop->the_post();
$order_obj = wc_get_order($loop->post->ID);
foreach ($order_obj->get_items() as $item_id => $item_obj)
{
$item_data = $item_obj->get_data(); // Accessing WC_Order_Item_Product object protected data
$product_id = $item_data['product_id']; // Product ID
$product_sku = get_post_meta( $product_id, '_sku', true ); // SKU
// Just for Testing output
echo "Product ID is $product_id - Sku is $product_sku<br>";
}
}
This code is tested and works for WooCommerce 3+
Helpful Answer: How to get WooCommerce order details