WooCommerce Display Product Variations SKU - wordpress

I am using WooCommerce and I'm trying to display product variation SKUs on the product page below the product title. I managed to find this code, which works but displays the SKU in the wrong place:
// Display product variations SKU and GTIN info
add_filter( 'woocommerce_available_variation', 'display_variation_sku_and_gtin', 20, 3 );
function display_variation_sku_and_gtin( $variation_data, $product, $variation ) {
$html = ''; // Initializing
// Inserting SKU
if( ! empty( $variation_data['sku'] ) ){
$html .= '</div><div class="woocommerce-variation-sku">' . __('SKU:') . ' ' . $variation_data['sku'];
}
// Using the variation description to add dynamically the SKU and the GTIN
$variation_data['variation_description'] .= $html;
return $variation_data;
}
Can anyone help with changing the order of this code so the SKU shows below the product title, or help me with some new code?
Many thanks!

WooCommerce does not provide a specific action hook that will let you add anything right after the product title, that also makes use of the variation data like the hook in your current code. You can work around this by adding an element after the product title via JavaScript/jQuery.
You want this element to dynamically change based on the selected variation. Since you do not have access to the variation data directly in the action hook you will have to check the hidden input variation_id that WooCommerce uses to store the selected variation id. Then use AJAX every time that input changes to retrieve the variation SKU belonging to this variation id.
add_action( 'woocommerce_before_single_product', 'show_variation_sku_underneath_product_title' );
function show_variation_sku_underneath_product_title() {
global $product;
if ( $product->is_type('variable') ) {
?>
<script>
jQuery(document).ready(function($) {
$('input.variation_id').change( function(){
if( '' != $('input.variation_id').val() ) {
jQuery.ajax( {
url: '<?php echo admin_url( 'admin-ajax.php'); ?>',
type: 'post',
data: {
action: 'get_variation_sku',
variation_id: $('input.variation_id').val()
},
success: function(data) {
$('h1.product_title').siblings('.variation-sku').remove();
if(data.length > 0) {
$('h1.product_title').after('<p class="variation-sku">' + data + '</p>');
}
}
});
}
});
});
</script>
<?php
}
}
add_action('wp_ajax_get_variation_sku' , 'get_variation_sku');
add_action('wp_ajax_nopriv_get_variation_sku','get_variation_sku');
function get_variation_sku() {
$variation_id = intval( $_POST['variation_id'] );
$sku = '';
if ( $product = wc_get_product( $variation_id ) ) $sku = $product->get_sku();
echo $sku;
wp_die(); // this is required to terminate immediately and return a proper response
}
These code snippets should be added to the functions.php of your child theme or via a plugin like Code Snippets.

Related

Add some attribute values to WooCommerce variable product title from chosen variation (extended) [duplicate]

I'm looking for some help getting the WooCommerce variable product title to change based on variations. In this specific case I would like the title to change when a color is selected, like "Productname Black".
Is there any easy snippet to get this to work?
UPDATE 04-2021 - Successfully tested on WooCommerce 5.1+ (handle custom product attributes)
The following code, will add to variable product title the value(s) of the chosen variation from specific defined product attribute(s) (or all of them optionally too):
The code:
// Defining product Attributes term names to be displayed on variable product title
add_filter( 'woocommerce_available_variation', 'filter_available_variation_attributes', 10, 3 );
function filter_available_variation_attributes( $data, $product, $variation ){
// Here define the product attribute(s) slug(s) which values will be added to the product title
// Or replace the array with 'all' string to display all attribute values
$attribute_names = array('Custom', 'Color');
foreach( $data['attributes'] as $attribute => $value ) {
$attribute = str_replace('attribute_', '', $attribute);
$attribute_name = wc_attribute_label($attribute, $variation);
if ( ( is_array($attribute_names) && in_array($attribute_name, $attribute_names) ) || $attribute_names === 'all' ) {
$value = taxonomy_exists($attribute) ? get_term_by( 'slug', $value, $attribute )->name : $value;
$data['for_title'][$attribute_name] = $value;
}
}
return $data;
}
// Display to variable product title, defined product Attributes term names
add_action( 'woocommerce_after_variations_form', 'add_variation_attribute_on_product_title' );
function add_variation_attribute_on_product_title(){
// Here define the separator string
$separator = ' - ';
?>
<script type="text/javascript">
(function($){
var name = '<?php global $product; echo $product->get_name(); ?>';
$('form.cart').on('show_variation', function(event, data) {
var text = '';
$.each( data.for_title, function( key, value ) {
text += '<?php echo $separator; ?>' + value;
});
$('.product_title').text( name + text );
}).on('hide_variation', function(event, data) {
$('.product_title').text( name );
});
})(jQuery);
</script>
<?php
}
Displaying all attributes
You can display all variations attributes values for the chosen variation by defining the variable $attribute_names to "all" so like:
$attribute_names = "all";
Code goes in functions.php file of your active child theme (or theme) or also in any plugin file.
Tested and works… you will get something like:

How to Add custom price on single product without affecting to related product?

I have code to changes the custom message on all product with 2 different messages. Please take a look.
add_filter('woocommerce_empty_price_html', 'show_alert_info_if_no_price');
function show_alert_info_if_no_price ($product){
if (is_product()) {
global $product;
$price = $product->get_price();
if ($price == '') {
ob_start();
// return for the product page
return '<div class="alert-info">Produk ini hanya dapat diproses melakukan pemesanan pembelian (PO). Segera hubungi tim kami. Kontak kami</div>';
} else {
// otherwise return short text as kontak kami
return 'Contact us';
}
}
}
Now I have a problem on related product. I need the related product price will appear like :
//short text as kontak kami
Now I am stuck how to add another code when using hooked.
$woocommerce_loop['name'] != 'related').
any help will appreciated!
There is an mistake in your code, because this hook is only executed for empty prices. So going to check in the hook again for an empty price and if it isn't, running an else condition is useless.
To display a different text on the single product page for related products you can use global $woocommerce_loop
So you get:
function filter_woocommerce_empty_price_html( $html, $product ) {
global $woocommerce_loop;
// True on a single product page
if ( is_product() ) {
$html = '<div class="alert-info">Produk ini hanya dapat diproses melakukan pemesanan pembelian (PO). Segera hubungi tim kami. Kontak kami</div>';
// Related
if ( $woocommerce_loop['name'] == 'related' ) {
$html = __( 'Some other text', 'woocommerce' );
}
}
return $html;
}
add_filter( 'woocommerce_empty_price_html', 'filter_woocommerce_empty_price_html', 10, 2 );

Show the name of the chosen variation under the product title on the My Account > Downloads page

