Display latest orders on WooCommerce "My account" Dashboard - php
I'm trying to show customer last 3 orders on WooCommerce dashboard. But get_template() does not work at all and shows nothing.
I also tried to put orders.php form table in to the dashboard.php template file but It displays no orders here, while already I have some active orders. I'm so confused and have no idea about this problem.
This is my dashboard code:
<?php get_header();?>
<?php
* #see https://docs.woocommerce.com/document/template-structure/
* #package WooCommerce\Templates
* #version 4.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
$allowed_html = array(
'a' => array(
'href' => array(),
),
);
?>
<p>
<!-- <?php
printf(
/* translators: 1: user display name 2: logout url */
wp_kses( __( 'Hello %1$s (not %1$s? Log out)', 'woocommerce' ), $allowed_html ),
'<strong>' . esc_html( $current_user->display_name ) . '</strong>',
esc_url( wc_logout_url() )
);
?> -->
</p>
<p>
<?php
/* translators: 1: Orders URL 2: Address URL 3: Account URL. */
// $dashboard_desc = __( 'From your account dashboard you can view your recent orders, manage your billing address, and edit your password and account details.', 'woocommerce' );
// if ( wc_shipping_enabled() ) {
// /* translators: 1: Orders URL 2: Addresses URL 3: Account URL. */
// $dashboard_desc = __( 'From your account dashboard you can view your recent orders, manage your shipping and billing addresses, and edit your password and account details.', 'woocommerce' );
// }
// printf(
// wp_kses( $dashboard_desc, $allowed_html ),
// esc_url( wc_get_endpoint_url( 'orders' ) ),
// esc_url( wc_get_endpoint_url( 'edit-address' ) ),
// esc_url( wc_get_endpoint_url( 'edit-account' ) )
// );
?>
</p>
<?php
/**
* My Account dashboard.
*
* #since 2.6.0
*/?>
<?php do_action( 'woocommerce_account_dashboard' );?>
<div class="row">
<div class="col-10 d-flex dashboard-custom">
<h4>Addresses</h4>
<div class="questionMark">
?
</div>
</div>
<div class="col-2 text-center pt-5 mt-2">
<a href="#" class="viwAdress">
See
</a>
</div>
</div>
<div class="row pt-5">
<div class="adress-dashboard">
<div class="col-12 pt-4 d-flex">
<?php
$fname = get_user_meta( $current_user->ID, 'first_name', true );
$lname = get_user_meta( $current_user->ID, 'last_name', true );
$address_1 = get_user_meta( $current_user->ID, 'billing_address_1', true );
$address_2 = get_user_meta( $current_user->ID, 'billing_address_2', true );
$phonenumber = get_user_meta( $current_user->ID, 'billing_mobile_phone', true );
$city = get_user_meta( $current_user->ID, 'billing_city', true );
$postcode = get_user_meta( $current_user->ID, 'billing_postcode', true );
// echo $fname . "<BR>";
// echo $lname . "<BR>";
// echo $address_1 . "<BR>";
// echo $address_2 . "<BR>";
// echo $city . "<BR>";
// echo $postcode . "<BR>";
?>
<svg id="a47b7a8a-e7bb-4135-b65b-2487268cdcff" width="14" height="17" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 17"><defs><style>.b21eb9b6-977e-44fb-a0e8-fad7fb47a827{fill:#909298;fill-rule:evenodd;}</style></defs><path class="b21eb9b6-977e-44fb-a0e8-fad7fb47a827" d="M10.32,7.26A3.11,3.11,0,1,1,7.21,4.13,3.12,3.12,0,0,1,10.32,7.26Zm-1.55,0A1.56,1.56,0,1,1,7.21,5.7,1.56,1.56,0,0,1,8.77,7.26Z" transform="translate(0 -0.01)"/><path class="b21eb9b6-977e-44fb-a0e8-fad7fb47a827" d="M2.17,12.15a7.07,7.07,0,0,1-.24-10A7,7,0,0,1,11.83,2a7.07,7.07,0,0,1,.24,10L7.24,17Zm8.77-1.32-3.75,4L3.25,11a5.5,5.5,0,0,1-.19-7.75,5.42,5.42,0,0,1,7.69-.19A5.5,5.5,0,0,1,10.94,10.83Z" transform="translate(0 -0.01)"/>
</svg>
<h5><?php echo $address_1; ?></h5>
</div>
<div class="col-12 d-flex pt-4">
<svg id="bd6f5e62-b10a-4e71-b77c-d5f9368c28e6" width="14" height="17" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 18"><defs><style>.a30aed3e-ff50-49ef-a803-e1cfe573925c,.fa1d0d58-d038-41f3-bd11-17bb673b76c2{fill:#909298;}.a30aed3e-ff50-49ef-a803-e1cfe573925c{fill-rule:evenodd;}</style></defs><path class="a30aed3e-ff50-49ef-a803-e1cfe573925c" d="M9.17,4A3.84,3.84,0,0,1,5.5,8,3.84,3.84,0,0,1,1.83,4,3.84,3.84,0,0,1,5.5,0,3.84,3.84,0,0,1,9.17,4ZM7.33,4A1.92,1.92,0,0,1,5.5,6,1.92,1.92,0,0,1,3.67,4,1.92,1.92,0,0,1,5.5,2,1.92,1.92,0,0,1,7.33,4Z"/><path class="fa1d0d58-d038-41f3-bd11-17bb673b76c2" d="M9.17,12a1,1,0,0,0-.92-1H2.75a1,1,0,0,0-.92,1v6H0V12A2.88,2.88,0,0,1,2.75,9h5.5A2.88,2.88,0,0,1,11,12v6H9.17Z"/>
</svg>
<h5>Customer :<?php echo $fname ; ?> </h5>
</div>
<div class="col-12 d-flex pt-4">
<h5>Phone :<?php echo $phonenumber; ?> </h5>
</div>
<div class="col-12 d-flex pt-4">
<h5>ZipCode:<?php echo $postcode ; ?> </h5>
</div>
</div>
<!-- adres box -->
</div>
<?php
/**
* Deprecated woocommerce_before_my_account action.
*
* #deprecated 2.6.0
*/
do_action( 'woocommerce_before_my_account' );
/**
* Deprecated woocommerce_after_my_account action.
*
* #deprecated 2.6.0
*/
do_action( 'woocommerce_after_my_account' );
/* Omit closing PHP tag at the end of PHP files to avoid "headers already sent" issues. */?>
</section>
And this is my Order template code that work on Orders Tab but don't work on dashboard Tab:
<?php
/**
* My Orders - Deprecated
*
* #deprecated 2.6.0 this template file is no longer used. My Account shortcode uses orders.php.
* #package WooCommerce\Templates
*/
defined('ABSPATH') || exit;
$my_orders_columns = apply_filters(
'woocommerce_my_account_my_orders_columns',
array(
'order-number' => esc_html__('Order', 'woocommerce'),
'order-date' => esc_html__('Date', 'woocommerce'),
'order-status' => esc_html__('Status', 'woocommerce'),
'order-total' => esc_html__('Total', 'woocommerce'),
'order-actions' => ' ',
)
);
$customer_orders = get_posts(
apply_filters(
'woocommerce_my_account_my_orders_query',
array(
'numberposts' => $order_count,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => wc_get_order_types('view-orders'),
'post_status' => array_keys(wc_get_order_statuses()),
)
)
); ?>
<?php if ($customer_orders) : ?>
<h2><?php echo apply_filters('woocommerce_my_account_my_orders_title', esc_html__('Recent orders', 'woocommerce')); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></h2>
<table class="shop_table shop_table_responsive my_account_orders">
<thead>
<tr>
<?php foreach ($my_orders_columns as $column_id => $column_name) : ?>
<th class="<?php echo esc_attr($column_id); ?>"><span
class="nobr"><?php echo esc_html($column_name); ?></span></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php
foreach ($customer_orders as $customer_order) :
$order = wc_get_order($customer_order); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$item_count = $order->get_item_count();
?>
<tr class="order">
<?php foreach ($my_orders_columns as $column_id => $column_name) : ?>
<td class="<?php echo esc_attr($column_id); ?>" data-title="<?php echo esc_attr($column_name); ?>">
<?php if (has_action('woocommerce_my_account_my_orders_column_' . $column_id)) : ?>
<?php do_action('woocommerce_my_account_my_orders_column_' . $column_id, $order); ?>
<?php elseif ('order-number' === $column_id) : ?>
<a href="<?php echo esc_url($order->get_view_order_url()); ?>">
<?php echo _x('#', 'hash before order number', 'woocommerce') . $order->get_order_number(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</a>
<?php elseif ('order-date' === $column_id) : ?>
<time datetime="<?php echo esc_attr($order->get_date_created()->date('c')); ?>"><?php echo esc_html(wc_format_datetime($order->get_date_created())); ?></time>
<?php elseif ('order-status' === $column_id) : ?>
<?php echo esc_html(wc_get_order_status_name($order->get_status())); ?>
<?php elseif ('order-total' === $column_id) : ?>
<?php
/* translators: 1: formatted order total 2: total order items */
printf(_n('%1$s for %2$s item', '%1$s for %2$s items', $item_count, 'woocommerce'), $order->get_formatted_order_total(), $item_count); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
<?php elseif ('order-actions' === $column_id) : ?>
<?php
$actions = wc_get_account_orders_actions($order);
if (!empty($actions)) {
foreach ($actions as $key => $action) { // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
echo '' . esc_html($action['name']) . '';
}
}
?>
<?php endif; ?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<?php
wc_get_template( 'myaccount/orders.php' );
?>
No need to overwrite template files, you can use the woocommerce_account_dashboard hook
Most of the code was copied from myaccount/orders.php template file,
here and there, however, there is an adjustment so that directly copying the template file is not a (complete) solution.
So you get:
function action_woocommerce_account_dashboard() {
// Set limit
$limit = 3;
// Get customer $limit last orders
$customer_orders = wc_get_orders( array(
'customer' => get_current_user_id(),
'limit' => $limit
) );
// Count customers orders
$count = count( $customer_orders );
// Greater than or equal to
if ( $count >= 1 ) {
// Message
echo '<p>' . sprintf( _n( 'Your last order', 'Your last %s orders', $count, 'woocommerce' ), $count ) . '</p>';
?>
<table class="woocommerce-orders-table woocommerce-MyAccount-orders shop_table shop_table_responsive my_account_orders account-orders-table">
<thead>
<tr>
<?php foreach ( wc_get_account_orders_columns() as $column_id => $column_name ) : ?>
<th class="woocommerce-orders-table__header woocommerce-orders-table__header-<?php echo esc_attr( $column_id ); ?>"><span class="nobr"><?php echo esc_html( $column_name ); ?></span></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php
foreach ( $customer_orders as $customer_order ) {
$order = wc_get_order( $customer_order ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$item_count = $order->get_item_count() - $order->get_item_count_refunded();
?>
<tr class="woocommerce-orders-table__row woocommerce-orders-table__row--status-<?php echo esc_attr( $order->get_status() ); ?> order">
<?php foreach ( wc_get_account_orders_columns() as $column_id => $column_name ) : ?>
<td class="woocommerce-orders-table__cell woocommerce-orders-table__cell-<?php echo esc_attr( $column_id ); ?>" data-title="<?php echo esc_attr( $column_name ); ?>">
<?php if ( has_action( 'woocommerce_my_account_my_orders_column_' . $column_id ) ) : ?>
<?php do_action( 'woocommerce_my_account_my_orders_column_' . $column_id, $order ); ?>
<?php elseif ( 'order-number' === $column_id ) : ?>
<a href="<?php echo esc_url( $order->get_view_order_url() ); ?>">
<?php echo esc_html( _x( '#', 'hash before order number', 'woocommerce' ) . $order->get_order_number() ); ?>
</a>
<?php elseif ( 'order-date' === $column_id ) : ?>
<time datetime="<?php echo esc_attr( $order->get_date_created()->date( 'c' ) ); ?>"><?php echo esc_html( wc_format_datetime( $order->get_date_created() ) ); ?></time>
<?php elseif ( 'order-status' === $column_id ) : ?>
<?php echo esc_html( wc_get_order_status_name( $order->get_status() ) ); ?>
<?php elseif ( 'order-total' === $column_id ) : ?>
<?php
/* translators: 1: formatted order total 2: total order items */
echo wp_kses_post( sprintf( _n( '%1$s for %2$s item', '%1$s for %2$s items', $item_count, 'woocommerce' ), $order->get_formatted_order_total(), $item_count ) );
?>
<?php elseif ( 'order-actions' === $column_id ) : ?>
<?php
$actions = wc_get_account_orders_actions( $order );
if ( ! empty( $actions ) ) {
foreach ( $actions as $key => $action ) { // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
echo '' . esc_html( $action['name'] ) . '';
}
}
?>
<?php endif; ?>
</td>
<?php endforeach; ?>
</tr>
<?php
}
?>
</tbody>
</table>
<?php
} else {
?>
<div class="woocommerce-message woocommerce-message--info woocommerce-Message woocommerce-Message--info woocommerce-info">
<a class="woocommerce-Button button" href="<?php echo esc_url( apply_filters( 'woocommerce_return_to_shop_redirect', wc_get_page_permalink( 'shop' ) ) ); ?>"><?php esc_html_e( 'Browse products', 'woocommerce' ); ?></a>
<?php esc_html_e( 'No order has been made yet.', 'woocommerce' ); ?>
</div>
<?php
}
}
add_action( 'woocommerce_account_dashboard', 'action_woocommerce_account_dashboard' );
Code goes in functions.php file of the active child theme (or active theme).
Related
Pagination stock log page
I'm using the stock manager plugin for Woo. Problem is that there is a lack of support , so I try to fix some problems myself. But now I'm stuck with pagination. I do only see 100 products , and on the bottom of the page there is no pagination visible , like it was in an earlier version. (I have over 500 active products) For me there are two possible solutions : or there is pagination per 100 products , or I can see al products on one page. The code used <?php /** * Stock Log page. * * #package woocommerce-stock-manager/admin/views/ * #version 2.8.0 */ if ( ! defined( 'ABSPATH' ) ) { exit; } $stock = $this->stock(); ?> <div class="wrap"> <h2><?php echo esc_html( get_admin_page_title() ); ?></h2> <div class="t-col-12"> <div class="toret-box box-info"> <div class="box-header"> <h3 class="box-title"></h3> </div> <div class="box-body"> <div class="clear"></div> <table class="table-bordered"> <tr> <th><?php esc_html_e( 'Product ID', 'woocommerce-stock-manager' ); ?></th> <th><?php esc_html_e( 'SKU', 'woocommerce-stock-manager' ); ?></th> <th><?php esc_html_e( 'Name', 'woocommerce-stock-manager' ); ?></th> <th><?php esc_html_e( 'Product type', 'woocommerce-stock-manager' ); ?></th> <th><?php esc_html_e( 'Parent ID', 'woocommerce-stock-manager' ); ?></th> <th><?php esc_html_e( 'Stock', 'woocommerce-stock-manager' ); ?></th> <th></th> </tr> <?php $get = ( ! empty( $_GET ) ) ? wc_clean( wp_unslash( $_GET ) ) : array(); // phpcs:ignore $products = ( ! empty( $get ) ) ? $stock->get_products( $get ) : array(); if ( ! empty( $products->posts ) ) { foreach ( $products->posts as $item ) { $item_product = wc_get_product( $item->ID ); if ( ! $item_product instanceof WC_Product ) { continue; } $product_type = $item_product->get_type(); ?> <tr> <td class="td_center"><?php echo esc_html( $item_product->get_id() ); ?></td> <td><?php echo esc_html( $item_product->get_sku() ); ?></td> <td> <a href="<?php echo esc_url( admin_url() . 'post.php?post=' . $item_product->get_id() . '&action=edit' ); ?>" target="_blank"> <?php echo wp_kses_post( get_the_title( $item_product->get_id() ) ); ?> </a> </td> <td class="td_center"><?php echo esc_html( $product_type ); ?></td> <td></td> <td class="td_center"><?php echo esc_html( $item_product->get_stock_quantity() ); ?></td> <td class="td_center"> <?php if ( 'variable' !== $product_type ) { ?> <a class="btn btn-success" href="<?php echo esc_url( admin_url() . 'admin.php?page=stock-manager-log&product-history=' . $item_product->get_id() ); ?>"><?php esc_html_e( 'History', 'woocommerce-stock-manager' ); ?></a> <?php } ?> </td> </tr> <?php if ( 'variable' === $product_type ) { $args = array( 'post_parent' => $item->ID, 'post_type' => 'product_variation', 'numberposts' => -1, 'post_status' => 'publish', 'order_by' => 'menu_order', ); $variations_array = $item_product->get_children(); foreach ( $variations_array as $vars ) { $item_product = wc_get_product( $vars ); if ( ! $item_product instanceof WC_Product ) { continue; } $product_type = 'product variation'; ?> <tr> <td class="td_center"><?php echo esc_html( $item_product->get_id() ); ?></td> <td><?php echo esc_html( $item_product->get_sku() ); ?></td> <td> <a href="<?php echo esc_url( admin_url() . 'post.php?post=' . $item_product->get_parent_id() . '&action=edit' ); ?>" target="_blank"> <?php echo wp_kses_post( get_the_title( $item_product->get_id() ) ); ?> </a> </td> <td class="td_center"><?php echo esc_html( $product_type ); ?></td> <td class="td_center"><?php echo esc_html( $item->ID ); ?></td> <td class="td_center"><?php echo esc_html( $item_product->get_stock_quantity() ); ?></td> <td class="td_center"> <a class="btn btn-success" href="<?php echo esc_url( admin_url() . 'admin.php?page=stock-manager-log&product-history=' . $item_product->get_id() ); ?>"><?php esc_html_e( 'History', 'woocommerce-stock-manager' ); ?></a> </td> </tr> <?php } } } } ?> </table> <div class="clear"></div> <?php echo wp_kses_post( $stock->pagination( $products ) ); ?> </div> </div> </div> <?php
How to open downloadable products in WooCommerce in new tab
I added a custom download link for my resellers to download product images. But I would like to add target="_blank" rel="noopener noreferrer" attributes to the link. Here's my custom download link: // Add a Custom Download File to My Account add_filter( 'woocommerce_customer_get_downloadable_products', 'my_custom_default_download', 9999, 1 ); function my_custom_default_download( $downloads ) { if ( is_admin() && !defined('DOING_AJAX') ) return; // Only on checkout page and logged in users if ( ! is_wc_endpoint_url() || ! is_user_logged_in() ) return; $wpuser_object = wp_get_current_user(); $allowed_roles = array( 'administrator', 'default_wholesaler', 'wholesaler-non-vat-registered', 'wholesaler-ex-vat-registered', 'wholesaler-ex-non-vat-registered', 'shop_manager'); if ( array_intersect($allowed_roles, $wpuser_object->roles) ){ $downloads[] = array( 'product_name' => 'Product Images (High Resolution)', 'download_name' => 'Download', 'download_url' => 'https://drive.google.com/drive/folders/', ); return $downloads; } } Here's the updated my-downloads.php file saved to my child theme: <?php defined( 'ABSPATH' ) || exit; $downloads = WC()->customer->get_downloadable_products(); if ( $downloads ) : ?> <?php do_action( 'woocommerce_before_available_downloads' ); ?> <h2><?php echo apply_filters( 'woocommerce_my_account_my_downloads_title', esc_html__( 'Available downloads', 'woocommerce' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></h2> <ul class="woocommerce-Downloads digital-downloads"> <?php foreach ( $downloads as $download ) : ?> <li> <?php do_action( 'woocommerce_available_download_start', $download ); if ( is_numeric( $download['downloads_remaining'] ) ) { /* translators: %s product name */ echo apply_filters( 'woocommerce_available_download_count', '<span class="woocommerce-Count count">' . sprintf( _n( '%s download remaining', '%s downloads remaining', $download['downloads_remaining'], 'woocommerce' ), $download['downloads_remaining'] ) . '</span> ', $download ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } echo apply_filters( 'woocommerce_available_download_link', '' . $download['download_name'] . '', $download ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped do_action( 'woocommerce_available_download_end', $download ); ?> </li> <?php endforeach; ?> </ul> <?php do_action( 'woocommerce_after_available_downloads' ); ?> <?php endif; ?>
You've got to update the order-downloads.php file not the my-downloads.php file and save it to the child theme. Here's the solution: <?php /** * Order Downloads. * * This template can be overridden by copying it to yourtheme/woocommerce/order/order-downloads.php. * * HOWEVER, on occasion WooCommerce will need to update template files and you * (the theme developer) will need to copy the new files to your theme to * maintain compatibility. We try to do this as little as possible, but it does * happen. When this occurs the version of the template file will be bumped and * the readme will list any important changes. * * #see https://docs.woocommerce.com/document/template-structure/ * #package WooCommerce\Templates * #version 3.3.0 */ if ( ! defined( 'ABSPATH' ) ) { exit; } ?> <section class="woocommerce-order-downloads"> <?php if ( isset( $show_title ) ) : ?> <h2 class="woocommerce-order-downloads__title"><?php esc_html_e( 'Downloads', 'woocommerce' ); ?></h2> <?php endif; ?> <table class="woocommerce-table woocommerce-table--order-downloads shop_table shop_table_responsive order_details"> <thead> <tr> <?php foreach ( wc_get_account_downloads_columns() as $column_id => $column_name ) : ?> <th class="<?php echo esc_attr( $column_id ); ?>"><span class="nobr"><?php echo esc_html( $column_name ); ?></span></th> <?php endforeach; ?> </tr> </thead> <?php foreach ( $downloads as $download ) : ?> <tr> <?php foreach ( wc_get_account_downloads_columns() as $column_id => $column_name ) : ?> <td class="<?php echo esc_attr( $column_id ); ?>" data-title="<?php echo esc_attr( $column_name ); ?>"> <?php if ( has_action( 'woocommerce_account_downloads_column_' . $column_id ) ) { do_action( 'woocommerce_account_downloads_column_' . $column_id, $download ); } else { switch ( $column_id ) { case 'download-product': if ( $download['product_url'] ) { echo '' . esc_html( $download['product_name'] ) . ''; } else { echo esc_html( $download['product_name'] ); } break; case 'download-file': echo '' . esc_html( $download['download_name'] ) . ''; break; case 'download-remaining': echo is_numeric( $download['downloads_remaining'] ) ? esc_html( $download['downloads_remaining'] ) : esc_html__( '∞', 'woocommerce' ); break; case 'download-expires': if ( ! empty( $download['access_expires'] ) ) { echo '<time datetime="' . esc_attr( date( 'Y-m-d', strtotime( $download['access_expires'] ) ) ) . '" title="' . esc_attr( strtotime( $download['access_expires'] ) ) . '">' . esc_html( date_i18n( get_option( 'date_format' ), strtotime( $download['access_expires'] ) ) ) . '</time>'; } else { esc_html_e( 'Never', 'woocommerce' ); } break; } } ?> </td> <?php endforeach; ?> </tr> <?php endforeach; ?> </table> </section>
Woocommerce Checkout page shows Order summary 2 times?
On the checkout page when user checkbox for the shipping details the order summary doubles. I have done many modifications in the in past. So i think i made mistake.On clicking shipping information checkbox. the order summary becomes double. only subtotal, shipping and total. I am providing review-order.php code. I think the problem is in after the end of table tag. <?php /** * Review order table * * This template can be overridden by copying it to yourtheme/woocommerce/checkout/review-order.php. * * HOWEVER, on occasion WooCommerce will need to update template files and you * (the theme developer) will need to copy the new files to your theme to * maintain compatibility. We try to do this as little as possible, but it does * happen. When this occurs the version of the template file will be bumped and * the readme will list any important changes. * * #see https://docs.woocommerce.com/document/template-structure/ * #package WooCommerce/Templates * #version 3.8.0 */ defined( 'ABSPATH' ) || exit; ?> <table class="shop_table woocommerce-checkout-review-order-table"> <thead> <tr> <th class="product-name"><?php esc_html_e( 'Product', 'woocommerce' ); ?></th> <th class="product-total"><?php esc_html_e( 'Subtotal', 'woocommerce' ); ?></th> </tr> </thead> <tbody> <?php do_action( 'woocommerce_review_order_before_cart_contents' ); foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_checkout_cart_item_visible', true, $cart_item, $cart_item_key ) ) { ?> <tr class="<?php echo esc_attr( apply_filters( 'woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key ) ); ?>"> <td class="product-name"> <?php echo apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key ) . ' '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> <?php echo apply_filters( 'woocommerce_checkout_cart_item_quantity', ' <strong class="product-quantity">' . sprintf( '× %s', $cart_item['quantity'] ) . '</strong>', $cart_item, $cart_item_key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> <?php echo wc_get_formatted_cart_item_data( $cart_item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> </td> <td class="product-total"> <?php echo apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> </td> </tr> <?php } } do_action( 'woocommerce_review_order_after_cart_contents' ); ?> </tbody> </table> <div class="cart-subtotal"> <h2><?php esc_html_e( 'Subtotal', 'woocommerce' ); ?></h2> <div class="order-detail-summary-item"><?php wc_cart_totals_subtotal_html(); ?></div> </div> <?php foreach ( WC()->cart->get_coupons() as $code => $coupon ) : ?> <div class="cart-discount coupon-<?php echo esc_attr( sanitize_title( $code ) ); ?>"> <h2><?php wc_cart_totals_coupon_label( $coupon ); ?></h2> <div class="order-detail-summary-item"><?php wc_cart_totals_coupon_html( $coupon ); ?></div> </div> <?php endforeach; ?> <h2>Shipping</h2> <?php if ( WC()->cart->needs_shipping() && WC()->cart->show_shipping() ) : ?> <?php do_action( 'woocommerce_review_order_before_shipping' ); ?> <?php wc_cart_totals_shipping_html(); ?> <?php do_action( 'woocommerce_review_order_after_shipping' ); ?> <?php endif; ?> <?php foreach ( WC()->cart->get_fees() as $fee ) : ?> <div class="fee"> <h2><?php echo esc_html( $fee->name ); ?></h2> <div class="order-detail-summary-item"><?php wc_cart_totals_fee_html( $fee ); ?></div> </div> <?php endforeach; ?> <?php if ( wc_tax_enabled() && ! WC()->cart->display_prices_including_tax() ) : ?> <?php if ( 'itemized' === get_option( 'woocommerce_tax_total_display' ) ) : ?> <?php foreach ( WC()->cart->get_tax_totals() as $code => $tax ) : // phpcs:ignore WordPress.WP.GlobalVariablesOverride.OverrideProhibited ?> <div class="tax-rate tax-rate-<?php echo esc_attr( sanitize_title( $code ) ); ?>"> <h2><?php echo esc_html( $tax->label ); ?></h2> <div class="order-detail-summary-item"><?php echo wp_kses_post( $tax->formatted_amount ); ?></div> </div> <?php endforeach; ?> <?php else : ?> <div class="tax-total"> <h2><?php echo esc_html( WC()->countries->tax_or_vat() ); ?></h2> <div class="order-detail-summary-item"><?php wc_cart_totals_taxes_total_html(); ?></div> </div> <?php endif; ?> <?php endif; ?> <?php do_action( 'woocommerce_review_order_before_order_total' ); ?> <div class="order-total"> <h2><?php esc_html_e( 'Total', 'woocommerce' ); ?></h2> <div class="order-detail-summary-item"><?php wc_cart_totals_order_total_html(); ?></div> </div> <?php do_action( 'woocommerce_review_order_after_order_total' ); ?>
Woocommerce Checkout page shows double Order summary? [duplicate]
On the checkout page when user checkbox for the shipping details the order summary doubles. I have done many modifications in the in past. So i think i made mistake.On clicking shipping information checkbox. the order summary becomes double. only subtotal, shipping and total. I am providing review-order.php code. I think the problem is in after the end of table tag. <?php /** * Review order table * * This template can be overridden by copying it to yourtheme/woocommerce/checkout/review-order.php. * * HOWEVER, on occasion WooCommerce will need to update template files and you * (the theme developer) will need to copy the new files to your theme to * maintain compatibility. We try to do this as little as possible, but it does * happen. When this occurs the version of the template file will be bumped and * the readme will list any important changes. * * #see https://docs.woocommerce.com/document/template-structure/ * #package WooCommerce/Templates * #version 3.8.0 */ defined( 'ABSPATH' ) || exit; ?> <table class="shop_table woocommerce-checkout-review-order-table"> <thead> <tr> <th class="product-name"><?php esc_html_e( 'Product', 'woocommerce' ); ?></th> <th class="product-total"><?php esc_html_e( 'Subtotal', 'woocommerce' ); ?></th> </tr> </thead> <tbody> <?php do_action( 'woocommerce_review_order_before_cart_contents' ); foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_checkout_cart_item_visible', true, $cart_item, $cart_item_key ) ) { ?> <tr class="<?php echo esc_attr( apply_filters( 'woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key ) ); ?>"> <td class="product-name"> <?php echo apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key ) . ' '; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> <?php echo apply_filters( 'woocommerce_checkout_cart_item_quantity', ' <strong class="product-quantity">' . sprintf( '× %s', $cart_item['quantity'] ) . '</strong>', $cart_item, $cart_item_key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> <?php echo wc_get_formatted_cart_item_data( $cart_item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> </td> <td class="product-total"> <?php echo apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> </td> </tr> <?php } } do_action( 'woocommerce_review_order_after_cart_contents' ); ?> </tbody> </table> <div class="cart-subtotal"> <h2><?php esc_html_e( 'Subtotal', 'woocommerce' ); ?></h2> <div class="order-detail-summary-item"><?php wc_cart_totals_subtotal_html(); ?></div> </div> <?php foreach ( WC()->cart->get_coupons() as $code => $coupon ) : ?> <div class="cart-discount coupon-<?php echo esc_attr( sanitize_title( $code ) ); ?>"> <h2><?php wc_cart_totals_coupon_label( $coupon ); ?></h2> <div class="order-detail-summary-item"><?php wc_cart_totals_coupon_html( $coupon ); ?></div> </div> <?php endforeach; ?> <h2>Shipping</h2> <?php if ( WC()->cart->needs_shipping() && WC()->cart->show_shipping() ) : ?> <?php do_action( 'woocommerce_review_order_before_shipping' ); ?> <?php wc_cart_totals_shipping_html(); ?> <?php do_action( 'woocommerce_review_order_after_shipping' ); ?> <?php endif; ?> <?php foreach ( WC()->cart->get_fees() as $fee ) : ?> <div class="fee"> <h2><?php echo esc_html( $fee->name ); ?></h2> <div class="order-detail-summary-item"><?php wc_cart_totals_fee_html( $fee ); ?></div> </div> <?php endforeach; ?> <?php if ( wc_tax_enabled() && ! WC()->cart->display_prices_including_tax() ) : ?> <?php if ( 'itemized' === get_option( 'woocommerce_tax_total_display' ) ) : ?> <?php foreach ( WC()->cart->get_tax_totals() as $code => $tax ) : // phpcs:ignore WordPress.WP.GlobalVariablesOverride.OverrideProhibited ?> <div class="tax-rate tax-rate-<?php echo esc_attr( sanitize_title( $code ) ); ?>"> <h2><?php echo esc_html( $tax->label ); ?></h2> <div class="order-detail-summary-item"><?php echo wp_kses_post( $tax->formatted_amount ); ?></div> </div> <?php endforeach; ?> <?php else : ?> <div class="tax-total"> <h2><?php echo esc_html( WC()->countries->tax_or_vat() ); ?></h2> <div class="order-detail-summary-item"><?php wc_cart_totals_taxes_total_html(); ?></div> </div> <?php endif; ?> <?php endif; ?> <?php do_action( 'woocommerce_review_order_before_order_total' ); ?> <div class="order-total"> <h2><?php esc_html_e( 'Total', 'woocommerce' ); ?></h2> <div class="order-detail-summary-item"><?php wc_cart_totals_order_total_html(); ?></div> </div> <?php do_action( 'woocommerce_review_order_after_order_total' ); ?>
WooCommerce - Adding product category to order-details table
Here's what I'm attempting to do and where. In the check out process for an order, in the plug-in WooCommerce; you are taken to a page when the check out is process is complete. It displays an overview of the order details. The template file used to output this page is order-details.php. Here's what I'd like to add I would like to display the product's product category like so: This is area of code I'm attempting to add to, the first section of the order details table. <tbody> <?php if ( sizeof( $order->get_items() ) > 0 ) { foreach( $order->get_items() as $item ) { $_product = apply_filters( 'woocommerce_order_item_product', $order->get_product_from_item( $item ), $item ); $item_meta = new WC_Order_Item_Meta( $item['item_meta'], $_product ); ?> <tr class="<?php echo esc_attr( apply_filters( 'woocommerce_order_item_class', 'order_item', $item, $order ) ); ?>"> <td class="product-name"> <?php if ( $_product && ! $_product->is_visible() ) echo apply_filters( 'woocommerce_order_item_name', $item['name'], $item ); else echo apply_filters( 'woocommerce_order_item_name', sprintf( '%s', get_permalink( $item['product_id'] ), $item['name'] ), $item ); echo apply_filters( 'woocommerce_order_item_quantity_html', ' <strong class="product-quantity">' . sprintf( '× %s', $item['qty'] ) . '</strong>', $item ); This is my understanding so far; That a custom query is being applied. That for each product listed details are being echoed. That a WooCommerce Class is being used to get specific product meta. My understandings are observations at my current knowledge level. What I was hoping was that I could use something like echo apply_filters( 'woocommerce_order_item_name', ' <strong class="product-category">' . e_( $item['product_cat'] ) . '</strong>', $item ); I can't find a more relevant filter and I'm really not sure that ['product_cat'] is even relevant here. This is an example of the way I'm attempting to solve my requirement. As you can tell, I don't work in PHP full time. I'm learning as much as I can when I can. Advise would be greatly appreciated
This is how you might add the product categories to the Product title. I don't particularly like how it is outputting for me, but then I am testing it on a variable subscription, so that is amending its own data. This would go in your theme's functions.php function kia_woocommerce_order_item_name( $name, $item ){ $product_id = $item['product_id']; $tax = 'product_cat'; $terms = wp_get_post_terms( $product_id, $tax, array( 'fields' => 'names' ) ); if( $terms && ! is_wp_error( $terms )) { $taxonomy = get_taxonomy($tax); $name .= '<label>' . $taxonomy->label . ': </label>' . implode( ', ', $terms ); } return $name; } add_filter( 'woocommerce_order_item_name', 'kia_woocommerce_order_item_name', 10, 2 ); Otherwise you could copy the order-details.php template into your own theme (so yourtheme/woocommerce/order/order-details.php and add the code directly. This would give you more control over where you want the category to appear since there aren't a lot of hooks available in this section, but put you at risk if WooCommerce ever modifies this code. I have worked on a few sites that broke because the the theme was using outdated template. Any way, an example would be: <?php /** * Order details * * #author WooThemes * #package WooCommerce/Templates * #version 2.2.0 */ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly global $woocommerce; $order = new WC_Order( $order_id ); ?> <h2><?php _e( 'Order Details', 'woocommerce' ); ?></h2> <table class="shop_table order_details"> <thead> <tr> <th class="product-name"><?php _e( 'Product', 'woocommerce' ); ?></th> <th class="product-total"><?php _e( 'Total', 'woocommerce' ); ?></th> </tr> </thead> <tfoot> <?php if ( $totals = $order->get_order_item_totals() ) foreach ( $totals as $total ) : ?> <tr> <th scope="row"><?php echo $total['label']; ?></th> <td><?php echo $total['value']; ?></td> </tr> <?php endforeach; ?> </tfoot> <tbody> <?php if ( sizeof( $order->get_items() ) > 0 ) { foreach( $order->get_items() as $item ) { $_product = apply_filters( 'woocommerce_order_item_product', $order->get_product_from_item( $item ), $item ); $item_meta = new WC_Order_Item_Meta( $item['item_meta'], $_product ); ?> <tr class="<?php echo esc_attr( apply_filters( 'woocommerce_order_item_class', 'order_item', $item, $order ) ); ?>"> <td class="product-name"> <?php if ( $_product && ! $_product->is_visible() ) echo apply_filters( 'woocommerce_order_item_name', $item['name'], $item ); else echo apply_filters( 'woocommerce_order_item_name', sprintf( '%s', get_permalink( $item['product_id'] ), $item['name'] ), $item ); echo apply_filters( 'woocommerce_order_item_quantity_html', ' <strong class="product-quantity">' . sprintf( '× %s', $item['qty'] ) . '</strong>', $item ); $item_meta->display(); // insert product category here $tax = 'product_cat'; $terms = wp_get_post_terms( $_product->id, $tax, array( 'fields' => 'names' ) ); if( $terms && ! is_wp_error( $terms )) { $taxonomy = get_taxonomy($tax); echo '<strong>' . $taxonomy->label . ': </strong>' . implode( ', ', $terms ); } // end edit if ( $_product && $_product->exists() && $_product->is_downloadable() && $order->is_download_permitted() ) { $download_files = $order->get_item_downloads( $item ); $i = 0; $links = array(); foreach ( $download_files as $download_id => $file ) { $i++; $links[] = '<small>' . sprintf( __( 'Download file%s', 'woocommerce' ), ( count( $download_files ) > 1 ? ' ' . $i . ': ' : ': ' ) ) . esc_html( $file['name'] ) . '</small>'; } echo '<br/>' . implode( '<br/>', $links ); } ?> </td> <td class="product-total"> <?php echo $order->get_formatted_line_subtotal( $item ); ?> </td> </tr> <?php if ( $order->has_status( array( 'completed', 'processing' ) ) && ( $purchase_note = get_post_meta( $_product->id, '_purchase_note', true ) ) ) { ?> <tr class="product-purchase-note"> <td colspan="3"><?php echo wpautop( do_shortcode( $purchase_note ) ); ?></td> </tr> <?php } } } do_action( 'woocommerce_order_items_table', $order ); ?> </tbody> </table> <?php do_action( 'woocommerce_order_details_after_order_table', $order ); ?> <header> <h2><?php _e( 'Customer details', 'woocommerce' ); ?></h2> </header> <dl class="customer_details"> <?php if ( $order->billing_email ) echo '<dt>' . __( 'Email:', 'woocommerce' ) . '</dt><dd>' . $order->billing_email . '</dd>'; if ( $order->billing_phone ) echo '<dt>' . __( 'Telephone:', 'woocommerce' ) . '</dt><dd>' . $order->billing_phone . '</dd>'; // Additional customer details hook do_action( 'woocommerce_order_details_after_customer_details', $order ); ?> </dl> <?php if ( ! wc_ship_to_billing_address_only() && $order->needs_shipping_address() && get_option( 'woocommerce_calc_shipping' ) !== 'no' ) : ?> <div class="col2-set addresses"> <div class="col-1"> <?php endif; ?> <header class="title"> <h3><?php _e( 'Billing Address', 'woocommerce' ); ?></h3> </header> <address><p> <?php if ( ! $order->get_formatted_billing_address() ) _e( 'N/A', 'woocommerce' ); else echo $order->get_formatted_billing_address(); ?> </p></address> <?php if ( ! wc_ship_to_billing_address_only() && $order->needs_shipping_address() && get_option( 'woocommerce_calc_shipping' ) !== 'no' ) : ?> </div><!-- /.col-1 --> <div class="col-2"> <header class="title"> <h3><?php _e( 'Shipping Address', 'woocommerce' ); ?></h3> </header> <address><p> <?php if ( ! $order->get_formatted_shipping_address() ) _e( 'N/A', 'woocommerce' ); else echo $order->get_formatted_shipping_address(); ?> </p></address> </div><!-- /.col-2 --> </div><!-- /.col2-set --> <?php endif; ?> <div class="clear"></div>