in_category() self defined $post->ID - wordpress

I have this code:
function add_cert_id_to_notes( $order_id ) {
$order = new WC_Order( $order_id );
$products = $order->get_items();
foreach( $products as $product ){
$product_id = $product['product_id'];
$order->add_order_note( 'First Test: '.$product_id, 0 );
if( in_category('188', $product_id)){
$order->add_order_note( 'Second Test: '.$product_id, 0 );
}
else {
$order->add_order_note( 'Second Test: FAIL', 0 );
}
}
}
Using WooCommerce, but that's not the problem. The issue is with in_category(). I'm not doing this is a standard loop, I've defined my post ID with $product_id.
Problem is, it keeps returning the failure notice I have set up. I've tried with both the category ID and slug and I still get nothing.

I think in_category is only for post's category.
Document says The given categories are checked against the post's categories' term_ids, names and slugs. So it only check for post i think.
Try following function:-
function add_cert_id_to_notes( $order_id )
{
$order = new WC_Order( $order_id );
$products = $order->get_items();
foreach( $products as $product )
{
$categories = array();
$product_id = $product['product_id'];
$order->add_order_note( 'First Test: '.$product_id, 0 );
$terms = wp_get_post_terms( $product_id, 'product_cat' );
foreach ( $terms as $term )
{
$categories[] = $term->term_id;
$categories[] = $term->slug;
}
//if you want to check category slug than you also can use `slug` as $your_cat_id.
//`$term->slug` is also in $categories array..
$your_cat_id = '188';
if ( in_array( $your_cat_id, $categories ) )
{
$order->add_order_note( 'Second Test: '.$product_id, 0 );
} else {
$order->add_order_note( 'Second Test: FAIL', 0 );
}
}
}
I have tested this function and its working...Hope it will work for you..

Related

How to add ACF field to custom column on WooCommerce admin orders list

ACF is set up for post type on WooCommerce products. However, I am trying to add a custom column to WooCommerce orders list within Admin dashboard and add the products ACF field.
I have added the column to display after order_status, but I'm having problems getting the ACF field to display.
// ADD NEW COLUMN
add_filter( 'manage_edit-shop_order_columns', 'custom_shop_order_column', 20 );
function custom_shop_order_column($columns)
{
$reordered_columns = array();
foreach( $columns as $key => $column){
$reordered_columns[$key] = $column;
if( $key == 'order_status' ){
$reordered_columns['my-column'] = __( 'Location','theme_domain');
}
}
return $reordered_columns;
}
Here, adding ACF to new colum.
// ADD ACF FIELD TO COLUMN
add_action( 'manage_shop_order_posts_custom_column' , 'custom_orders_list_column_content', 20, 2 );
function custom_orders_list_column_content( $column, $post_id )
{
if ( 'Location' == $column_name ){
$product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;
echo get_field( 'location', $product_id );
}
return true;
}
Still learning and not sure how to do this, any advice?
An order generally consists of several products, therefore you cannot use $product_id directly, but you have to loop through the order items.
So you get:
/**
* Add columns
*/
function filter_manage_edit_shop_order_columns( $columns ) {
$reordered_columns = array();
foreach ( $columns as $key => $column ) {
$reordered_columns[$key] = $column;
if ( $key == 'order_status' ) {
$reordered_columns['my-column'] = __( 'Location','theme_domain' );
}
}
return $reordered_columns;
}
add_filter( 'manage_edit-shop_order_columns', 'filter_manage_edit_shop_order_columns', 10, 1 );
/**
* Populate columns
*/
function filter_manage_shop_order_posts_custom_column( $column, $post_id ) {
// Compare
if ( $column == 'my-column' ) {
// Get order
$order = wc_get_order( $post_id );
// Is a WC_Order
if ( is_a( $order, 'WC_Order' ) ) {
// Get items
$items = $order->get_items();
// Loop through
foreach ( $items as $key => $item ) {
// Product ID
$product_id = $item->get_variation_id() > 0 ? $item->get_variation_id() : $item->get_product_id();
// Get field
$address = get_field( 'location', $product_id );
// Output
echo ($address) ? '<div>Address: ' . $address . '</div>' : '<div>Address: No address found!</div>';
}
}
}
}
add_filter( 'manage_shop_order_posts_custom_column', 'filter_manage_shop_order_posts_custom_column', 10, 2 );

Remove duplicate values from custom column on WooCommerce admin orders list

