I would like to display the thumbnails of all items in the orders I received from my customers. I'm using Add products thumbnail to Woocommerce admin orders list answer code but sometimes I got error with the notice:
"Error message: Uncaught Error: Call to a member function
get_image_id() on bool in".
I wonder how can I solve this problem?
I am checking as you share the link, It's working fine but if you got an issue should be a versioning issue or something missing.
I have few/small changes, I hope this is helpful for you.
// Add a new custom column name "Product Image" to admin order list
add_filter( 'manage_edit-shop_order_columns', 'woo_admin_orders_list_add_column', 10, 1 );
function woo_admin_orders_list_add_column( $columns ){
$columns['custom_column'] = __( 'Product Image', 'woocommerce' );
return $columns;
}
// The data of the new custom column value in admin order list
add_action( 'manage_shop_order_posts_custom_column' , 'woo_add_product_image_order_column', 10, 2 );
function woo_add_product_image_order_column( $column, $post_id ){
global $order;
if( 'custom_column' === $column ){
$count = 0;
$order = wc_get_order($post_id);
// Loop through order items
foreach( $order->get_items() as $item ) {
$product = $item->get_product(); // The WC_Product Object
$style = $count > 0 ? ' style="padding-left:6px;"' : '';
// Display product thumbnail
printf( '<span%s>%s</span>', $style, $product->get_image( array( 50, 50 ) ) );
$count++;
}
}
}
Related
I am trying to display product thumbnails on WooCommerce My account > Orders list, beside the order number.
Below is the screenshot of the order
What hook I have to use to display the image?
I tried Add the product image to Woocommerce my account order view answer code, but it displays the image on single view orders.
Updated
You can use the following to add product thumbnails on WooCommerce My account > Orders list, beside the order number:
add_action( 'woocommerce_my_account_my_orders_column_order-number', 'my_account_orders_product_thumbnails', 20, 1 );
function my_account_orders_product_thumbnails( $order ) {
echo '' . '#' . $order->get_order_number() . '';
// Loop through order items
foreach( $order->get_items() as $item ) {
$product = $item->get_product(); // Get the WC_Product object (from order item)
$thumbnail = $product->get_image(array( 36, 36)); // Get the product thumbnail (from product object)
if( $product->get_image_id() > 0 ) {
echo ' ' . $thumbnail;
}
}
}
Or you can add a new column with the product thumbnails after the order number like:
add_filter( 'woocommerce_my_account_my_orders_columns', 'filter_woocommerce_my_account_my_orders_columns', 10, 1 );
function filter_woocommerce_my_account_my_orders_columns( $columns ) {
$new_column = array( 'order-number' => $columns['order-number']);
unset($columns['order-number']);
$new_column['order-thumbnails'] = '';
return array_merge($new_column, $columns);
}
add_action( 'woocommerce_my_account_my_orders_column_order-thumbnails', 'filter_woocommerce_my_account_my_orders_column_order', 10, 1 );
function filter_woocommerce_my_account_my_orders_column_order( $order ) {
// Loop through order items
foreach( $order->get_items() as $item ) {
$product = $item->get_product(); // Get the WC_Product object (from order item)
$thumbnail = $product->get_image(array( 36, 36)); // Get the product thumbnail (from product object)
if( $product->get_image_id() > 0 ) {
echo $thumbnail . ' ' ;
}
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
This is working fine for me. Unfortunately, the function is not working on Woocommerce Pre-Order plugin and in mobile the graphics are so small.
add_action( 'woocommerce_my_account_my_orders_column_order-number', 'my_account_orders_product_thumbnails', 20, 1 );
function my_account_orders_product_thumbnails( $order ) {
echo '' . '#' . $order->get_order_number() . '';
// Loop through order items
foreach( $order->get_items() as $item ) {
$product = $item->get_product(); // Get the WC_Product object (from order item)
$thumbnail = $product->get_image(array( 36, 36)); // Get the product thumbnail (from product object)
if( $product->get_image_id() > 0 ) {
echo ' ' . $thumbnail;
}
}
}
We add a new column to display the author => store-name form each product. (Add custom meta column to WooCommerce product listing)
I was able to answer the mentioned question by my self. But now we ran into a new problem. The needed information are now in the new column, but we can not click it. We want to have the entries in that new column clickable in order that every product from that author would be filtered. So it's a question about how to make a clickable link in order to show all other product from that author.
This is our code:
add_filter( 'manage_edit-product_columns', 'custom_admin_products_store_name_column', 9999 );
function custom_admin_products_store_name_column( $columns ){
$columns['vendor_store_name'] = __( 'Vendor');
return $columns;
}
add_action( 'manage_product_posts_custom_column', 'custom_admin_products_store_name_column_content', 10, 2 );
function custom_admin_products_store_name_column_content( $column, $product_id ){
$seller = get_post_field( 'post_author', $product_id);
$store_info = dokan_get_store_info( $seller );
$store_name = $store_info['store_name'];
if ( $column == 'vendor_store_name' ) {
echo __($store_name);
}
}
I already tried around with the information from here: WooCommerce: Adding a custom filter to the Product Admin area
But this is more for a new filter than a clickable value in a column which will apply a filter.
I was able to get this to work! :)
Here is my code. Is this a proper solution or where can I improve this? :)
Thanlks
add_filter( 'manage_edit-product_columns', 'custom_admin_products_store_name_column', 9999 );
function custom_admin_products_store_name_column( $columns ){
$columns['vendor_store_name'] = __( 'Vendor');
return $columns;
}
add_action( 'manage_product_posts_custom_column', 'custom_admin_products_store_name_column_content', 10, 2 );
function custom_admin_products_store_name_column_content( $column, $product_id ){
$seller = get_post_field( 'post_author', $product_id);
$store_info = dokan_get_store_info( $seller );
$store_name = $store_info['store_name'];
$vendor_products = get_admin_url() . 'edit.php?post_type=product&author=' . $seller;
if ( $column == 'vendor_store_name' ) {
printf('%s', $vendor_products, $store_name);
}
}
I am trying to modify the product images in the auto generated WooCommerce order e-mails. Note, I am trying to do this with hooks, rather than creating a modified e-mail template.
To start, I have a hidden input on the single product page. I have some JS that sets the ID of the image, which is based on the product's colour (a custom attribute I made with ACF).
<input class="js-col-img-id" type="hidden" name="product-col-img-id" value="">
For reference, here's what I've done to get this to work on the cart page:
// Add custom attributes to cart item data
add_action('woocommerce_add_cart_item_data', 'jwd_add_custom_attr_to_cart', 10, 3);
function jwd_add_custom_attr_to_cart($cart_item_data, $product_id, $variation_id) {
$attrs = array(...,'product-col-img-id');
foreach ($attrs as $attr) {
$san_attr = filter_input( INPUT_POST, $attr );
if ( !empty( $san_attr ) ) {
$cart_item_data[$attr] = $san_attr;
}
}
return $cart_item_data;
}
// This function sets the image ID in the cart, and it displays the image properly
add_action( 'woocommerce_before_calculate_totals', 'bwa_new_price' );
function bwa_new_price($cart) {
// ...
$cart_items = $cart->get_cart();
foreach($cart_items as $item) {
$data = $item['data'];
// product-col-img-id is sent through the hidden input when the add to cart form is submitted
$colour_img_ID = $item['product-col-img-id'] ?? false;
if ($colour_img_ID) {
$data->set_image_id($colour_img_ID);
}
}
}
// Add custom attributes to order
add_action( 'woocommerce_checkout_create_order_line_item', 'jwd_add_attr_to_order_items', 10, 4 );
function jwd_add_attr_to_order_items( $item, $cart_item_key, $values, $order ) {
if ( !empty( $values['product-colour'] ) ) {
$item->add_meta_data( 'Colour', $values['product-colour'] );
}
// I tried replicating this for the img ID. It does display it in the var dump mentioned below, and it does display it as an actual label in the e-mail (which I'd want to get rid of). The difficulty then becomes reading the ID through code and setting the product to display that image
if ( !empty( $values['product-col-img-id'] ) ) {
$item->add_meta_data( 'col_img_id', $values['product-col-img-id'] );
}
}
That works fine, but I'm having difficulty replicating this in the order e-mail. So far I've come across the following. This shows images in the e-mail, but it's the product's featured image. Of note is the "show_image" key being set to true.
// Add prod IMG to e-mails
function jwd_add_images_woocommerce_emails( $output, $order ) {
// set a flag so we don't recursively call this filter
static $run = 0;
// if we've already run this filter, bail out
if ( $run ) {
return $output;
}
$args = array(
'show_image' => true,
//'image_size' => array( 300, 300 ),
'image_size' => 'full',
);
// increment our flag so we don't run again
$run++;
// if first run, give WooComm our updated table
return wc_get_email_order_items($order, $args);
}
add_filter( 'woocommerce_email_order_items_table', 'jwd_add_images_woocommerce_emails', 10, 2 );
To modify the image, I found this filter, but I'm just having a difficult time figuring out what I need to do to replicate what I've done on the cart page. The closest I've got is having $item_data work, and I do see the product-col-img-id key in the var dump, though it's in a protected object, which I'm not sure how to access. Even if I could access, I'm not sure how I could even set the image from here.
add_filter('woocommerce_order_item_thumbnail', 'jwd_add_colour_img', 10, 2);
function jwd_add_colour_img($image, $item) {
$item_id = $item->get_id();
//var_dump($item->get_current_data());
$product = $item->get_product();
$product_id = $item->get_product_id();
$item_data = $item->get_data();
$col_img_id = false;
$item->set_image_id(1);
foreach ($item_data as $key => $item) {
//current_data
var_dump($item);
//echo "<br><br>";
$col_img_id = $item['product-col-img-id'] ?? false;
if ($col_img_id) {
break;
}
}
//var_dump($col_img_id);
//$item_id = $item->get_product_id();
//var_dump(wc_get_order_item_meta( $item_id, 'col_img_id', true ) );
return $image;
}
To get WooCommerce custom meta data, you can use WC_Data method get_meta().
Try the following instead to display your custom image on email notifications:
// Save custom image ID as order item meta
add_action( 'woocommerce_checkout_create_order_line_item', 'save_custom_image_id_to_order_item', 10, 4 );
function save_custom_image_id_to_order_item( $item, $cart_item_key, $values, $order ) {
if ( isset($values['product-colour']) && ! empty($values['product-colour']) ) {
$item->add_meta_data('Colour', $values['product-colour'] );
}
if ( isset($values['product-col-img-id']) && ! empty($values['product-col-img-id']) ) {
$item->add_meta_data('_col_img_id', $values['product-col-img-id'] );
}
}
// (optional) Force display item image on emails
add_filter( 'woocommerce_email_order_items_args', 'show_image_on_email_notifications' );
function show_image_on_email_notifications( $args ) {
$args['show_image'] = true;
return $args;
}
// Display custom image on emails
add_filter( 'woocommerce_order_item_thumbnail', 'display_email_order_item_custom_image', 10, 2 );
function display_email_order_item_custom_image( $image, $item ) {
// Only on email notifications
if( is_wc_endpoint_url() )
return $image;
$image_id = $item->get_meta('_col_img_id');
if( $image_id ) {
$image = wp_get_attachment_image( $image_id, array( 32, 32 ), false, array() );
}
return $image;
}
Code goes in functions.php file of the active child theme (or active theme). It should work.
I would like to add futured image on admin view order pages in Woocommerce.
New Column created, but the product image does not appear.
What should I do to show the order thumbnail?
Thanks.
// Admin Order page new colums
add_filter( 'manage_edit-shop_order_columns', 'add_account_orders_column', 10, 1 );
function add_account_orders_column( $columns ){
$columns['custom-column'] = __( 'New Column', 'woocommerce' );
return $columns;
}
add_action( 'woocommerce_my_account_my_orders_column_custom-column', 'add_account_orders_column_rows' );
function add_account_orders_column_rows( $order ) {
// Example with a custom field
if ( $value = $order->get_meta( 'order_received_item_thumbnail_image' ) ) {
echo esc_html( $value );
}
}
Beware, as orders can have many products (many order items) and in this cas you will have many images (also it will weigh down the page)…
Now Your 2nd function hook is wrong and will not do anything.
To so you need to loop through order items as follow:
// Add a new custom column to admin order list
add_filter( 'manage_edit-shop_order_columns', 'admin_orders_list_add_column', 10, 1 );
function admin_orders_list_add_column( $columns ){
$columns['custom_column'] = __( 'New Column', 'woocommerce' );
return $columns;
}
// The data of the new custom column in admin order list
add_action( 'manage_shop_order_posts_custom_column' , 'admin_orders_list_column_content', 10, 2 );
function admin_orders_list_column_content( $column, $post_id ){
global $the_order;
if( 'custom_column' === $column ){
$count = 0;
// Loop through order items
foreach( $the_order->get_items() as $item ) {
$product = $item->get_product(); // The WC_Product Object
$style = $count > 0 ? ' style="padding-left:6px;"' : '';
// Display product thumbnail
printf( '<span%s>%s</span>', $style, $product->get_image( array( 50, 50 ) ) );
$count++;
}
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
I would like to have a custom back-order message for certain WooCommerce products based on their ID, SKU or something else unique.
Right now I have this, and this works fine for all products that have back-order enabled, but what if I want this logic conditional for only certain product variations?
function backorder_text($availability) {
if($product->get_sku() == "111100"){
foreach($availability as $i) {
//$availability = str_replace('Available on backorder', 'Yo, allow 3-4 weeks for your shiz!', $availability);
$availability = str_replace('Beschikbaar via nabestelling', 'UITVERKOCHT (U kunt wel bestellen, maar de levertijd is 2-3 werkdagen).', $availability);
}
return $availability;
}
}
add_filter('woocommerce_get_availability', 'backorder_text');
if( $product->is_type( 'variable' ) ){
$available_variations = $product->get_available_variations()
foreach( $available_variations as $i => $variation ) {
//Do your code here by checking specific
}
}
This actually worked best for me:
function backorder_text_prikkabel_zonder_fittingen( $availability, $product ) {
$product_ids = array( 7631, 7631, 8612, 7629, 7628, 7627 );
if ( in_array( $product->get_id(), $product_ids ) ){
foreach( $availability as $i ) {
$availability = str_replace( 'Default back-order message', 'Your custom back-order message', $availability );
}
}
return $availability;
}
add_filter('woocommerce_get_availability', 'backorder_text_prikkabel_zonder_fittingen', 10, 2 );
Explanation: the array contains a list of product variation ID's. If you echo $product->get_id(), somewhere around the bottom of the page, you will see a list of ID's for each of the products variations for that product.
Make sure the default order message exactly matches the message you get on your product page so the custom message will be used instead.