Hello World!
I am currently working on an e-commerce website based on woocommerce and I've recently bought
the Dynamic Pricing & the Request a Quote plugins made by YITH
Everything is okay with those plugins but the e-commerce website I'm doing can both do quote and cart that's why I use the Request a Quote plugin but the differents dynamic prices I do are'nt visibe in my Quote page but they are in my cart page.
After many search on google it seems that the two plugins are not compatible.
So this is my question, is there a way to hook the final prices obtain by the dynamic prices plugin in my quote page ?
I know some basics on PHP and I have took a look at the differents functions and classes of the both plugins to try to solve the problem but I didn't found it.. :(
Here is the beta of website i'm doing, http://beta.jardivrac.com you can try the dynamic prices on this page and after go to the card page and the quote page
And here is the public function I've found on the fronted class in the dynamic prices plugin ->
public function replace_cart_item_price( $price, $cart_item, $cart_item_key ) {
if ( ! isset( $cart_item['ywdpd_discounts'] ) ) {
return $price;
}
$old_price = $price;
foreach ( $cart_item['ywdpd_discounts'] as $discount ) {
if ( isset( $discount['status'] ) && $discount['status'] == 'applied' ) {
if ( wc_price( $cart_item['ywdpd_discounts']['default_price'] ) != WC()->cart->get_product_price( $cart_item['data'] ) ) {
$price = '<del>' . wc_price( $cart_item['ywdpd_discounts']['default_price'] ) . '</del> ' . WC()->cart->get_product_price( $cart_item['data'] );
} else {
return $price;
}
}
}
$price = apply_filters( 'ywdpd_replace_cart_item_price', $price, $old_price, $cart_item, $cart_item_key );
return $price;
}
If somebody have the solution that will be a great news !
Thanks in advance for your help !
Antoine
EDIT:
This is the loop inside the Woocommerce cart.php
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 );
?>
<tr class="<?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( 'woocommerce_cart_item_remove_link', sprintf(
'×',
esc_url( WC()->cart->get_remove_url( $cart_item_key ) ),
__( '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;
} else {
printf( '%s', esc_url( $product_permalink ), $thumbnail );
}
?>
</td>
<td class="product-name" data-title="<?php _e( 'Product', 'woocommerce' ); ?>">
<?php
if ( ! $product_permalink ) {
echo apply_filters( 'woocommerce_cart_item_name', $_product->get_title(), $cart_item, $cart_item_key ) . ' ';
} else {
echo apply_filters( 'woocommerce_cart_item_name', sprintf( '%s', esc_url( $product_permalink ), $_product->get_title() ), $cart_item, $cart_item_key );
}
// Meta data
echo WC()->cart->get_item_data( $cart_item );
// Backorder notification
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) {
echo '<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'woocommerce' ) . '</p>';
}
?>
</td>
<td class="product-price" data-title="<?php _e( 'Price', 'woocommerce' ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
?>
</td>
<td class="product-quantity" data-title="<?php _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->backorders_allowed() ? '' : $_product->get_stock_quantity(),
'min_value' => '0'
), $_product, false );
}
echo apply_filters( 'woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item );
?>
</td>
<td class="product-subtotal" data-title="<?php _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 );
?>
</td>
</tr>
<?php
}
}
And this is the loop for the quote
$total = 0;
foreach ( $raq_content as $key => $raq ):
$_product = wc_get_product( ( isset( $raq['variation_id'] ) && $raq['variation_id'] != '' ) ? $raq['variation_id'] : $raq['product_id'] );
if( ! $_product ){
continue;
}
$show_price = true;
do_action( 'ywraq_before_request_quote_view_item', $raq_content, $key );
?>
<tr class="<?php echo esc_attr( apply_filters( 'yith_ywraq_item_class', 'cart_item', $raq_content, $key ) ); ?>" <?php echo esc_attr( apply_filters( 'yith_ywraq_item_attributes', '', $raq_content, $key ) ); ?>>
<td class="product-remove">
<?php
echo apply_filters( 'yith_ywraq_item_remove_link', sprintf( '×', $key, wp_create_nonce( 'remove-request-quote-' . $_product->id ), $_product->id, __( 'Retirer cet article', 'yith-woocommerce-request-a-quote' ) ), $key );
?>
</td>
<td class="product-thumbnail">
<?php $thumbnail = $_product->get_image();
if ( ! $_product->is_visible() ) {
echo $thumbnail;
} else {
printf( '%s', $_product->get_permalink(), $thumbnail );
}
?>
</td>
<td class="product-name">
<?php
$title = $_product->get_title();
if ( $_product->get_sku() != '' && get_option( 'ywraq_show_sku' ) == 'yes' ) {
$title .= apply_filters( 'ywraq_sku_label', __( ' SKU:', 'yith-woocommerce-request-a-quote' ) ) . $_product->get_sku();
}
?>
<?php echo $title ?>
<?php
// Meta data
$item_data = array();
// Variation data
if ( ! empty( $raq['variation_id'] ) && is_array( $raq['variations'] ) ) {
foreach ( $raq['variations'] as $name => $value ) {
$label = '';
if ( '' === $value ) {
continue;
}
$taxonomy = wc_attribute_taxonomy_name( str_replace( 'attribute_pa_', '', urldecode( $name ) ) );
// If this is a term slug, get the term's nice name
if ( taxonomy_exists( $taxonomy ) ) {
$term = get_term_by( 'slug', $value, $taxonomy );
if ( ! is_wp_error( $term ) && $term && $term->name ) {
$value = $term->name;
}
$label = wc_attribute_label( $taxonomy );
} else {
if ( strpos( $name, 'attribute_' ) !== false ) {
$custom_att = str_replace( 'attribute_', '', $name );
if ( $custom_att != '' ) {
$label = wc_attribute_label( $custom_att );
} else {
$label = $name;
}
}
}
$item_data[] = array(
'key' => $label,
'value' => $value
);
}
}
$item_data = apply_filters( 'ywraq_request_quote_view_item_data', $item_data, $raq, $_product, $show_price );
// Output flat or in list format
if ( sizeof( $item_data ) > 0 ) {
foreach ( $item_data as $data ) {
echo esc_html( $data['key'] ) . ': ' . wp_kses_post( $data['value'] ) . "\n";
}
}
?>
</td>
<td class="product-price" data-title="<?php _e( 'Price', 'woocommerce' ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
?>
</td>
<td class="product-quantity">
<?php
$product_quantity = woocommerce_quantity_input( array(
'input_name' => "raq[{$key}][qty]",
'input_value' => apply_filters( 'ywraq_quantity_input_value', $raq['quantity'] ),
'max_value' => apply_filters( 'ywraq_quantity_max_value', $_product->backorders_allowed() ? '' : $_product->get_stock_quantity(), $_product ),
'min_value' => apply_filters( 'ywraq_quantity_min_value', 0, $_product )
), $_product, false );
echo $product_quantity;
?>
</td>
<?php if ( get_option( 'ywraq_hide_total_column', 'yes' ) == 'no' ): ?>
<td class="product-subtotal">
<?php
$total += apply_filters( 'yith_ywraq_product_price', $_product->get_display_price( '', $raq[ 'quantity' ] ), $_product, $raq );
$price = apply_filters( 'yith_ywraq_product_price_html', WC()->cart->get_product_subtotal( $_product, $raq[ 'quantity' ] ), $_product, $raq );
echo apply_filters( 'yith_ywraq_hide_price_template', $price, $_product->id, $raq);
?>
</td>
<?php endif ?>
</tr>
<?php do_action( 'ywraq_after_request_quote_view_item', $raq_content, $key ); ?>
<?php endforeach ?>
<!--
<?php if ( get_option( 'ywraq_hide_total_column', 'yes' ) == 'no' ): ?>
<tr>
<td colspan="3">
</td>
<th>
<?php _e( 'Total:', 'yith-woocommerce-request-a-quote') ?>
</th>
<td class="raq-totals">
<?php echo wc_price( $total ); ?>
</td>
</tr>
<?php endif ?>
-->
I think it will help, I already tried to replace the loop of the request a quote page by the loop of the card but it only created 2 cart loop, not what I expected... Maybe somebody better in PHP than me could have an idea ?
After many try & a short night I've found a "solution" not really good one, but everything works perfectly!
So I modified those pages:
request-quote-view.php (Table of the quote page)
I've added this little loop before the foreach of the differents products in the table.
$arr_discount = array();
foreach(YITH_WC_Dynamic_Pricing() as $key => $raq ){
foreach($raq as $arr => $data){
array_push($arr_discount, $data);
}
}
With this loop I put the differents informations about the dynamic pricing in a new array
So then, in the start of the foreach loop I have an other loop wich put the content we get before into the array of the quote
foreach($arr_discount as $test){
foreach($test['apply_to_products_list'] as $id){
if($id == $raq['product_id']){
foreach($test['rules'] as $rule){
$raq['arr_dsct'][] = $rule;
}
}
}
}
And finaly in the td class=subtotal I replaced the content with
if(isset($raq['arr_dsct']) == ''){
$total += apply_filters( 'yith_ywraq_product_price', $_product->get_display_price( '', $raq[ 'quantity' ] ), $_product, $raq );
$price = apply_filters( 'yith_ywraq_product_price_html', WC()->cart->get_product_subtotal( $_product, $raq[ 'quantity' ] ), $_product, $raq );
echo apply_filters( 'yith_ywraq_hide_price_template', $price, $_product->id, $raq);
} else {
$count = count($raq['arr_dsct']);
for($i = 0; $i < $count; $i++) {
if( $raq['quantity'] >= $raq['arr_dsct'][$i][min_quantity] AND $raq['quantity'] <= $raq['arr_dsct'][$i][max_quantity] ){
$price = $_product->price - $_product->price * $raq['arr_dsct'][$i][discount_amount];
$total = round($raq['quantity'] * $price, 2);
$totale = '<span class="woocommerce-Price-amount amount">'. $total .'<span class="woocommerce-Price-currencySymbol">€</span></span>';
} elseif ( $raq['quantity'] < $raq['arr_dsct'][0][min_quantity] ) {
$total += apply_filters( 'yith_ywraq_product_price', $_product->get_display_price( '', $raq[ 'quantity' ] ), $_product, $raq );
$price = apply_filters( 'yith_ywraq_product_price_html', WC()->cart->get_product_subtotal( $_product, $raq[ 'quantity' ] ), $_product, $raq );
$totale = apply_filters( 'yith_ywraq_hide_price_template', $price, $_product->id, $raq);
}
}
echo $totale;
}
request-quote-table.php (Table of the mail)
For the mail page it was exactly the same answer with only one difference, the array object of the product is named $item not $raq so It need some modification
If you want more information about the place where should be the different piece of code there is two images wich show it !
Related
I've been trying to figure out how can I make the value on the product meta data shown on the cart to be editable and saved when clicking the update quote button. When I try to update the value on the BOP field for each product, it does not reflect properly
I've made some work in progress but can never seem to make it work
cart.php
<?php
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 );
?>
<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 );
?>
<?php
// Meta data.
// echo wc_get_formatted_cart_item_data( $cart_item ); // PHPCS: XSS ok. ?>
<div class="box-type-field">
<span>BOP: <input class="box-type" cart_item_key="<?php echo $cart_item['key'] ?>" type="number" value="<?php echo $cart_item['BOP'] ?>" /></span>
</div>
<?php
// 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-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>
</tr>
<?php
}
}
?>
JS
jQuery('.box-type-field .box-type').on('change', function () {
var cartItemKey = jQuery(this).attr("cart_item_key");
var boxType = jQuery(this).val();
jQuery.ajax({
type : "post",
url : '/wp-admin/admin-ajax.php',
datatype: 'json',
data : {
action : "update_cart_boxtype",
cart_item_key : cartItemKey,
box_type : boxType,
},
success: function(cartItem) {
cartItemKey = cartItem[0];
cartItemQty = cartItem[1];
if (cartItem) jQuery('input[name="cart['+cartItemKey+'][qty]"]').val(cartItemQty); // update quantity
jQuery('.woocommerce-cart-form button[type="submit"]').click(); // submit form
}
})
})
PHP (functions.php)
function update_cart_boxtype_init() {
if ( ! WC()->cart->is_empty() ) {
$cart_item_key = (isset($_POST['cart_item_key']))?$_POST['cart_item_key'] : '';
$cart_item = WC()->cart->cart_contents[ $cart_item_key ];
$box_type = (isset($_POST['box_type']))?$_POST['box_type'] : '';
$cart_updated = false;
$cart_item_key_new = WC()->cart->generate_cart_id( $cart_item['product_id'], $cart_item['variation_id'], $cart_item['variation'], ['box-type'=>$box_type] );
$found = WC()->cart->find_product_in_cart( $cart_item_key_new );
if ($found != '') {
$new_qty = $cart_item['quantity'] + WC()->cart->cart_contents[ $cart_item_key_new ]['quantity'];
WC()->cart->remove_cart_item($cart_item_key);
wp_send_json_success([$cart_item_key_new, $new_qty]);
} else {
WC()->cart->add_to_cart($cart_item['product_id'], $cart_item['quantity'], $cart_item['variation_id'], $cart_item['variation'], ['box-type' => $box_type]);
$cart_updated = true;
WC()->cart->remove_cart_item($cart_item_key);
wp_send_json_success(false);
}
}
wp_die();
}
add_action( 'wp_ajax_update_cart_boxtype', 'update_cart_boxtype_init' );
add_action( 'wp_ajax_nopriv_update_cart_boxtype', 'update_cart_boxtype_init' );
Some errors indicated:
1.) When I try to update the value it returns 404 on the console as shown below
Looking at your ajax function I will say that when you define this wp_send_json_success(false); your javascript is expecting an array of something and you are submitting a boolean.
if you are getting a 404 error then it seems like your ajax url is wrong:
you can define it on the page as a localize_script to an enqueued script
$args = array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
);
wp_localize_script( 'YOUR_ENQUEUED_SCRIPT', 'ajax', $args );
and call it in your js:
ajax.ajaxurl
or defined in the theme:
<?php $ajax_url = admin_url( 'admin-ajax.php' ); ?>
<?php echo $ajax_url; ?>
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!
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 );
?>
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
I need to sort my cart items by variation addon values.
For example I have 5 items in cart, and they have variation date:
first item date - 2016-05-05;
second 2016-05-08;
third 2016-05-20 and so on.
How can I sort them in cart ? I found that all info are in $cart_item[‘addons’] , but don’t find solution for how to sort them.
I editing my cart.php
<?php
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 ) ) {
?>
<tr class="<?php echo esc_attr( apply_filters( 'woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key ) ); ?>">
<td class="product-name">
<div class="product-thumbnail">
<?php
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
if ( ! $_product->is_visible() )
echo $thumbnail;
else
printf( '%s', $_product->get_permalink(), $thumbnail );
?>
</div>
</td>
<td class="product-details">
<div class="cart-item-details">
<?php
if ( ! $_product->is_visible() )
echo apply_filters( 'woocommerce_cart_item_name', $_product->get_title(), $cart_item, $cart_item_key );
else
echo apply_filters( 'woocommerce_cart_item_name', sprintf( '%s', $_product->get_permalink(), $_product->get_title() ), $cart_item, $cart_item_key );
// Meta data
echo WC()->cart->get_item_data( $cart_item );
// Backorder notification
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) )
echo '<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'xstore' ) . '</p>';
?>
<span class="mobile-price">
<?php
echo apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
?>
</span>
</div>
</td>
<td class="product-price">
<?php
echo apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
?>
</td>
<td class="product-quantity">
<?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->backorders_allowed() ? '' : $_product->get_stock_quantity(),
'min_value' => '0'
), $_product, false );
}
echo apply_filters( 'woocommerce_cart_item_quantity', $product_quantity, $cart_item_key );
?>
</td>
<td class="product-subtotal">
<?php
echo apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key );
?>
</td>
<td class="product-remove">
<?php
echo apply_filters( 'woocommerce_cart_item_remove_link', sprintf( 'X', esc_url( WC()->cart->get_remove_url( $cart_item_key ) ), __( 'Pašalinti produktą', 'xstore' ) ), $cart_item_key );
?>
</td>
</tr>
<?php
}
}