WooCommerce Display avanced custom fields (ACF) inside order notification - php

I've added the following snippet to display a custom field (that don't display taxonomy field if product has field) with the estimated delivery time. This is working.
<?php add_action( 'woocommerce_before_add_to_cart_form', 'geschatte_levertijd', 10 );
function geschatte_levertijd (){
if( get_field('plevertijd') ): ?>
<span class="product_melding_kleur"><i class="fa fa-truck"></i>Levertijd: <a href="/verzending-en-levertijd/" alt="Verzending en levertijd" ><?php the_field( 'plevertijd' ); ?></a></span>
<?php else: ?>
<? $terms = get_the_terms( $post->ID, 'product_cat' );
if ( !empty($terms)):
$term = array_pop($terms);
$text= get_field('levertijd', $term);
if (!empty($levertijd))?>
<span class="product_melding_kleur"><i class="fa fa-truck"></i>Levertijd: <a href="/verzending-en-levertijd/" alt="Verzending en levertijd" ><?php the_field( 'levertijd', $term ); ?></a></span>
<?php endif; ?>
<?php endif;
}
?>
But now I'm trying to display that field inside the order notification mail. Below the product title.
Could someone point me into the right direction on how to do that?

The following will use your code to make happen the display in order email notifications under order item product name:
add_action( 'woocommerce_order_item_meta_start', 'add_estimated_delivery_time_to_emails', 10, 3 );
function add_estimated_delivery_time_to_emails( $item_id, $item, $order ) {
// On email notifications and for line items
if ( ! is_wc_endpoint_url() && $item->is_type('line_item') ) {
if( $plevertijd = get_field('plevertijd', $item->get_product_id() ) ) {
echo '<span class="product_melding_kleur"><i class="fa fa-truck"></i>Levertijd: <a href="/verzending-en-levertijd/" alt="Verzending en levertijd" >' . $plevertijd . '</a></span>';
} else {
$terms = get_the_terms( $item->get_product_id(), 'product_cat' );
if ( ! empty($terms) ) {
$term = array_pop( $terms );
if( $levertijd = get_field('levertijd', $term ) ) {
echo '<span class="product_melding_kleur"><i class="fa fa-truck"></i>Levertijd: <a href="/verzending-en-levertijd/" alt="Verzending en levertijd" >' . $levertijd . '</a></span>';
}
}
}
}
}
Code goes in functions.php file of your active child theme (or active theme). It should works.
Displaying on frontend orders:
If you want that to be displayed on customer order (front end), you can remove from the IF statement the following: ! is_wc_endpoint_url() &&
You can also use the woocommerce_order_item_meta_end hook instead, to get the display after the product attributes on product variations.

Related

Adding parent category to url

I am having trouble adding the parent category to my URL in this code snippet. Any help would be appreciated.
Code is to show categories underneath products in woocommerce.
remove_action( 'woocommerce_shop_loop_item_title', 'woocommerce_template_loop_product_title', 10 );
add_action( 'woocommerce_shop_loop_item_title', 'VS_woo_loop_product_title', 10 );
function VS_woo_loop_product_title() {
echo '<h3>' . get_the_title() . '</h3>';
$terms = get_the_terms( $post->ID, 'product_cat' );
if ( $terms && ! is_wp_error( $terms ) ) :
// only displayed if the product has at least one category
$cat_links = array();
foreach ( $terms as $term ) {
$cat_links[] = ''.$term->name.'';
}
$on_cat = join( ", ", $cat_links );
?>
<div class="label-group">
<div class="categories-link"><?php echo $on_cat; ?></div>
</div>
<?php endif;
}

Display problem depending on the customer's role - woocommerce