By default WooCommerce shows the attribute of a variable product in the title and I'm using this code to show the attribute below the title in the cart and checkout pages:
add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
add_filter( 'woocommerce_is_attribute_in_product_name', '__return_false' );
But that doesn't work in My Account page, users see the full product name with no attribute.
To fix it I'm using the code below to show the attribute in the product title:
function show_attributes_outside_title_1( $enabled ) {
if ( !is_account_page() ) {
$enabled = false;
}
return $enabled;
}
add_filter( 'woocommerce_product_variation_title_include_attributes', 'show_attributes_outside_title_1' );
function show_attributes_outside_title_2( $enabled ) {
if ( !is_account_page() ) {
$enabled = false;
}
return $enabled;
}
add_filter( 'woocommerce_is_attribute_in_product_name', 'show_attributes_outside_title_2' );
But I'd like to show the attribute below the title (or a new column), it's easier to read and goes with the same desing you see in the cart and checkout pages.
There is some confusion in the initial part of the question.
You say you want to show the attribute under the product title on the cart and checkout page but then return __return_false, do you intend to do the opposite?
SOLUTION #1
You may want to reverse the check to make sure that your chosen product variation attribute is shown under the product name on your account page under Downloads (as evidenced by your comment above):
add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
add_filter( 'woocommerce_is_attribute_in_product_name', '__return_false' );
add_filter( 'woocommerce_product_variation_title_include_attributes', 'show_attributes_outside_title_1' );
function show_attributes_outside_title_1( $enabled ) {
if ( is_account_page() ) {
$enabled = true;
}
return $enabled;
}
add_filter( 'woocommerce_is_attribute_in_product_name', 'show_attributes_outside_title_2' );
function show_attributes_outside_title_2( $enabled ) {
if ( ! is_account_page() ) {
$enabled = false;
}
return $enabled;
}
SOLUTION #2
If you want to leave the code in your question unchanged you can use the woocommerce_account_downloads_column_download-product hook where download-product is the id of the product name column (in the /my-account/downloads/ page). Here the documentation.
Finally, with the wc_get_formatted_variation function you can get the name of the chosen variation. For more information on parameters read the documentation.
// shows the variation chosen in the product name in the download table of the my-account page
add_action( 'woocommerce_account_downloads_column_download-product', 'change_product_download_name', 10, 1 );
function change_product_download_name( $download ) {
// gets the product object
$product = wc_get_product( $download['product_id'] );
// gets the name of the produc
$product_name = $download['product_name'];
// if the product is a variation
if ( $product->is_type( 'variation' ) ) {
// gets the name of the product with the chosen variation
$product_name = $product->get_name() . " - " . wc_get_formatted_variation( $product, true, false, false );
}
// print the product name (with or without product url)
if ( $download['product_url'] ) {
echo '' . esc_html( $product_name ) . '';
} else {
echo esc_html( $product_name );
}
}
The code has been tested and works. Add it to your active theme's functions.php.
I changed Vincenzo's answer a bit to make it look the same way I see the attributes in my Cart and Checkout pages. Here's the code in case anybody else needs it:
// Shows the variation chosen in the product name in the download table of the my-account page
add_action( 'woocommerce_account_downloads_column_download-product', 'change_product_download_name', 10, 1 );
function change_product_download_name( $download ) {
// gets the product object
$product = wc_get_product( $download['product_id'] );
// gets the name of the product
$product_name = $download['product_name'];
// define variable
$product_attributes = '';
// if the product is a variation
if ( $product->is_type( 'variation' ) ) {
// gets the name of the product with the chosen variation
$product_name = $product->get_name();
$product_attributes = wc_get_formatted_variation( $product, true, true, false );
}
// print the product name (with or without product url)
if ( $download['product_url'] ) {
echo '' . esc_html( $product_name ) . '<p>' . esc_html( $product_attributes ) . '</p>';
} else {
echo esc_html( $product_name ) . '<p>' . esc_html( $product_attributes ) . '</p>';
}
}
// Shows variation outside title in cart and checkout pages
add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
add_filter( 'woocommerce_is_attribute_in_product_name', '__return_false' );
The last two filters replace my code and the first part solves the issue in the Downloads page.

How to add/update custom cart item data in the cart page

