Wordpress Mini Cart auto qty update not working - php

I am facing an error ajax load in the Woocommerce Mini cart qty + - Not refresh price when I clicking + -
My WordPress version 5.4.1 and Woocommerce Version 4.1.1
My mini-cart.php code is below :
Please help what I did wrong it's custom mini-cart.php I have created, thanks in advance, I really appreciate if anyone can help me
My website URL:https://wmiserver.com/bulkwholesale/
<?php
/**
* Mini-cart
*
* Contains the markup for the mini-cart, used by the cart widget.
*
* This template can be overridden by copying it to yourtheme/woocommerce/cart/mini-cart.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.7.0
*/
defined( 'ABSPATH' ) || exit;
do_action( 'woocommerce_before_mini_cart' ); ?>
<?php if ( ! WC()->cart->is_empty() ) : ?>
<div class="widget_shopping_cart_body kapee-scroll">
<div class="kapee-scroll-content">
<div class="cart-countdown-empty">
<?php echo do_shortcode('[checkout_countdown]');?>
</div>
<ul class="woocommerce-mini-cart cart_list product_list_widget <?php echo esc_attr( $args['list_class'] ); ?>">
<?php
do_action( 'woocommerce_before_mini_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 );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_widget_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
$product_name = apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key );
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
$product_price = apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
$product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key );
?>
<li class="woocommerce-mini-cart-item <?php echo esc_attr( apply_filters( 'woocommerce_mini_cart_item_class', 'mini_cart_item', $cart_item, $cart_item_key ) ); ?>">
<?php
echo apply_filters( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'woocommerce_cart_item_remove_link',
sprintf(
'<i class="fa fa-trash"></i>',
esc_url( wc_get_cart_remove_url( $cart_item_key ) ),
esc_html__( 'Remove this item', 'kapee' ),
esc_attr( $product_id ),
esc_attr( $cart_item_key ),
esc_attr( $_product->get_sku() )
),
$cart_item_key
);
?>
<?php if ( empty( $product_permalink ) ) : ?>
<?php echo wp_kses_post( $thumbnail ); ?>
<?php else : ?>
<a class="mini_cart_item_image" href="<?php echo esc_url( $product_permalink ); ?>">
<?php echo wp_kses_post( $thumbnail ); ?>
</a>
<?php endif; ?>
<div class="mini-cart-item-content">
<?php if ( empty( $product_permalink ) ) : ?>
<?php echo wp_kses_post( $product_name ); ?>
<?php else : ?>
<a class="mini_cart_item_image" href="<?php echo esc_url( $product_permalink ); ?>">
<?php echo wp_kses_post( $product_name ); ?>
</a>
<?php endif; ?>
<?php echo wc_get_formatted_cart_item_data( $cart_item ); ?>
<?php echo apply_filters( 'woocommerce_widget_cart_item_quantity', '<span class="quantity">' . sprintf( '%s × %s', $cart_item['quantity'], $product_price ) . '</span>', $cart_item, $cart_item_key ); ?>
<? echo do_shortcode('[quantity_minicart]');?>
</div>
</li>
<? }
}
?>
<div class="minicart-upsell">
<div class="upsell-tittle">
<span>Boost your results with:</span>
</div>
<?
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 );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
$product = new WC_Product($_product );
$upsells = $product->get_upsell_ids();
if ($upsells){
$meta_query = WC()-> query -> get_meta_query( $meta_query, $main_query );
$args = array(
'status'=>'publish',
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'posts_per_page' => $posts_per_page,
'orderby' => $orderby,
'post__in' => $upsells,
'post__not_in' => array($product-> get_id() ),
'meta_query' =>array($meta_query),
);
$products = new WP_Query( $args );
if ( $products->have_posts() ) : ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php wc_get_template_part( 'cart/upsell', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php endif;
}}
?>
</div>
<?
do_action( 'woocommerce_mini_cart_contents' );
?>
</ul><div class="mini-cart-footer-block"><?php echo do_shortcode('[sc name="cart-icon-box"]'); ?></div>
</div>
</div>
<div class="widget_shopping_cart_footer">
<div class="woocommerce-mini-cart__total total">
<?php
/**
* Woocommerce_widget_shopping_cart_total hook.
*
* #hooked woocommerce_widget_shopping_cart_subtotal - 10
*/
?><div class="saving"><? echo do_shortcode('[mini_cart_discount]');?></div>
<div class="subtotal"><? do_action( 'woocommerce_widget_shopping_cart_total' );
?></div>
</div>
<?php do_action( 'woocommerce_widget_shopping_cart_before_buttons' ); ?>
<p class="woocommerce-mini-cart__buttons buttons"><?php do_action( 'woocommerce_widget_shopping_cart_buttons' ); ?></p>
<?php do_action( 'woocommerce_widget_shopping_cart_after_buttons' ); ?>
</div>
<?php else : ?>
<div class="woocommerce-mini-cart-empty">
<i class="cart-empty-icon"></i>
<p class="woocommerce-mini-cart__empty-message"><?php esc_html_e( 'No products in the cart.', 'kapee' ); ?></p>
<?php do_action( 'kapee_after_empty_mini_cart' ); ?>
</div>
<?php endif; ?>
<?php do_action( 'woocommerce_after_mini_cart' ); ?>

