WooCommerce show on-sale badge only for logged in users - php

I want to display sale bubble in WooCommerce only for logged in users.
I have a function which hides sale-bubble for unlogged users but if I log in there is showing only value "1" instead of sale-bubble.
I know why, because I am returning a true, but I cant figure out how to return sale-bubble instead of true..
WooCommerce
add_filter('woocommerce_sale_flash', 'woo_custom_hide_sales_flash');
function woo_custom_hide_sales_flash()
{
if ( is_user_logged_in() ) {
return true;
}
return false;
}

You are not using this filter hook in the right way. Try the following:
add_filter( 'woocommerce_sale_flash', 'filter_sales_flash_callback', 100, 3 );
function filter_sales_flash_callback( $output_html, $post, $product )
{
if ( ! is_user_logged_in() ) {
$output_html = false;
}
return $output_html;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.

function sales_badge() {
global $product;
if ( ! $product->is_on_sale() ) return;
if ( $product->is_type( 'simple' ) ) {
$max_percentage = ( ( $product->get_regular_price() - $product->get_sale_price() ) / $product->get_regular_price() ) * 100;
} elseif ( $product->is_type( 'variable' ) ) {
$max_percentage = 0;
foreach ( $product->get_children() as $child_id ) {
$variation = wc_get_product( $child_id );
$price = $variation->get_regular_price();
$sale = $variation->get_sale_price();
if ( $price != 0 && ! empty( $sale ) ) $percentage = ( $price - $sale ) / $price * 100;
if ( $percentage > $max_percentage ) {
$max_percentage = $percentage;
}
}
}
if ( $max_percentage > 0 ) { ?>
<span class="prinjal-sale-badge"><?php echo round($max_percentage) . "%"; ?></span>
<?php
}
}
// use shortcode instead of action and then use shortcode anywhere you want to ouptut it
add_shortcode( 'custom_sales_badge', 'sales_badge' );
my problem solve using this code you can place any ware you want to display sale badge

function sales_markup() {
if(!is_admin()) {
if(is_user_logged_in()) {
// Instead of outputting add the markup that you want to show
$output = '<div class="Sales_markup_here">
</div>';
return $output;
}
}
}
// use shortcode instead of action and then use shortcode anywhere you want to ouptut it
add_shortcode( 'sales_markup', 'sales_markup' );
Use the shortcode where you want to output the bubble. You can add the css in the global css file.

Related

How to override Schema 'availability' in Woocommerce?

I need to override Schema 'availability' option to Preorder for Woocommerce (3.9.2) products on backorder. Currently WC generates 'InStock' for them. Which filters and how do I apply? My current code (below) ruins Wordpress, seems like filter is wrong:
function tt_WC_change_schema_availability( $availability ) {
if ( is_product() && ! is_admin() ) {
$stock_status = $product->is_in_stock();
$output = 'OutOfStock'; // default, out of stock
if ($stock_status){
$output = 'InStock';
$qty = $product->get_stock_quantity();
if ( ! ($qty > 0) ) {
$output = 'PreOrder';
}
}
return 'http://schema.org/' . $output;
}
}
add_filter( 'woocommerce_structured_data_product_offer', 'tt_WC_change_schema_availability' );
It looks like you are close, but the $product object also has to be included in your function. It's the second parameter that can be passed to this filter. Also, you want to return part of the array that gets sent to the woocommerce_structured_data_product_offer filter. This would be $availability['availability'] since you're passing the variable as $availability
function tt_WC_change_schema_availability( $availability, $product ) {
if ( is_product() && ! is_admin() ) {
$stock_status = $product->get_stock_status();
$output = 'OutOfStock'; // default, out of stock
if ($stock_status){
$output = 'InStock';
$qty = $product->get_stock_quantity();
if ( ! ($qty > 0) ) {
$output = 'PreOrder';
}
}
return $availability['availability'] = 'http://schema.org/' . $output;
}
}
add_filter( 'woocommerce_structured_data_product_offer', 'tt_WC_change_schema_availability' , 10, 2 );
Many thanks to #Howard E! I've found out that $stock_status returns a string, also added extra check if product stock's managed. Here's working function:
function tt_WC_change_schema_availability( $markup_offer, $product ) {
if ( is_product() && ! is_admin() ) {
$managed = $product->managing_stock();
if ($managed === TRUE) {
$stock_status = $product->get_stock_status();
if ($stock_status == 'instock'){
$output = 'InStock';
}
if ($stock_status == 'onbackorder') {
$output = 'PreOrder';
}
if ($stock_status == 'outofstock') {
$output = 'OutOfStock';
}
}
$markup_offer['availability'] = 'http://schema.org/' . $output;
}
return $markup_offer;
}
add_filter( 'woocommerce_structured_data_product_offer', 'tt_WC_change_schema_availability' , 10, 2 );

Display variable product discounted percentage only on Woocommerce archive pages

I'd like to display the percentage variable products are discounted in the archive pages. With the code below, I was able to get both the discounts % on variable products but also for simple products. Can I do this ONLY for variable products and not simple products? I realize it's probably a simple adjustment in the code but I can't figure it out because I'm an idiot when it comes to PHP.
add_action( 'woocommerce_after_shop_loop_item', 'show_sale_percentage', 25 );
function show_sale_percentage() {
global $product;
if ( $product->is_on_sale() ) {
if ( ! $product->is_type( 'variable' ) ) {
$max_percentage = ( ( $product->get_regular_price() - $product->get_sale_price() ) / $product->get_regular_price() ) * 100;
} else {
$max_percentage = 0;
foreach ( $product->get_children() as $child_id ) {
$variation = wc_get_product( $child_id );
$price = $variation->get_regular_price();
$sale = $variation->get_sale_price();
if ( $price != 0 && ! empty( $sale ) ) $percentage = ( $price - $sale ) / $price * 100;
if ( $percentage > $max_percentage ) {
$max_percentage = $percentage;
}
}
}
echo "<div class='saved-sale'>-" . round($max_percentage) . "%</div>";
}
}
To display the on sale percentage, on archives pages, for variable products only, try the following:
add_action( 'woocommerce_after_shop_loop_item', 'loop_variable_product_sale_percentage', 25 );
function loop_variable_product_sale_percentage() {
global $product;
if ( $product->is_on_sale() && $product->is_type( 'variable' ) ) {
$max_percentage = 0;
foreach ( $product->get_children() as $child_id ) {
$variation = wc_get_product( $child_id );
$percentage = 0;
$price = $variation->get_regular_price();
$sale = $variation->get_sale_price();
if ( $price != 0 && ! empty( $sale ) ) {
$percentage = ( $price - $sale ) / $price * 100;
}
if ( $percentage > $max_percentage ) {
$max_percentage = $percentage;
}
}
echo '<div class="saved-sale">-' . round($max_percentage) . '%</div>';
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Change price of product in WooCommerce cart and checkout

I'm creating a WooCommerce add-on to customize the product, based on selected options by the visitor and custom price is calculated and stored into session table also.
I am able to get that value in cart page also.
My problem: I would like to change the default price of the product and replace it with new calculated value in the WooCommerce process as cart, checkout, payment, mail notifications, order...
Any advice please?
Thanks
Ce right hook to get it working is woocommerce_before_calculate_totals. But you will have to complete (replace) the code to get the new price in the hooked function below:
add_action( 'woocommerce_before_calculate_totals', 'custom_cart_items_prices', 10, 1 );
function custom_cart_items_prices( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Loop Through cart items
foreach ( $cart->get_cart() as $cart_item ) {
// Get the product id (or the variation id)
$product_id = $cart_item['data']->get_id();
// GET THE NEW PRICE (code to be replace by yours)
$new_price = 500; // <== Add your code HERE
// Updated cart item price
$cart_item['data']->set_price( $new_price );
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works on WooCommerce versions 3+. But as you don't give any code I can't test it for real getting the new price from session…
function save_subscription_wrap_data( $cart_item_data, $product_id ) {
$include_as_a_addon_subscription = get_field('include_as_a_addon_subscription',$product_id);
$subscricption_product_data = get_field('subscricption_product',$product_id);
$current_user = is_user_logged_in() ? wp_get_current_user() : null;
$subscriptions = wcs_get_users_subscriptions( $current_user->ID );
if($include_as_a_addon_subscription == "yes")
{
foreach ( $subscriptions as $subscription_id => $subscription ) {
$subscription_status = $subscription->get_status();
}
if($subscription_status == 'active')
{
$cart_item_data[ "subscribe_product" ] = "YES";
}
}
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'save_subscription_wrap_data', 99, 2 );
function render_meta_on_cart_and_checkout1( $cart_data, $cart_item = null ) {
$meta_items = array();
if( !empty( $cart_data ) ) {
$meta_items = $cart_data;
}
if( isset( $cart_item["subscribe_product"] ) ) {
$meta_items[] = array( "name" => "Product Type", "value" => "Package Addon" );
}
return $meta_items;
}
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout1', 100, 2 );
function calculate_gift_wrap_fee( $cart_object ) {
if( !WC()->session->__isset( "reload_checkout" )) {
$additionalPrice = 100;
foreach ( WC()->cart->get_cart() as $key => $value ) {
if( isset( $value["subscribe_product"] ) ) {
if( method_exists( $value['data'], "set_price" ) ) {
$orgPrice = floatval( $value['data']->get_price() );
//$value['data']->set_price( $orgPrice + $additionalPrice );
$value['data']->set_price(0);
} else {
$orgPrice = floatval( $value['data']->price );
//$value['data']->price = ( $orgPrice + $additionalPrice );
$value['data']->price = (0);
}
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'calculate_gift_wrap_fee', 99 );

Determine language in functions.php [wpml]

I have function in functions.php , which automatically adds woocommerce product by ID to cart when website is visited.
The website is bilingual and the function can't determine translated product ID.
So, I want to know if is possible to add wpml function in functions.php, which determines first language of front end, then executes function, something like this:
<?php if(wpml_getLanguage()=='en'); ?>
---do function for product 22---
<?php elseif(wpml_getLanguage()=='it'); ?>
---do function for product 45--
<?php endif; ?>
My code:
add_action( 'template_redirect', 'add_product_to_cart' );
function add_product_to_cart() {
if ( ! is_admin() ) {
$product_id = 22;
$found = false;
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $product_id );
}
}
}
You can easily get this by using the native WPML variable ICL_LANGUAGE_CODE.
You can find more information about this topic on the following page:
https://wpml.org/documentation/support/wpml-coding-api/
This can be dropped into functions.php
add_action( 'init', 'add_product_on_language' );
function add_product_on_language(){
if ( ! is_admin() ) {
if( ICL_LANGUAGE_CODE == 'en' ){
$product_id = 22;
} elseif ( ICL_LANGUAGE_CODE == 'it' ) {
$product_id = 45;
}
$found = false;
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $product_id );
}
}
}

Disabling Amazon Payments Advanced method from WooCommerce checkout page

I'm trying to disable a couple of payment gateways based on a user's role. The function & hook I found works on the Paypal method but not Amazon Payments Advanced. Here's my code:
function wk_disable_gateways( $available_gateways ) {
global $woocommerce;
$wholesale_cust = check_user_role( array( 'wholesale', 'orig-wholesale' ) );
if ( isset( $available_gateways['paypal'] ) && $wholesale_cust ) {
unset( $available_gateways['paypal'] );
}
if ( isset( $available_gateways['amazon_payments_advanced'] ) && $wholesale_cust ) {
unset( $available_gateways['amazon_payments_advanced'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'wk_disable_gateways' );
The "Pay with Amazon" code is still running on the checkout page. Any ideas?
This is not the best solution, but I have not been able to find a more viable answer.
First off I did what you did and disabled all gateways expect the one I wanted the user to use. In my case I only want someone to check out with the nmigateway.
This goes inside of your theme functions.php
add_filter( 'woocommerce_available_payment_gateways', 'filter_gateways', 1);
function filter_gateways( $gateways ){
global $woocommerce;
// what products you wish to exculde
$nonPPproducts = array(1457, 1447, 479); // LIST YOUR PRODUCT IDS HERE
foreach ($woocommerce->cart->cart_contents as $key => $values ) {
if ( in_array( $values['product_id'], $nonPPproducts ) ) {
foreach ( $gateways as $gateway_key => $gateway ) {
if ( $gateway_key !== 'nmipay' ) {
unset( $gateways[ $gateway_key ] );
}
}
}
}
return $gateways;
}
Next here is the part that makes this not the best solution editing the plugins source code.
Change the following two functions inside of the plugins/woocommerce-gateway-amazon-payments-advanced/amazon-payments-advanced.php
/**
* Checkout Button
*
* Triggered from the 'woocommerce_proceed_to_checkout' action.
*/
function checkout_button() {
global $woocommerce;
// what products you wish to exculde
$nonPPproducts = array(1457, 1447, 479); // LIST YOUR PRODUCT IDS HERE
foreach ($woocommerce->cart->cart_contents as $key => $values ) {
if ( in_array( $values['product_id'], $nonPPproducts ) ) {
$disable_button = true;
}
}
if(!isset($disable_button) && $disable_button !== true ){
?><div id="pay_with_amazon"></div><?php
}
}
/**
* Checkout Message
*/
function checkout_message() {
global $woocommerce;
// what products you wish to exculde
$nonPPproducts = array(1457, 1447, 479); // LIST YOUR PRODUCT IDS HERE
foreach ($woocommerce->cart->cart_contents as $key => $values ) {
if ( in_array( $values['product_id'], $nonPPproducts ) ) {
$disable_button = true;
}
}
if(!isset($disable_button) && $disable_button !== true ){
if ( empty( $this->reference_id ) ) {
echo '<div class="woocommerce-info info"><div id="pay_with_amazon"></div> ' . apply_filters( 'woocommerce_amazon_pa_checkout_message', __( 'Have an Amazon account?', 'woocommerce-gateway-amazon-payments-advanced' ) ) . '</div>';
}
}
}
Keep in mind that when the plugin is updated all of your changes will be lost.

Categories