I want to add a comment to individual products in the cart page. I am new to woocommerce wordpress plugin so I have no idea how to do.
I have done some research. In that tutorial, I found that I can use woocommerce_add_cart_item_data hook this way:
add_filter( 'woocommerce_add_cart_item_data', 'add_comment', 10, 3 );
function add_comment( $cart_item_data, $product_id, $variation_id ) {
$cart_item_data['comment'] = 'This is comment';
return $cart_item_data;
}
but this does not work in my case.
I attach the Cart page image so you can understand.
I hope you guys understand what I want?
Thank you.
Below code will add a custom text to an item in cart:
You need to create a custom field "comment" for the product to use it here.
add_filter( 'woocommerce_add_cart_item_data', 'add_comment', 10, 3 );
function add_comment( $cart_item_data, $product_id, $variation_id ) {
$cart_item_data['comment'] = 'This is comment';
return $cart_item_data;
}
Add a Custom text/comment before Cart table in Cart Page:
add_action( 'woocommerce_before_cart_table', 'add_comment' );
function add_comment()
{
echo '<div class="woocommerce-info">This is comment</div>';
}
Add a Custom text/comment after Cart table in Cart Page:
add_action( 'woocommerce_after_cart_table', 'add_comment' );
function add_comment() {
echo '<div class="woocommerce-info">This is comment</div>';
}
HOW TO ADD AN INPUT FIELD TO WOOCOMMERCE CART ITEMS & Let users update input fields in the cart
https://pluginrepublic.com/how-to-add-an-input-field-to-woocommerce-cart-items/
Refer this link for a working solution to similar request:
https://stackoverflow.com/a/21818028/12291365
If you are okay with using the plugin, then this plugin will do the trick:
https://wordpress.org/plugins/wc-fields-factory/
Use code snippet below for adding custom values for each cart item.
Please add your logic for attaching values for each item
// Add custom value into cart item
add_filter('woocommerce_add_cart_item_data','sub_add_item_data',1,2);
if(!function_exists('sub_add_item_data'))
{
function sub_add_item_data($cart_item_data,$product_id)
{
// use condition for adding custom value here
$new_value = array(
'sub_custom_value' => 'custom value',
);
return array_merge($cart_item_data,$new_value);
}
}
// Extract custom values
add_filter('woocommerce_get_cart_item_from_session', 'sub_get_cart_items_from_session', 1, 3 );
if(!function_exists('sub_get_cart_items_from_session'))
{
function sub_get_cart_items_from_session($item,$values,$key)
{
if (array_key_exists( 'sub_custom_value', $values ) )
{
$item['sub_custom_value'] = $values['sub_custom_value'];
}
return $item;
}
}
// display in cart and checkout
add_filter('woocommerce_checkout_cart_item_quantity','sub_add_user_custom_option_from_session_into_cart',1,3);
add_filter('woocommerce_cart_item_price','sub_add_user_custom_option_from_session_into_cart',1,3);
if(!function_exists('sub_add_user_custom_option_from_session_into_cart'))
{
function sub_add_user_custom_option_from_session_into_cart($product_name, $values, $cart_item_key )
{
if(isset( $values['sub_custom_value'] ) && '' != $values['sub_custom_value'] )
{
$return_string = $product_name . "</a><dl class='variation'>";
$return_string .= "<table class='sub_options_table' id='" . $values['product_id'] . "'>";
$return_string .= "<tr><td>" . $values['sub_custom_value'] . "</td></tr>";
$return_string .= "</table></dl>";
return $return_string;
}
else
{
return $product_name;
}
}
}

Showing 'Please choose product options…' on checkout page after clicks custom checkout button

I have created custom checkout button in single product page. It is working fine.But after selected the variation with checkout button,it redirects to the checkout page with this error 'Please choose product options…'.
This is my code
function add_content_after_addtocart() {
global $woocommerce;
// get the current post/product ID
$current_product_id = get_the_ID();
// get the product based on the ID
$product = wc_get_product( $current_product_id );
// get the "Checkout Page" URL
$checkout_url = WC()->cart->get_checkout_url();
// run only on simple products
if( $product->is_type( 'variable' ) ){
?>
<script>
jQuery(function($) {
<?php /* if our custom button is clicked, append the string "&quantity=", and also the quantitiy number to the URL */ ?>
// if our custom button is clicked
$(".custom-checkout-btn").on("click", function() {
// get the value of the "href" attribute
$(this).attr("href", function() {
// return the "href" value + the string "&quantity=" + the current selected quantity number
return this.href + '&quantity=' + $('input.qty').val();
});
});
});
</script>
<?php
echo '<div class="col-sm-6"><div class="buy_now"><a href="'.$checkout_url.'?add-to-cart='.$current_product_id.'" class="single_add_to_cart_button buy_now_button button alt disabled custom-checkout-btn ajax_add_to_cart" >Buy Now</a></div></div><div class="clearfix"></div>';
?>
<?php
}
else if( $product->is_type( 'simple' ) ){
echo '</div><div class="col-sm-6"><div class="p-t-35"></div><div class="buy_now">Buy Now</div></div><div class="clearfix"></div>';
}
}
add_action( 'woocommerce_after_add_to_cart_button', 'add_content_after_addtocart' );
Please help me..
I had the same issue and I had contacted WooThemes support team and they said that
"We limit the amount of variations we show on the front end for speed.
But sometimes you need more than 36 variations, so we offer that
filter to override that limitation."
Please add this code below in the functions.php file.
function custom_wc_ajax_variation_threshold( $qty, $product )
{
return 100;
}
add_filter( 'woocommerce_ajax_variation_threshold', 'custom_wc_ajax_variation_threshold', 100, 2 );

Resources