Related

How to show the tag/s product in review order tab in woocommerce

I'm trying to show next to each single product its tag or tags in the review order table.
This is my code in override review-order.php but doesn't work.
From my review-order.php:
<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 wp_kses_post( apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key ) ) . ' '; ?>
</td>
<td>
<?php echo apply_filters( 'woocommerce_checkout_cart_item_quantity', ' <strong class="product-quantity">' . sprintf( 'nº %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>
<?php
$terms = get_terms( 'product_tag' );
$term_array = array();
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
foreach ( $terms as $term ) {
$term_array[] = $term->name;
}
}
if( in_array( 'bird', $term_array ) ) {
echo 'Bird';
}
elseif( in_array( 'dog', $term_array ) ) {
echo 'Dog';
}
else {
echo 'not exists animal';
}
?>
</td>
</tr>
<?php
}
}
do_action( 'woocommerce_review_order_after_cart_contents' );
?>
</tbody>
This return only "not exists animal".
Obviously something wrong! But I can't figure out what.
Better would be work in the custom woocommerce-functions.php I have, but once again I don't know how.
Thanks for any help!
Solved!
Based on this question and its answers:
Display Woocommerce Product Category on cart and checkout page
watching also the answer with no vote and using a bit of imagination this below is the working code. To complete the test, I added the product category in addition to the tag. I hope it will be helpful to someone.
This is my overwritten order-review.php template now.
<?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 5.2.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-name"><?php esc_html_e( 'Quantity', 'woocommerce' ); ?></th>
<th class="product-name"><?php esc_html_e( 'Tag', 'woocommerce' ); ?></th>
<th class="product-name"><?php esc_html_e( 'Category', '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 );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $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 wp_kses_post( apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key ) ) . ' '; ?>
</td>
<td>
<?php echo apply_filters( 'woocommerce_checkout_cart_item_quantity', ' <strong class="product-quantity">' . sprintf( 'nº %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>
<?php
$terms = get_the_terms( $product_id, 'product_tag' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
foreach ($terms as $term) {
$product_tag = $term->name;
}
echo $product_tag ;
}
?>
</td>
<td>
<?php
$terms = get_the_terms( $product_id, 'product_cat' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
foreach ($terms as $term) {
$product_cat = $term->name;
}
echo $product_cat ;
}
?>
</td>
</tr>
<?php
}
}
do_action( 'woocommerce_review_order_after_cart_contents' );
?>
</tbody>
</table>
Just to be clear notice that:
I added this code(from cart.php)
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
and this in the loop
<td>
<?php
$terms = get_the_terms( $product_id, 'product_tag' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
foreach ($terms as $term) {
$product_tag = $term->name;
}
echo $product_tag ;
}
?>
</td>
<td>
<?php
$terms = get_the_terms( $product_id, 'product_cat' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
foreach ($terms as $term) {
$product_cat = $term->name;
}
echo $product_cat ;
}
?>
</td>
Here it is!

add product quantity input modifier in woocommerce mini-cart.php

in the woocommerce mini-cart I'd like to display an input to adjust the quantity of each product.
I added line in the mini-cart.php file of my Storefront child theme (using the function woocommerce_quantity_input), it displays the input, but the cart is not 'updated'.
Any idea how to do this?
See the last line of:
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 );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_widget_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
$product_name = apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key );
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
$product_price = apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
$product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key );
?>
<li class="woocommerce-mini-cart-item <?php echo esc_attr( apply_filters( 'woocommerce_mini_cart_item_class', 'mini_cart_item', $cart_item, $cart_item_key ) ); ?>">
<?php
//split product name and color
$pattern = '/ [^a-zA-Z0-9 ]+| –/';
$matches = array();
$dummy = preg_match($pattern, $product_name, $matches);
$posi = strpos($product_name, $matches[0]);
$productnamename = substr($product_name, 0, $posi);
$dashAndProductcolor = substr($product_name, $posi);
?>
<?php if ( empty( $product_permalink ) ) : ?>
<?php echo $thumbnail; ?>
<?php echo '<span class="minicart-prod-name">'.$productnamename.'</span><br/>' ?>
<?php echo '<span class="minicart-prod-color">'.$dashAndProductcolor.'</span>' ?>
<?php else : ?>
<a href="<?php echo esc_url( $product_permalink ); ?>">
<?php echo $thumbnail; ?>
<?php echo '<span class="minicart-prod-name">'.$productnamename.'</span><br/>' ?>
<?php echo wc_get_formatted_cart_item_data( $cart_item ); ?>
<?php echo '<span class="minicart-prod-color">'.$dashAndProductcolor.'</span>' ?>
</a>
<?php echo apply_filters( 'woocommerce_widget_cart_item_quantity', '<span class="each-price">' . sprintf( '%s', $product_price ) . '</span>', $cart_item, $cart_item_key ); ?>
<?php endif; ?>
<?php echo apply_filters( 'woocommerce_widget_cart_item_quantity', '<span class="quantity">' . sprintf( '%s', $cart_item['quantity'] ) . '</span>', $cart_item, $cart_item_key ); ?>
<?php
echo woocommerce_quantity_input( array('input_value' => $cart_item['quantity']),$cart_item['data'], false );
?>