I have a problem on the "my account" page of my woocommerce store.
Indeed, when I log in with a new customer account that has never placed an order, I have 3 content containers that disappear.
After testing, they only appear if I place an order with the account in question.
Do you have any idea where this could be coming from?
The 3 divs in question correspond to :
the navigation menu of the page my account that disappears only on the dashboard tab (it reappears on all other tabs - my orders, my addresses ...)
a div with the recently viewed products (see code n°1 below)
a div with the articles recently written by the customer (see code n°2 below)
When an order is placed, all the content reappears.
I also have a div with the recent orders which strangely, does not have any problem of display (see code n°3 below)
Do not hesitate to ask me for clarifications, or if you think that the error comes from a tag elsewhere in my code (a tag of authorization according to the role for example?)
In advance, Thank you very much for your help.
add_shortcode( 'recently_viewed_products', 'bbloomer_recently_viewed_shortcode' );
function bbloomer_recently_viewed_shortcode() {
$viewed_products = ! empty( $_COOKIE['woocommerce_recently_viewed'] ) ? (array) explode( '|', wp_unslash( $_COOKIE['woocommerce_recently_viewed'] ) ) : array();
$viewed_products = array_reverse( array_filter( array_map( 'absint', $viewed_products ) ) );
if ( empty( $viewed_products ) ) return;
?>
<div class="col-23">
<?php $title = '<h3>Produits consultés récemment</h3>';?>
<?php $product_ids = implode( ",", $viewed_products );?>
<?php return $title . do_shortcode("[products ids='$product_ids' limit='4' columns='4' orderby='post__in' class='recentes-vues']");?>
</div>
<?php }
function custom_track_product_view() {
if ( ! is_singular( 'product' ) ) {
return;
}
global $post;
if ( empty( $_COOKIE['woocommerce_recently_viewed'] ) )
$viewed_products = array();
else
$viewed_products = (array) explode( '|', $_COOKIE['woocommerce_recently_viewed'] );
if ( ! in_array( $post->ID, $viewed_products ) ) {
$viewed_products[] = $post->ID;
}
if ( sizeof( $viewed_products ) > 15 ) {
array_shift( $viewed_products );
}
// Store for session only
wc_setcookie( 'woocommerce_recently_viewed', implode( '|', $viewed_products ) );
}
add_action( 'template_redirect', 'custom_track_product_view', 20 );
// PRODUIT RECENT PAGE COMPTE
add_action( 'woocommerce_account_dashboard' , 'recentes_vues', 5 );
function recentes_vues() {
echo do_shortcode('[recently_viewed_products]');
}
add_action( 'woocommerce_account_dashboard' , 'recent_posts', 3 );
function recent_posts() {
if ( is_user_logged_in()) :
global $current_user;
wp_get_current_user();
$author_query = array('posts_per_page' => '-1','author' => $current_user->ID);
$author_posts = new WP_Query($author_query);
?><div id="recentposts">
<?php
if ($author_posts->found_posts) {
?>
<ul class="liststylenone">
<?php
while($author_posts->have_posts()) : $author_posts->the_post();
?>
<li><?php the_title(); ?></li>
<?php
endwhile;
?></ul><?php
}
else {
echo '<p>Aucun article trouvé 😞</p>';
}
else :
echo "not logged in";
endif;
?>
add_action( 'woocommerce_account_dashboard', 'recent_order', 2 );
function recent_order(){
// For logged in users only
if ( is_user_logged_in() ) :
$user_id = get_current_user_id(); // The current user ID
// Get the WC_Customer instance Object for the current user
$customer = new WC_Customer( $user_id );
// Get the last WC_Order Object instance from current customer
$last_order = $customer->get_last_order();
if ( is_a( $last_order, 'WC_Order' ) ) {
$order_id = $last_order->get_id(); // Get the order id
$order_data = $last_order->get_data(); // Get the order unprotected data in an array
$order_status = $last_order->get_status(); // Get the order status
$date_created = $last_order->get_date_created();
$order_total = $last_order->get_total();
}
?>
<div class="row last-order">
<div class="col-md-7">
<div class="col-3">
<div class="col-5">
<div class="col-md-4 order-status-box">
<h6 class="status">État : <?php echo esc_html( wc_get_order_status_name( $order_status ) ); ?></h6>
</div>
<p class="totalcmdd"><?php echo $order_total."€"; ?></p>
<?php
setlocale(LC_TIME, 'fr_FR');
date_default_timezone_set('Europe/Paris');
echo utf8_encode(strftime('%d %B %Y', strtotime($date_created)));
//echo date('d-F-Y', strtotime($date_created)); ?>
</p>
</div>
<div style="display: flex;flex-direction: row;justify-content: space-evenly;align-items: center;margin-right: 1.5em;margin-left: 1.5em;padding: 0.3em;background-color: white;text-transform: uppercase;text-decoration: none;font-size: 13px;">
<?php foreach ($last_order->get_items() as $item) :
$product = $item->get_product();
$thumbnail = $product->get_image(array(50, 50));
if ($product->get_image_id() > 0) {
$item_name = '<div class="item-thumbnail">' . $thumbnail . '</div>'; // You had an extra variable here
}
echo $item_name . $item->get_name();
endforeach;
endif;
?>

Add product category link on WooCommerce single product page

This code is outputting the Product (Brand) Category in (almost) the right spot - above the product title - on the Single Product Page.
How can I hyperlink it (Product Category) to the Product Category page? I essentially need to make this <?php echo $single_cat->name; ?> a dynamic hyperlink.
/** Output Product (Brand) Category on single product page **/
function add_brand_category(){
$product_cats = wp_get_post_terms( get_the_ID(), 'product_cat' );
if ( $product_cats && ! is_wp_error ( $product_cats ) ){
$single_cat = array_shift( $product_cats ); ?>
<h3 itemprop="name" class="product_category_title"><span><?php echo $single_cat->name; ?></span></h3>
<?php }
}
add_action( 'woocommerce_single_product_summary', 'add_brand_category', 2 );
You can use wc_get_product_category_list() – which returns the product categories in a list + adding a hyperlink to the product category page.
So you get:
function action_woocommerce_single_product_summary() {
global $product;
// Is a WC product
if ( is_a( $product, 'WC_Product' ) ) {
echo '<h3 itemprop="name" class="product_category_title">';
echo wc_get_product_category_list( $product->get_id(), ', ', '<span>' . _n( 'Category:', 'Categories:', count( $product->get_category_ids() ), 'woocommerce' ) . ' ', '</span>' );
echo '</h3>';
}
}
add_action( 'woocommerce_single_product_summary', 'action_woocommerce_single_product_summary', 2 );

Ajax update product count on cart menu in Woocommerce

I have a menu item that points to the cart and that reads the number of products currently in the cart.
CART (3)
When, on the cart page, I change the number of products and click the "Update cart" button, or delete an item, the number doesn't refresh.
Any idea why?
/*CHANGE CART MENU TITLE IN MENU*/
add_filter( 'wp_setup_nav_menu_item','my_item_setup' );
function my_item_setup($item) {
if ( ! is_admin() ) {
if ( class_exists( 'woocommerce' ) ) {
global $woocommerce;
if ( $item->url == esc_url( wc_get_cart_url() ) ) {
if (is_null($woocommerce->cart)){
} else {
if( get_locale() == 'fr_FR' ) {
$item->title = 'PANIER ('. '<span class="count-cart">' . $woocommerce->cart->get_cart_contents_count() . '</span>)';
} else {
$item->title = 'MY CART ('. '<span class="count-cart">' . $woocommerce->cart->get_cart_contents_count() . '</span>)';
}
}
}
}
}
return $item;
}
And
add_filter( 'woocommerce_add_to_cart_fragments', 'my_woocommerce_add_to_cart_fragments' );
function my_woocommerce_add_to_cart_fragments( $fragments ) {
// Add our fragment
$fragments['li.menu-item-type-woocommerce-cart'] = my_item_setup( '');
return $fragments;
}
EDIT:
Using Ajaxify the cart items count in Woocommerce answer code, seems to work a little better. The product number updates when I delete an item from the cart page, or when I change the number of items, but it doesn't update when I empty the cart. Moreover, there's a space before and after the product number (see picture with empty cart and "CART ( 1 )".
add_filter( 'woocommerce_add_to_cart_fragments', 'wc_refresh_cart_fragments');
function wc_refresh_cart_fragments($fragments){
ob_start();
?>
<span class="count-cart"><?php echo WC()->cart->get_cart_contents_count(); ?></span>
<?php
$fragments['li a span.count-cart'] = ob_get_clean();
return $fragments;
}
Updated
It's better to set a tag ID than a tag CLASS to ajaxify a cart count, as this selector reference need to be unique. If it's not the case, and there is a hidden mobile duplicated menu, it can't work.
So this item menu need to be unique on the generated html code of your page… If this menu item is duplicated in a mobile version, you will need to change the tag ID or the tag CLASS for the mobile code version.
I have revisited your code a bit:
add_filter( 'wp_setup_nav_menu_item','my_item_setup' );
function my_item_setup( $item ) {
if ( ! is_admin() && class_exists( 'woocommerce' ) ) {
if ( $item->url == esc_url( wc_get_cart_url() ) && ! WC()->cart->is_empty() ){
$title = get_locale() == 'fr_FR' ? 'PANIER' : 'MY CART';
$item->title = $title . ' (<span id="count-cart-items">' . WC()->cart->get_cart_contents_count() . '</span>)';
}
}
return $item;
}
add_filter( 'woocommerce_add_to_cart_fragments', 'wc_refresh_cart_fragments', 50, 1 );
function wc_refresh_cart_fragments( $fragments ){
$cart_count = WC()->cart->get_cart_contents_count();
// Normal version
$count_normal = '<span id="count-cart-items">' . $cart_count . '</span>';
$fragments['#count-cart-items'] = $count_normal;
// Mobile version
$count_mobile = '<span id="count-cart-itemob">' . $cart_count . '</span>';
$fragments['#count-cart-itemob'] = $count_mobile;
return $fragments;
}
Code goes in function.php file of your active child theme (active theme). It should better work.
To Ajaxify your cart viewer so it updates when an item is added or deleted (via ajax) use:
/**
* Show cart contents / total Ajax
*/
add_filter( 'woocommerce_add_to_cart_fragments', 'woocommerce_header_add_to_cart_fragment' );
function woocommerce_header_add_to_cart_fragment( $fragments ) {
global $woocommerce;
ob_start();
?>
<a class="cart-customlocation" href="<?php echo esc_url(wc_get_cart_url()); ?>" title="<?php _e('View your shopping cart', 'woothemes'); ?>"><?php echo sprintf(_n('%d item', '%d items', $woocommerce->cart->cart_contents_count, 'woothemes'), $woocommerce->cart->cart_contents_count);?> - <?php echo $woocommerce->cart->get_cart_total(); ?></a>
<?php
$fragments['a.cart-customlocation'] = ob_get_clean();
return $fragments;
} ?>
Reference Link

Display "Sold Out" text on External products with empty price in WooCommerce

Some Amazon imported products dont have price or are sold out but not removed from listings, and its breaking aligments.
Im trying to customize woocommerce/templates/loop/price.phptemplate file.
From this
<?php if ( $price_html = $product->get_price_html() ) : ?>
<span class="price"><?php echo $price_html; ?></span>
<?php endif; ?>
To something like this
<?php if ( $price_html = $product->get_price_html() ) :
if (empty($price))
{
echo 'Sold Out';}
else
{ ?>
<span class="price"><?php echo $price_html; ?></span>
<?php }; ?>
<?php endif; ?>
But its not working properly as now all products are sold out.
What am I doing wrong?
You can try the following code instead of overriding price template. The code will make sure that the product is external and the price is zero or empty.
function op_change_price_html( $price_html, $product ) {
if ( 'external' === $product->get_type() && empty( $product->get_price() ) ) {
return 'Sold Out';
}
return $price_html;
}
add_filter( 'woocommerce_empty_price_html', 'op_change_price_html', 10, 2 );
add_filter( 'woocommerce_get_price_html', 'op_change_price_html', 10, 2 );

Categories