wc_update_order_item not saving correctly - php

I'm trying to update the Item Name in the wp_woocommerce_order_items table and found the function wc_update_order_item to do the trick.
I want it to change to a randomly picked product. They main thing here is I already know the order_item_id that I want to change.
Here's my code:
$order_item_id = array(1,2,3);
$num = 3;
$ctr = 0;
$products = new WP_Query( array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => $num,
'orderby' => 'rand',
));
if ( $products->have_posts() ): while ( $products->have_posts() ): $products->the_post();
wc_update_order_item($order_item_id[$ctr], array('order_item_name' => $products->post->post_title));
$ctr++;
endwhile; wp_reset_postdata(); endif;
The wc_update_order_item() is where it is supposed to update the order item name. It does update the order_item_name but not with the current $products->post->post_title value. It updates with with a random product title.
How do I know the title being saved is different from the current post_title inside the loop? If I echo $products->post->post_title inside the loop, it displays the current product name, as it should, but the updated order_item_name has a different value.

Try the following that will get the related product IDs corresponding to the Order items, to exclude them from the WP_Query, avoiding having the same product names:
$order_item_ids = array(1,2,3);
$num = 3;
$ctr = 0;
$exluded_ids = array();
// Loop through the Order items Ids
foreach ( $order_item_ids as $item_id ) {
// Get the order ID from the order Item ID
$order_id = wc_get_order_id_by_order_item_id( $item_id );
// Get the WC_Order object instance
$order = wc_get_order( $order_id );
// Get the WC_Order_Item_Product object instance
$item = $order->get_item( $item_id );
// Products IDs to be excluded from the WP_Query (array)
$exluded_ids[] = $item->get_product_id();
}
$products = new WP_Query( array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => $num,
'orderby' => 'rand',
'post__not_in' => $exluded_ids,
));
if ( $products->have_posts() ):
while ( $products->have_posts() ): $products->the_post();
wc_update_order_item($order_item_id[$ctr], array('order_item_name' => $products->post->post_title));
$ctr++;
endwhile;
wp_reset_postdata();
endif;
It should work.
Now as we don't know how you get the $order_item_id array, it's not possible to know what really happen. It should be better to explain what you are trying to do from the start.

Related

WooCommerce: Get average rating from multiple products [duplicate]