How to split woocommerce cart page based on product categories

Thanks you for your help. I have a very unique requirement for woocommerce cart page. What i want is to split products based on categories. For example:
Category name 1:
product 1
product 2
product 3
Category name 2:
product 1
product 2
product 3
Assumptions: Each product is assigned a single category, so i want to pull all the categories and display products which is in that category.
I have tried using the following code but it display all the categories.
Your help will be highly appreciated.
<?php
/**
* Cart Page
*
* This template can be overridden by copying it to yourtheme/woocommerce/cart/cart.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.7.0
*/
defined( 'ABSPATH' ) || exit;
do_action( 'woocommerce_before_cart' ); ?>
<style>
table {
position: relative;
}
form.woocommerce-cart-form {
font-size: 0;
}
td.aa {
width: 100% !important;
position: absolute;
border: 0 !IMPORTANT;
padding: 4px !IMPORTANT;
font-size: 23px !important;
background: #28d18b;
color: #fff;
text-align: center;
display: none !Important;
}
</style>
<form class="woocommerce-cart-form" action="<?php echo esc_url( wc_get_cart_url() ); ?>" method="post">
<?php do_action( 'woocommerce_before_cart_table' ); ?>
<table class="shop_table shop_table_responsive cart woocommerce-cart-form__contents" cellspacing="0">
<thead>
<tr>
<th class="product-remove"> </th>
<th class="product-thumbnail"> </th>
<th class="product-name"><?php esc_html_e( 'Product', 'woocommerce' ); ?></th>
<th class="product-price"><?php esc_html_e( 'Price', 'woocommerce' ); ?></th>
<th class="product-quantity"><?php esc_html_e( 'Quantity', 'woocommerce' ); ?></th>
<th class="product-subtotal"><?php esc_html_e( 'Total', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<?php do_action( 'woocommerce_before_cart_contents' ); ?>
<?php
$args = array(
'taxonomy' => 'product_cat',
'orderby' => 'name',
'show_count' => '0',
'pad_counts' => '0',
'hide_empty' => '0'
);
$cats = get_categories( $args );
foreach ($cats as $cat) {
$category_id = $cat->term_id;
echo "<tr>";
echo "<td class='aa'>";
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( has_term( $category_id, 'product_cat', $cart_item['product_id'] ) ) {
echo $cat->name ;
$_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
$product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key );
?>
<tr class="woocommerce-cart-form__cart-item <?php echo esc_attr( apply_filters( 'woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key ) ); ?>">
<td class="product-remove">
<?php
echo apply_filters( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'woocommerce_cart_item_remove_link',
sprintf(
'×',
esc_url( wc_get_cart_remove_url( $cart_item_key ) ),
esc_html__( 'Remove this item', 'woocommerce' ),
esc_attr( $product_id ),
esc_attr( $_product->get_sku() )
),
$cart_item_key
);
?>
</td>
<td class="product-thumbnail">
<?php
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
if ( ! $product_permalink ) {
echo $thumbnail; // PHPCS: XSS ok.
} else {
printf( '%s', esc_url( $product_permalink ), $thumbnail ); // PHPCS: XSS ok.
}
?>
</td>
<td class="product-name" data-title="<?php esc_attr_e( 'Product', 'woocommerce' ); ?>">
<?php
if ( ! $product_permalink ) {
echo wp_kses_post( apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key ) . ' ' );
} else {
echo wp_kses_post( apply_filters( 'woocommerce_cart_item_name', sprintf( '%s', esc_url( $product_permalink ), $_product->get_name() ), $cart_item, $cart_item_key ) );
}
do_action( 'woocommerce_after_cart_item_name', $cart_item, $cart_item_key );
// Meta data.
echo wc_get_formatted_cart_item_data( $cart_item ); // PHPCS: XSS ok.
// Backorder notification.
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) {
echo wp_kses_post( apply_filters( 'woocommerce_cart_item_backorder_notification', '<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'woocommerce' ) . '</p>', $product_id ) );
}
?>
</td>
<td class="product-price" data-title="<?php esc_attr_e( 'Price', 'woocommerce' ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key ); // PHPCS: XSS ok.
?>
</td>
<td class="product-quantity" data-title="<?php esc_attr_e( 'Quantity', 'woocommerce' ); ?>">
<?php
if ( $_product->is_sold_individually() ) {
$product_quantity = sprintf( '1 <input type="hidden" name="cart[%s][qty]" value="1" />', $cart_item_key );
} else {
$product_quantity = woocommerce_quantity_input(
array(
'input_name' => "cart[{$cart_item_key}][qty]",
'input_value' => $cart_item['quantity'],
'max_value' => $_product->get_max_purchase_quantity(),
'min_value' => '0',
'product_name' => $_product->get_name(),
),
$_product,
false
);
}
echo apply_filters( 'woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item ); // PHPCS: XSS ok.
?>
</td>
<td class="product-subtotal" data-title="<?php esc_attr_e( 'Total', 'woocommerce' ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key ); // PHPCS: XSS ok.
?>
</td>
</tr>
<?php
}
}
}
echo "</td>";
echo "</tr>";
}
?>
</tbody>
</table>
<table class="shop_table shop_table_responsive cart woocommerce-cart-form__contents" cellspacing="0">
<tbody>
<?php do_action( 'woocommerce_cart_contents' ); ?>
<tr>
<td colspan="6" class="actions">
<?php if ( wc_coupons_enabled() ) { ?>
<div class="coupon">
<label for="coupon_code"><?php esc_html_e( 'Coupon:', 'woocommerce' ); ?></label> <input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="<?php esc_attr_e( 'Coupon code', 'woocommerce' ); ?>" /> <button type="submit" class="button" name="apply_coupon" value="<?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?>"><?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?></button>
<?php do_action( 'woocommerce_cart_coupon' ); ?>
</div>
<?php } ?>
<button type="submit" class="button" name="update_cart" value="<?php esc_attr_e( 'Update cart', 'woocommerce' ); ?>"><?php esc_html_e( 'Update cart', 'woocommerce' ); ?></button>
<?php do_action( 'woocommerce_cart_actions' ); ?>
<?php wp_nonce_field( 'woocommerce-cart', 'woocommerce-cart-nonce' ); ?>
</td>
</tr>
<?php do_action( 'woocommerce_after_cart_contents' ); ?>
</tbody>
</table>
<?php do_action( 'woocommerce_after_cart_table' ); ?>
</form>
<?php do_action( 'woocommerce_before_cart_collaterals' ); ?>
<div class="cart-collaterals">
<?php
/**
* Cart collaterals hook.
*
* #hooked woocommerce_cross_sell_display
* #hooked woocommerce_cart_totals - 10
*/
do_action( 'woocommerce_cart_collaterals' );
?>
</div>
<?php do_action( 'woocommerce_after_cart' ); ?>
Override cart.php template first, after then just replace table <tbody></tbody> section with follows -
<tbody>
<?php do_action( 'woocommerce_before_cart_contents' ); ?>
<?php
$cat_wisw_pros = array();
foreach ( WC()->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 ) {
$term = get_term( $cat_id, 'product_cat' );
?>
<tr>
<td colspan="6" class=""><strong><?php echo $term->name; ?></strong></td>
</tr>
<?php
foreach ( $cart_items as $cart_item_key => $cart_item ) {
if( !array_key_exists( $cart_item_key, $grouped_cart_items ) ) {
$_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
$product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key );
?>
<tr class="woocommerce-cart-form__cart-item <?php echo esc_attr( apply_filters( 'woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key ) ); ?>">
<td class="product-remove">
<?php
echo apply_filters( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'woocommerce_cart_item_remove_link',
sprintf(
'×',
esc_url( wc_get_cart_remove_url( $cart_item_key ) ),
esc_html__( 'Remove this item', 'woocommerce' ),
esc_attr( $product_id ),
esc_attr( $_product->get_sku() )
),
$cart_item_key
);
?>
</td>
<td class="product-thumbnail">
<?php
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
if ( ! $product_permalink ) {
echo $thumbnail; // PHPCS: XSS ok.
} else {
printf( '%s', esc_url( $product_permalink ), $thumbnail ); // PHPCS: XSS ok.
}
?>
</td>
<td class="product-name" data-title="<?php esc_attr_e( 'Product', 'woocommerce' ); ?>">
<?php
if ( ! $product_permalink ) {
echo wp_kses_post( apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key ) . ' ' );
} else {
echo wp_kses_post( apply_filters( 'woocommerce_cart_item_name', sprintf( '%s', esc_url( $product_permalink ), $_product->get_name() ), $cart_item, $cart_item_key ) );
}
do_action( 'woocommerce_after_cart_item_name', $cart_item, $cart_item_key );
// Meta data.
echo wc_get_formatted_cart_item_data( $cart_item ); // PHPCS: XSS ok.
// Backorder notification.
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) {
echo wp_kses_post( apply_filters( 'woocommerce_cart_item_backorder_notification', '<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'woocommerce' ) . '</p>', $product_id ) );
}
?>
</td>
<td class="product-price" data-title="<?php esc_attr_e( 'Price', 'woocommerce' ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key ); // PHPCS: XSS ok.
?>
</td>
<td class="product-quantity" data-title="<?php esc_attr_e( 'Quantity', 'woocommerce' ); ?>">
<?php
if ( $_product->is_sold_individually() ) {
$product_quantity = sprintf( '1 <input type="hidden" name="cart[%s][qty]" value="1" />', $cart_item_key );
} else {
$product_quantity = woocommerce_quantity_input(
array(
'input_name' => "cart[{$cart_item_key}][qty]",
'input_value' => $cart_item['quantity'],
'max_value' => $_product->get_max_purchase_quantity(),
'min_value' => '0',
'product_name' => $_product->get_name(),
),
$_product,
false
);
}
echo apply_filters( 'woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item ); // PHPCS: XSS ok.
?>
</td>
<td class="product-subtotal" data-title="<?php esc_attr_e( 'Total', 'woocommerce' ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key ); // PHPCS: XSS ok.
?>
</td>
</tr>
<?php
}
}
}
}
?>
<?php do_action( 'woocommerce_cart_contents' ); ?>
<tr>
<td colspan="6" class="actions">
<?php if ( wc_coupons_enabled() ) { ?>
<div class="coupon">
<label for="coupon_code"><?php esc_html_e( 'Coupon:', 'woocommerce' ); ?></label> <input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="<?php esc_attr_e( 'Coupon code', 'woocommerce' ); ?>" /> <button type="submit" class="button" name="apply_coupon" value="<?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?>"><?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?></button>
<?php do_action( 'woocommerce_cart_coupon' ); ?>
</div>
<?php } ?>
<button type="submit" class="button" name="update_cart" value="<?php esc_attr_e( 'Update cart', 'woocommerce' ); ?>"><?php esc_html_e( 'Update cart', 'woocommerce' ); ?></button>
<?php do_action( 'woocommerce_cart_actions' ); ?>
<?php wp_nonce_field( 'woocommerce-cart', 'woocommerce-cart-nonce' ); ?>
</td>
</tr>
<?php do_action( 'woocommerce_after_cart_contents' ); ?>
</tbody>