I have the following code that adds a custom column on WooCommerce admin orders list
add_action( 'manage_shop_order_posts_custom_column', 'inforder_add_new_order_admin_list_column_content' );
function inforder_add_new_order_admin_list_column_content( $column ) {
global $post;
if ( 'product_order' === $column ) {
$order = wc_get_order( $post->ID );
$items = $order->get_items();
$count = count($items);
$i = 1;
foreach($items as $item) {
if($i==$count)
echo $item->get_name();
else
echo $item->get_name() .', ';
$i++;
}
}
}
But this shows duplicate values. I've tried to avoid this using
array_unique(), but unfortunately without the desired result.
Any advice to avoid this?
Your code contains some mistakes
The manage_edit-shop_order_columns is missing, which is for adding columns
The manage_shop_order_posts_custom_column has not 1 but 2 parameters, the 2nd contains the $post_id so the use of global $post is not necessary
You can use in_array(), which checks if a value exists in an array. If this is not the case, we will add this value to the array, this way we avoid duplicate values
So you get:
// Add header
function filter_manage_edit_shop_order_columns( $columns ) {
$columns['product_order'] = __( 'Product', 'woocommerce' );
return $columns;
}
add_filter( 'manage_edit-shop_order_columns', 'filter_manage_edit_shop_order_columns', 10, 1 );
// Display (populate the column)
function action_manage_shop_order_posts_custom_column( $column, $post_id ) {
// Compare
if ( $column == 'product_order' ) {
// Get order
$order = wc_get_order( $post_id );
// Initialize
$names = array();
// Is a WC_Order
if ( is_a( $order, 'WC_Order' ) ) {
// Get items
$items = $order->get_items();
// Loop through
foreach ( $items as $key => $item ) {
// Get name
$name = $item->get_name();
// NOT in array
if ( ! in_array( $name, $names, true ) ) {
// Push one or more elements onto the end of array
array_push( $names, $name );
}
}
// NOT empty, print result
if ( ! empty( $names ) ) {
// Use implode() function to join comma in the array
$list = implode( ', ', $names );
// Output
echo $list;
}
}
}
}
add_action( 'manage_shop_order_posts_custom_column' , 'action_manage_shop_order_posts_custom_column', 10, 2 );

Wordpress: saving a taxonomy based on the value of a different taxonomy

We're building a clothing store. The products that will be uploaded could have label sizes from various countries, and as such we have two size taxonomies: product_size and product_size_uk.
I'm trying to set the uk size based upon the international size at the point the product is saved/updated, and running a switch to set a variable to the id of the uk size taxonomy and using
wp_set_object_terms. But this isn't working:
add_action( 'save_post', 'save_uk_size' );
function save_uk_size( $post_id ) {
if ( $post->post_type == 'product' ) {
$post = get_post($post_id);
$terms = wp_get_post_terms( $post->ID, 'product_size', array( 'fields' => 'all' ) );
if ( $terms ) {
$prod_size_int = $terms[0]->slug;
}
switch ($prod_size_int) {
...
case "FR-36":
$prod_size_uk = 805;
break;
case "FR-38":
$prod_size_uk = 806;
break;
...
}
wp_set_object_terms($post_id, $prod_size_uk, 'product_size_uk');
}
}
Can anyone steer me in the right direction? Thanks!
First you need to install Advanced Custom Fields plugin
Then for taxonomy product_size we create Taxonomy field (product_size_uk).
Now in the pages of taxonomy product_size in admin panel there is a field where we can choose which product_size_uk corresponds to this taxonomy.
3.Then we have to choose product_size_uk matching for all sizes.
And then this code
add_action( 'save_post_product', 'product_save_new_term' );
function product_save_new_term($post_id) {
remove_action( 'save_post_product', 'product_save_new_term' );
$terms = wp_get_object_terms( $post_id, 'product_size' );
$term_id = $terms[0]->term_id;
if($term_id != "") {
$key_for_field = 'product_size_' . $term_id;
$product_size_uk_value = get_field( 'product_size_uk', $key_for_field );
wp_set_object_terms($post_id, $product_size_uk_value, 'product_size_uk');
clean_post_cache( $post_id );
} else {
wp_delete_object_term_relationships( $post_id, 'product_size_uk' );
}
add_action( 'save_post_product', 'product_save_new_term' );
}
Or, if you don't want to have controls for size matching in the admin panel and it's easier for you to write everything in the code.
add_action( 'save_post_product', 'product_save_new_term' );
function product_save_new_term($post_id) {
$data_array = array(
"product_size_term_id" => "product_size_uk_term_id",
"product_size_term_id2" => "product_size_uk_term_id2",
"product_size_term_id3" => "product_size_uk_term_id3",
);
remove_action( 'save_post_product', 'product_save_new_term' );
$terms = wp_get_object_terms( $post_id, 'product_size' );
$term_id = $terms[0]->term_id;
if($term_id != "") {
$product_size_uk_value = $data_array[$term_id];
if($product_size_uk_value !="") {
wp_set_object_terms($post_id, $product_size_uk_value, 'product_size_uk');
}
clean_post_cache( $post_id );
} else {
wp_delete_object_term_relationships( $post_id, 'product_size_uk' );
}
add_action( 'save_post_product', 'product_save_new_term' );
}

Show order details in a new column on My account / order table