This question already has an answer here:
Display total customers reviews and ratings average in WooCommerce
(1 answer)
Closed last year.
I've a custom loop to get a list of products based on a list of product IDs.
Now I try to get the total ratings and average rating of all the products within that loop.
The total count of ratings isn't the problem.
My problem is that I don't get the star rating from the comments.
(I'm using the plugin "WooCommerce Product Reviews Pro")
Here's my current loop so far:
<?php $args = array (
'post_type' => 'product',
'number' => '-1',
'post__in' => $product_ids,
'meta_key' => 'rating',
'orderby' => 'meta_value_num',
'order' => 'DESC'
);
$comments = get_comments( $args );
echo count($comments);
?>
<?php if ( !empty($comments) ) : ?>
<pre><?php print_r($comments); ?></pre>
<?php foreach ( $comments as $comment ) {
echo $comment_ID = $comment->comment_ID;
} ?>
<?php endif; ?>
With echo count($comments) I get the total count of ratings.
But if I do print_r($comments), I don't see the star rating for the review.
I guess that I need to use the comment ID for that.
With the foreach I get all comment Ids as a string.
But I'm not sure where to look and how I add all ratings to generate a new average rating for the selected posts from the loop.
EDIT: I found another way to get to the average ratings.
This time I loop through the posts instead the comments.
So I can get the average rating for every product.
The problem is that in that loop are also ratings with a 0 if there are no comments/reviews.
Here's the loop for the product so far:
$average_ratings = array();
foreach ( $posts as $post ) {
global $product;
echo $average_ratings[] = $product->get_average_rating();
}
var_dump($average_ratings);
I found an answer. This is my code:
<?php
$args = array (
'post_type' => 'product',
'post__in' => $product_ids,
'meta_key' => 'rating',
'orderby' => 'meta_value_num',
'order' => 'DESC'
);
$comments = get_comments( $args );
$total_ratings = count($comments);
?>
<?php if ( !empty($comments) ) : ?>
<?php
$average_ratings = array();
foreach ( $comments as $comment ) {
$comment_post_ID = $comment->comment_post_ID;
$product = wc_get_product( $comment_post_ID );
$average_ratings[] = $product->get_average_rating();
}
$average_ratings = array_filter($average_ratings);
$average = array_sum($average_ratings)/count($average_ratings);
echo $average;
?>
<?php endif; ?>

Wordpress get term current category problem with loop

I'm having trouble displaying the loop category correctly. Need display only one category in lit posts. Why the first post gets all selected categories and the next posts already have the correct display of one category. How can I make only the current selected category displayed in the first post? My code looks like this. I attached the picture.
My loop custom post
<?php
/* Start the Loop */
$args = array( 'post_type' => 'database',
'posts_per_page' => 10,
'paged' => $paged,
'post_status' => 'publish',
'ignore_sticky_posts' => true,
'order' => 'DESC',
'orderby' => 'date');
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
This is for display one category in loop post
<?php
// Get terms for post
$terms = wp_get_post_terms( $post->ID , 'database_categories' ,$args2);
$args2 = array( 'parent' => 39,
'fields' => 'all');
// Loop over each item since it's an array
if ( $terms != null ) {
foreach( $terms as $term ) {
$term_link = get_term_link( $term, 'database_categories' );
// Print the name and URL
echo '' . $term->name . ' ';
// Get rid of the other data stored in the object, since it's not needed
unset($term);
}
}
?>
If the object here is to get the first term and ignore the rest then I would just shift off the first array element and no need for a loop on terms.
$args2 = array('parent' => 39, 'fields' => 'all');
$terms = wp_get_post_terms( $post->ID , 'database_categories' ,$args2);
if (!empty($terms)) {
$term = array_shift($terms);
echo sprintf('%s', get_term_link( $term, 'database_categories' ), $term->name);
}

Wordpress woocommerce multiple orderby args loop

Does anyone know how to incorporate a while loop into a basic order by filter? I have the following basic filter in my functions.php page that orders my products by the featured products and it works:
add_filter('woocommerce_get_catalog_ordering_args', 'am_woocommerce_catalog_orderby');
function am_woocommerce_catalog_orderby( $args ) {
if(!$_GET['orderby']) {
$args = array(
'orderby' => array( 'meta_value' => 'DESC' ),
'meta_key' => '_featured'
);
return $args;
}
}
My problem is I want to use some more advanced while loops to try and get multiple different arguments tied into the same args. I am trying to show my featured products first, then load that into an array then get my next loop and only show the products that are 6 months old or younger and add that to my array, then show everything else and sort them by menu_order and title and add it to my array as shown below:
add_filter('woocommerce_get_catalog_ordering_args', 'am_woocommerce_catalog_orderby');
function am_woocommerce_catalog_orderby( $my_post_array ) {
if(!$_GET['orderby']) {
//First loop - show featured
$args['orderby'] = array( 'meta_value' => 'DESC' );
$args['meta_key'] = '_featured';
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$post_id = get_the_ID();
$my_post = my_post_function($post_id);
//Store the items in an array
$my_post_array [] = $my_post;
query_posts($args);
endwhile;
wp_reset_query();
//Second loop - Show newer than 6 months
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'date_query' => array(
array(
'before' => '6 months ago',
),
)
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$post_id = get_the_ID();
$my_post = my_post_function($post_id);
//Store the items in an array
$my_post_array [] = $my_post;
query_posts($args);
endwhile;
wp_reset_query();
//Third loop - show everything else and sort by menu_order and title
$args['orderby'] = array( 'menu_order' => 'ASC', 'title' => 'ASC' );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$post_id = get_the_ID();
$my_post = my_post_function($post_id);
//Store the items in an array
$my_post_array [] = $my_post;
query_posts($args);
endwhile;
wp_reset_query();
//Remove duplicate entries from the array
array_unique ( $my_post_array, SORT_STRING );
}
}
Then the last thing I do is remove my duplicates. Only problem is it does not work and I am not sure where I am going wrong, I have not done something like this before so I could be working in the wrong area or missing something obvious. Anyone have ideas on how I can trouble shoot this or does anyone see something that may be causing me issues? Thanks for the help, still learning and trying to improve!

Wordpress woocommerce, sort by featured, New (with date range), menu order then title

I am trying to set my default sort for my products in WordPress with Woocommerce to show me all the featured products first, then any new products that are no older than 120 days, then show everything else by menu order and finally by the title. Below is my initial code that does kind of do what i want but i have no idea how to set a date range of 120 days or newer.
add_filter('woocommerce_get_catalog_ordering_args', 'am_woocommerce_catalog_orderby');
function am_woocommerce_catalog_orderby( $args ) {
if(!$_GET['orderby']) {
$args['orderby'] = array(
'meta_value' => 'DESC',
'date' => 'DESC',
'menu_order' => 'ASC',
'title' => 'ASC'
);
$args['meta_key'] = '_featured';
return $args;
}
}
UPDATE
Ok so I have done some searching and i found some code that is supposed to loop through arguments and then remove duplicates, being a noob I am not sure what I am missing. My code below gets an error: Fatal error: Call to a member function have_posts() on null so i tried to add $loop = new WP_Query( $args ); but then the code does nothing. So I am lost and looking for some clues on what i need to fix. Thanks!
add_filter('woocommerce_get_catalog_ordering_args', 'am_woocommerce_catalog_orderby');
function am_woocommerce_catalog_orderby( $my_post_array ) {
if(!$_GET['orderby']) {
//First loop - show featured
$args['orderby'] = array( 'meta_value' => 'DESC' );
$args['meta_key'] = '_featured';
while ( $loop->have_posts() ) : $loop->the_post();
$post_id = get_the_ID();
$my_post = my_post_function($post_id);
//Store the items in an array
$my_post_array [] = $my_post;
query_posts($args);
endwhile;
//Second loop - Show newer than 6 months
$args = array(
'orderby' => 'date',
'order' => 'DESC',
'date_query' => array(
array(
'before' => '6 months ago',
),
)
);
while ( $loop->have_posts() ) : $loop->the_post();
$post_id = get_the_ID();
$my_post = my_post_function($post_id);
//Store the items in an array
$my_post_array [] = $my_post;
query_posts($args);
endwhile;
//Third loop - show everything else and sort by menu_order and title
$args['orderby'] = array( 'menu_order' => 'ASC', 'title' => 'ASC' );
while ( $loop->have_posts() ) : $loop->the_post();
$post_id = get_the_ID();
$my_post = my_post_function($post_id);
//Store the items in an array
$my_post_array [] = $my_post;
query_posts($args);
endwhile;
//Remove duplicate entries from the array
array_unique ( $my_post_array, SORT_STRING );
}
}
Update 2
I have yet to have any luck, any chance someone can take a look at my latest code above and give me some ideas on a direction to try? This loop does not seem to work for this filter when adding to the functions.php, maybe i need to do something different. Any help is appreciated!

Woocommerce get product ID's from Category

So on my template for taxonomy-product_tag.php, I want to get all product id's from the Category.
Here is how I currently do it
<?php
$post_ids = array();
$args = array( 'post_type' => 'product', 'posts_per_page' => 1, 'product_cat' => 'dog-collars', 'orderby' => 'rand' );
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
$post_ids[] = get_the_ID();
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_query();
print_r($post_ids);
?>
I can loop through the product_cat, pull id's into an array and then further down the page I use foreach and the WC product factory to manipulate data how I want it shown for users.
My problem is I need the loop to be Dynamic based on categories, and I can't understand how to do this.
I did think I can just grab the category name from the url
<?php $actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; ?>
Grab it and the parse to just get the last , i.e category name, and then print into loop
But this seems like it would be a really poor way of doing it.
What I want is in the args
$args = array( 'post_type' => 'product', 'posts_per_page' => 1, 'product_cat' => 'DYNAMICHERE', 'orderby' => 'rand' );
I want to be able to populate product_cat dynamically based on the category I am on
Any help or advise / pointing me in the right direction would be appreciated
Use get_query_var( 'product_cat' ).

Categories