Ajax refreshing custom mini-cart count and content in Woocommerce

I'm trying to make my custom mini-cart. Cart should be updated without page reload(ajax) after item removing, but it is not happens, I have infinite load on front-end and see changes only after page reload.
My mini-cart action
function my_wc_mini_cart() {
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
$count = WC()->cart->cart_contents_count;
$cart = WC()->cart->get_cart();
?>
<?php _e('Cart', 'frosted'); ?> <span class="cart__amount"><?php echo esc_html( $count ); ?></span>
<div class="sub-menu sub-menu--right sub-menu--cart">
<?php
foreach ( $cart as $cart_item_key => $cart_item ):
$_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_widget_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
$product_name = apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key );
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
$product_price = apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
$variation_val = $cart_item['variation']['attribute_pa_size'];
$term_obj = get_term_by('slug', $variation_val, 'pa_size');
$size_name = $term_obj->name;
?>
<div class="media mini-cart__item woocommerce-mini-cart-item <?php echo esc_attr( apply_filters( 'woocommerce_mini_cart_item_class', 'mini_cart_item', $cart_item, $cart_item_key ) ); ?>">
<?php echo $thumbnail; ?>
<div class="media-body mini-cart__item_body">
<div class="mini-cart__item__heading mt-0"><?php echo $product_name; ?></div>
<?php
echo apply_filters( 'woocommerce_widget_cart_item_quantity', '<div class="cart__item__price">' . sprintf( '%s × %s', $cart_item['quantity'], $product_price ) . '</div>', $cart_item, $cart_item_key ); ?>
<div class="mini-cart__item__size"><?php echo $size_name; ?></div>
</div>
<div class="mini-cart__item_remove ">
<?php
echo apply_filters( 'woocommerce_cart_item_remove_link', sprintf(
'×',
esc_url( wc_get_cart_remove_url( $cart_item_key ) ),
__( 'Remove this item', 'woocommerce' ),
esc_attr( $product_id ),
esc_attr( $cart_item_key ),
esc_attr( $_product->get_sku() )
), $cart_item_key );
?>
</div>
</div>
<?php } ?>
<?php endforeach; ?>
<span class="btn__text"><?php _e('Checkout', 'frosted'); ?></span>
</div>
<?php
}
}
add_action( 'frosted_header_top', 'my_wc_mini_cart' );
Action for updating cart using ajax, maybe I'm suing wrong hook...
function my_header_add_to_cart_fragment( $fragments ) {
ob_start();
$count = WC()->cart->cart_contents_count;
$cart = WC()->cart->get_cart();
?>
<?php _e('Cart', 'frosted'); ?> <span class="cart__amount"><?php echo esc_html( $count ); ?></span>
<div class="sub-menu sub-menu--right sub-menu--cart">
<?php
foreach ( $cart as $cart_item_key => $cart_item ):
$_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_widget_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
$product_name = apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key );
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
$product_price = apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
$variation_val = $cart_item['variation']['attribute_pa_size'];
$term_obj = get_term_by('slug', $variation_val, 'pa_size');
$size_name = $term_obj->name;
?>
<div class="media mini-cart__item woocommerce-mini-cart-item <?php echo esc_attr( apply_filters( 'woocommerce_mini_cart_item_class', 'mini_cart_item', $cart_item, $cart_item_key ) ); ?>">
<?php echo $thumbnail; ?>
<div class="media-body mini-cart__item_body">
<div class="mini-cart__item__heading mt-0"><?php echo $product_name; ?></div>
<?php
echo apply_filters( 'woocommerce_widget_cart_item_quantity', '<div class="cart__item__price">' . sprintf( '%s × %s', $cart_item['quantity'], $product_price ) . '</div>', $cart_item, $cart_item_key ); ?>
<div class="mini-cart__item__size"><?php echo $size_name; ?></div>
</div>
<div class="mini-cart__item_remove">
<?php
echo apply_filters( 'woocommerce_cart_item_remove_link', sprintf(
'×',
esc_url( wc_get_cart_remove_url( $cart_item_key ) ),
__( 'Remove this item', 'woocommerce' ),
esc_attr( $product_id ),
esc_attr( $cart_item_key ),
esc_attr( $_product->get_sku() )
), $cart_item_key );
?>
</div>
</div>
<?php } ?>
<?php endforeach; ?>
<span class="btn__text"><?php _e('Checkout', 'frosted'); ?></span>
</div>
<?php
$fragments['a.cart-contents'] = ob_get_clean();
return $fragments;
}
add_filter( 'woocommerce_add_to_cart_fragments', 'my_header_add_to_cart_fragment' );
Looking for an advices and your help.
UPDATE: changed $fragments['a.cart-contents'] = ob_get_clean(); to $fragments['div.widget_shopping_cart_content'] = ob_get_clean(); to make it return right fragment(not two, like on sreenshot), but didn't help
The following will compact your code and will ajax refresh the mini-cart count + the mini-cart content in the right way:
// Utility function that outputs the mini cart content
function my_wc_mini_cart_content(){
$cart = WC()->cart->get_cart();
foreach ( $cart as $cart_item_key => $cart_item ):
$_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_widget_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
$product_name = apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key );
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
$product_price = apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
if(isset($cart_item['variation']['attribute_pa_size'])) {
$variation_val = $cart_item['variation']['attribute_pa_size'];
$term_obj = get_term_by('slug', $variation_val, 'pa_size');
$size_name = $term_obj->name;
}
?>
<div class="media mini-cart__item woocommerce-mini-cart-item <?php echo esc_attr( apply_filters( 'woocommerce_mini_cart_item_class', 'mini_cart_item', $cart_item, $cart_item_key ) ); ?>">
<?php echo $thumbnail; ?>
<div class="media-body mini-cart__item_body">
<div class="mini-cart__item__heading mt-0"><?php echo $product_name; ?></div>
<?php
echo apply_filters( 'woocommerce_widget_cart_item_quantity', '<div class="cart__item__price">' .
sprintf( '%s × %s', $cart_item['quantity'], $product_price ) .
'</div>', $cart_item, $cart_item_key );
if( isset($size_name) ) { ?>
<div class="mini-cart__item__size"><?php echo $size_name; ?></div>
<?php } ?>
</div>
<div class="mini-cart__item_remove ">
<?php
echo apply_filters( 'woocommerce_cart_item_remove_link', sprintf(
'×',
esc_url( wc_get_cart_remove_url( $cart_item_key ) ),
__( 'Remove this item', 'woocommerce' ),
esc_attr( $product_id ),
esc_attr( $cart_item_key ),
esc_attr( $_product->get_sku() )
), $cart_item_key );
?>
</div>
</div>
<?php
}
endforeach; ?>
<span class="btn__text"><?php _e('Checkout', 'frosted'); ?></span>
<?php
}
// Hooked: The mini cart count and the cart content
add_action( 'frosted_header_top', 'my_wc_mini_cart' );
function my_wc_mini_cart() {
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
$count = WC()->cart->get_cart_contents_count();
?>
<?php _e('Cart', 'frosted'); ?> <span id="cart_count" class="cart__amount"><?php echo esc_html( $count ); ?></span>
<div id="mini-cart-content" class="sub-menu sub-menu--right sub-menu--cart">
<?php my_wc_mini_cart_content(); ?>
</div>
<?php
}
}
// Ajax refreshing mini cart count and content
add_filter( 'woocommerce_add_to_cart_fragments', 'my_header_add_to_cart_fragment' );
function my_header_add_to_cart_fragment( $fragments ) {
$count = WC()->cart->get_cart_contents_count();
$fragments['#cart_count'] = '<span id="cart_count" class="cart__amount">' . esc_attr( $count ) . '</span>';
ob_start();
?>
<div id="mini-cart-content" class="sub-menu sub-menu--right sub-menu--cart">
<?php my_wc_mini_cart_content(); ?>
<div>
<?php
$fragments['#mini-cart-content'] = ob_get_clean();
return $fragments;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
After trying to use solution marked as correct answer, the remove function still not worked for me, but I found another solution here.
adding widget_shopping_cart_content classname to my mini-cart's container made it work

How do I remove my item from the cart in WooCommerce?

I'm generating my cart as such:
if( !is_wp_error( $this->getCartContentsCount() ) ) {
$cart_items = WC()->cart->get_cart();
foreach( $cart_items as $item ) { ?>
<div class="left col-md-3">
<div class="product-image"><!-- Make sure ot check if it's a gallery, if so, get its first image -->
<?php echo $item['data']->get_image(); ?>
</div>
</div>
<div class="right col-md-8">
<h4 class="product-name"><?php echo $item['data']->get_name(); ?></h4>
<div class="product-information">
<span class="product-quantity"><?php echo $item['quantity'] . 'x' ?></span>
<span class="product-price"><?php echo $item['data']->get_price_html(); ?></span>
</div>
<?php
echo apply_filters( 'woocommerce_cart_item_remove_link', sprintf(
'X',
esc_url( wc_get_cart_remove_url( $item ) ),
__( 'Remove this item', 'woocommerce' ),
esc_attr( $item['product_id'] ),
esc_attr( $item['data']->get_sku() )
), $item );
?>
</div>
<?php }
}
As you can see, I'm using the basic Woocommerce implementation of the "remove item" mechanism as per cart.php, but unfortunately, it doesn't work.
This is what Woo generates:
X
I have checked every attribute and it is indeed valid!
Other symptoms:
The link, if accessed directly, takes me to the cart itself (I
believe it is due to the nonce).
Dumping the cart before and after the click still shows the same
cart with just one item in it, so the mechanism to delete doesn't
work as the cart doesn't change its state.
How come it doesn't work?
I actually went ahead and copied the cart.php implementation and customized it to my needs:
ob_start();
if( !is_wp_error( $this->getCartContentsCount() ) ) { //This checks if there are any items in the cart.
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
);
$product_id = apply_filters(
'woocommerce_cart_item_product_id',
$cart_item['product_id'], $cart_item, $cart_item_key
);
if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
$product_permalink = apply_filters(
'woocommerce_cart_item_permalink',
$_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key
); ?>
<div class="cart-item <?php echo esc_attr( apply_filters( 'woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key ) ); ?>">
<div class="left col-md-3">
<div class="product-image">
<?php
$thumbnail = apply_filters(
'woocommerce_cart_item_thumbnail',
$_product->get_image(), $cart_item, $cart_item_key
);
if ( !$product_permalink ) {
echo wp_kses_post( $thumbnail );
} else {
printf( '%s', esc_url( $product_permalink ), wp_kses_post( $thumbnail ) );
}
?>
</div>
</div>
<div class="right col-md-8">
<h4 class="product-name">
<?php
if ( ! $product_permalink ) {
echo wp_kses_post( apply_filters(
'woocommerce_cart_item_name',
$_product->get_name(), $cart_item, $cart_item_key ) . ' '
);
} else {
echo wp_kses_post( apply_filters(
'woocommerce_cart_item_name',
sprintf(
'%s',
esc_url( $product_permalink ), $_product->get_name()
), $cart_item, $cart_item_key
)
);
}
// Meta data.
echo wc_get_formatted_cart_item_data( $cart_item ); // PHPCS: XSS ok.
// Backorder notification.
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) {
echo wp_kses_post( apply_filters(
'woocommerce_cart_item_backorder_notification',
'<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'woocommerce' ) . '</p>'
)
);
}
?>
</h4>
<div class="product-information">
<div class="product-quantity">
<?php
$product_quantity = sprintf(
'%s<input type="hidden" name="cart[%s][qty]" value="%s" />',
$cart_item['quantity'], $cart_item_key, $cart_item['quantity']
);
echo apply_filters(
'woocommerce_cart_item_quantity',
$product_quantity, $cart_item_key, $cart_item
); // PHPCS: XSS ok.
?>
</div>
<div class="product-price">
<?php
echo apply_filters(
'woocommerce_cart_item_price',
WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key ); // PHPCS: XSS ok.
?>
</div>
</div>
<div class="product-remove">
<?php
echo apply_filters( 'woocommerce_cart_item_remove_link', sprintf(
'×',
esc_url( wc_get_cart_remove_url( $cart_item_key ) ),
__( 'Remove this item', 'woocommerce' ),
esc_attr( $product_id ),
esc_attr( $_product->get_sku() )
), $cart_item_key );
?>
</div>
</div>
</div>
<?php
}
}
}
$markup_output = ob_get_contents();
ob_end_clean();
echo $markup_output;
Simple use this WC_Cart::remove_cart_item( $cart_item_key );

Categories