In WooCommerce, I would like to add a new column to the "My Account" orders table and show the order details.
I have this code, which adds the column, but the values don't show (e.g. get_formatted_meta_data).
Can anyone help rewrite the code to make it work?
function wc_add_my_account_orders_column( $columns ) {
$new_columns = array();
foreach ( $columns as $key => $name ) {
$new_columns[ $key ] = $name;
if ( 'order-status' === $key ) {
$new_columns['order-details'] = __( 'Order details', 'textdomain' );
}
}
return $new_columns;
}
add_filter( 'woocommerce_my_account_my_orders_columns', 'wc_add_my_account_orders_column' );
function wc_my_orders_order_details_column( $order ) {
$order_details = get_post_meta( $order->get_id(), 'order_details', true );
echo ! empty( $order_details ) ? $order_details : '–';
}
add_action( 'woocommerce_my_account_my_orders_column_order_details', 'wc_my_orders_order_details_column' );
The woocommerce_my_account_my_orders_columns filter has been deprecated since WooCommerce 2.6.0. So although it still functions you should use the woocommerce_account_orders_columns filter to add an additional column.
To populate the column with your data you can use the woocommerce_my_account_my_orders_column_ action which expects you to append the column ID of your custom column. So in your case that would be order-details. In your example you've used order_details (with an underscore instead of a hyphen). That is why your data doesn't show up.
Also it is best practice to retrieve order meta data via the internal WooCommerce getter function get_meta() instead of using get_post_meta().
add_filter( 'woocommerce_account_orders_columns', 'wc_add_my_account_orders_column', 10, 1 );
function wc_add_my_account_orders_column( $columns ) {
$new_columns = array();
foreach ( $columns as $key => $name ) {
$new_columns[ $key ] = $name;
if ( 'order-status' === $key ) {
$new_columns['order-details'] = __( 'Order details', 'textdomain' );
}
}
return $new_columns;
}
add_action( 'woocommerce_my_account_my_orders_column_order-details', 'wc_my_orders_order_details_column', 10, 1 );
function wc_my_orders_order_details_column( $order ) {
$item_meta = '';
foreach ( $order->get_items() as $item ) {
$item_meta .= wc_display_item_meta( $item, array( 'echo' => false ) );
}
echo !empty( $item_meta ) ? $item_meta : '-';
}

Sort WooCommerce cart by category

I already found a snippet to sort the checkout cart alphabetically. This works perfect but as mentioned I try to sort and group my products by category.
Is there anyone who could tweak the following snippet so it sorts the products by category?
add_action( 'woocommerce_cart_loaded_from_session', 'bbloomer_sort_cart_items_alphabetically' );
function bbloomer_sort_cart_items_alphabetically() {
global $woocommerce;
// READ CART ITEMS
$products_in_cart = array();
foreach ( $woocommerce->cart->cart_contents as $key => $item ) {
$products_in_cart[ $key ] = $item['data']->get_title();
}
// SORT CART ITEMS
natsort( $products_in_cart );
// ASSIGN SORTED ITEMS TO CART
$cart_contents = array();
foreach ( $products_in_cart as $cart_key => $product_title ) {
$cart_contents[ $cart_key ] = $woocommerce->cart->cart_contents[ $cart_key ];
}
$woocommerce->cart->cart_contents = $cart_contents;
}
In order to grouped cart items by categories, add follows code snippet -
function woocommerce_before_cart_contents(){
global $woocommerce;
$cat_wisw_pros = array();
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $cart_item ) {
$product_id = $cart_item['product_id'];
$cat_ids = wp_get_post_terms( $product_id, 'product_cat', array( 'fields' => 'ids' ) );
foreach ( $cat_ids as $id ) {
$cat_wisw_pros[$id][$cart_item_key] = $cart_item;
}
}
ksort( $cat_wisw_pros ); // Cat ID wise sort
$grouped_cart_items = array();
foreach ( $cat_wisw_pros as $cat_id => $cart_items ) {
foreach ( $cart_items as $cart_item_key => $cart_item ) {
if( !array_key_exists( $cart_item_key, $grouped_cart_items ) )
$grouped_cart_items[$cart_item_key] = $cart_item;
}
}
$woocommerce->cart->cart_contents = $grouped_cart_items;
}
add_action( 'woocommerce_before_cart_contents', 'woocommerce_before_cart_contents' );
You should be able to access the category ids with the method get_category_ids() as defined in the class WC_Product
$item['data']->get_category_ids()
but this gives you back an array, so you need to handle getting the id, e.g.
$ids = $item['data']->get_category_ids();
$id = $ids[ 0 ];
and transforming to a string, e.g.
$term_obj = get_term( $id, 'product_cat' );
$name = $term_obj->name;
you could then do
$products_in_cart[ $key ] = $name;
and by the same logic used in the code in your question sort by category.
There are several things to consider though, this does not handle items being in multiple categories, it just gets the first by using index 0. Additionally, this has no extra logic of sorting, if there are multiple products in the same category.
Please note, this is untested and merely an idea of an approach of how this could be handled.

Resources