This question already has answers here:
Replace WooCommerce variable products price range with 'Up to' and the max price
(2 answers)
Closed 3 years ago.
I want to display the maximum variation price in woocommerce shop page under product title.
I have tried using this code but does not seem to work, only breaks my site instead.
add_filter( ‘woocommerce_variable_sale_price_html’, ‘con_show_max_variation_price_only’, 10, 2 );
add_filter( ‘woocommerce_variable_price_html’, ‘con_show_max_variation_price_only’, 10, 2 );
function con_show_max_variation_price_only( $price, $product ) {
// Main Variation Price
$prices = array( $product->get_variation_price( ‘max’, true ), $product->get_variation_price( ‘min’, true ) );
$price = $prices[0] !== $prices[1] ? sprintf( __( ‘%1$s’, ‘woocommerce’ ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );
I think this is what you want. I tested the code with Envo Multipurpose theme.
// define the woocommerce_variable_price_html callback
function filter_woocommerce_variable_price_html( $wc_format_price_range, $instance ) {
$index = strpos($wc_format_price_range, "– ");
$wc_format_price_range = substr($wc_format_price_range, $index+7);
//This will remove the first price by dividing the standard string with dash
//You may add a prefix like, $wc_format_price_range = "Max Price: $wc_format_price_range";
return $wc_format_price_range;
};
// add the filter
add_filter( 'woocommerce_variable_price_html', 'filter_woocommerce_variable_price_html', 10, 2 );
I hope this will help you. Have a good day.
Related
Want to display discount percentage badge on right hand side of product image and sale badge on left hand side of product image in products slider. So, Please Suggest some hooks for this functionality!
Tried to add the following hook but it will replace the existing sale badge with the discount percentage badge on shop page and also this hook is not working for the product slider on homepage.
add_filter('woocommerce_sale_flash', 'add_percentage_to_sale_bubble'); function add_percentage_to_sale_bubble( $html ) { global $product; $percentage = round( ( ( $product->regular_price - $product->sale_price ) / $product->regular_price ) * 100 ); $output =' <span class="onsale">'.$percentage.'%</span>'; return $output; }
you can use the following hook
add_filter( 'woocommerce_get_price_html', 'change_displayed_sale_price_html', 10, 2 );
function change_displayed_sale_price_html( $price, $product ) {
// Only on sale products on frontend and excluding min/max price on variable products
if( $product->is_on_sale() && ! is_admin() && $product->is_type('simple') ){
// Get product prices
$regular_price = (float) $product->get_regular_price(); // Regular price
// Active price (the "Sale price" when on-sale)
$sale_price = (float) $product->get_price();
// "Saving Percentage" calculation and formatting
$precision = 0; // Max number of decimals
$saving_percentage = round( 100 - ( $sale_price / $regular_price * 100 ), $precision ) . '%';
// Append to the formated html price
$price .= sprintf( __('<p class="saved-sale">%s</p>', 'woocommerce' ), $saving_percentage );
}
return $price;
}
Here is what I am trying to accomplish: turn off a True/False Advanced Custom Fields(ACF) option on a post if the current date is on or past a selected date on the same post. Also after that code, turn off a Sample Lesson True/False option inside of the lessons attached to the current post.
At first, all I had was the update_sample_child_lessons function with an 'init' action (i.e.add_action( 'init', 'update_sample_child_lessons' );), but that seemed to only run when I clicked update on the post. It did work and everything switched over, but it only ran when I manually clicked Update on the post. So then I did a little research and found that a Cron job should do the trick if I want the code to run automatically without me having to click update, but for some reason I can't seem to get it to work.
So if you know of a way to accomplish what I am trying to do with the code below, or with other code that is completely different, any suggestions or help would be much appreciated.
//CRON JOB TO RUN EVERYDAY
function myprefix_custom_cron_schedule( $schedules ) {
$schedules['every_day'] = array(
'interval' => 86400, //24 HOURS IN SECONDS
'display' => __( 'Every 24 hours' ),
);
return $schedules;
}
add_filter( 'cron_schedules', 'myprefix_custom_cron_schedule' );
if ( ! wp_next_scheduled( 'myprefix_cron_hook' ) ) {
wp_schedule_event( time(), 'every_day', 'myprefix_cron_hook' );
}
//AUTOMATICALLY ADJUSTS SAMPLE LESSON FREE OPTIONS AND FREE BANNER IF DATE IS PASSED
add_action( 'myprefix_cron_hook', 'update_sample_child_lessons' );
function update_sample_child_lessons() {
$allcourses = array(
'post_type' => 'sfwd-courses', //CUSTOM POST TYPE: COURSES
'posts_per_page' => -1 //QUERY ALL OF THEM
);
$query = new WP_Query($allcourses);
if ($query->have_posts()) {
global $post;
if ( ( in_array( $post->post_type, array( 'sfwd-courses' ), true ) )) { //ONLY DO ACTION IF ON CPT OF COURSES
while ($query->have_posts()) {
$query->the_post();
$course_id = learndash_get_course_id( $post->ID ); //GET THE COURSE ID
$free = get_field('display_free_lessons', $course_id); //GET THE FREE COURSE OPTION (TRUE/FALSE TICKER)
if (!empty($free)) { //ONLY DO REST OF CODE IF FREE OPTION IS TURNED ON
$freeDate = get_field('free_until', $course_id); //GET THE DATE FIELD THAT THE COURSE IS FREE UNTIL
$currentDate = date('Ymd'); //GET CURRENT DATE
$diff = strtotime($freeDate) - strtotime($currentDate); //GET THE DIFFERENCE BETWEEN THE TWO DATES
if ($diff <= 0) { //ONLY DO REST OF CODE IF DATE DIFFERENCE IS LESS THAN OR EQUAL TO ZERO
$value = '';
update_field('display_free_lessons', $value, $course_id); //UPDATES THE FREE OPTION FIELD TO FALSE(OR NOTHING)
//LESSON CODE
$lessons = array_slice(learndash_course_get_lessons($course_id), 1); //GET ALL THE LESSONS FROM THE COURSE EXCEPT FOR THE FIRST ONE
foreach ($lessons as $lesson) {
$lessonID = $lesson->ID; //GET THE LESSON ID
$lesson_meta = get_post_meta($lessonID); //GET THE METADATA FOR THE LESSON
if ( is_array( $lesson_meta ) ) {
foreach ( $lesson_meta as $meta_key => $meta_value ) {
if ( '_sfwd-lessons' === $meta_key ) {
$lesson_settings = maybe_unserialize( $meta_value[0] ); //SOME OF THE ARRAYS ARE SERIALIZED, SO UNSERIALIZE IF NEEDED
if ( isset( $lesson_settings['sfwd-lessons_sample_lesson'] ) ) {
$lesson_settings['sfwd-lessons_sample_lesson'] = ''; //TURN OFF THE SAMPLE LESSON OPTION ON THE LESSONS
}
update_post_meta( $lessonID, $meta_key, $lesson_settings );
}
}
}
} //END FOREACH
} //END IF DIFF IS 0
wp_reset_postdata();
}
}
}
}
}
Thanks for the comment #Luke Chaffey, I was actually able to figure it out after finding I had my cron actions reversed. Below is the final code that I got working so that it runs every day at 12am:
//CRON JOB TO RUN EVERYDAY
function custom_cron_schedule( $schedules ) {
$schedules['every_day'] = array(
'interval' => 86400,
'display' => __( 'Every 24 hours' ),
);
return $schedules;
}
add_filter( 'cron_schedules', 'custom_cron_schedule' );
$ve = get_option('gmt_offset') > 0 ? '-' : '+';
if ( ! wp_next_scheduled('cron_sample_lesson' ) ) {
wp_schedule_event(strtotime('00:00 tomorrow ' . $ve .
absint(get_option('gmt_offset')) . ' HOURS'), 'daily','cron_sample_lesson' );
}
add_action('cron_sample_lesson', 'update_sample_child_lessons' );
function update_sample_child_lessons() {...
I am new to BuddyPress and want to hide the member count in the groups. As mentioned in another forum, I tried using this code in bp-custom.php but it doesn't work.
function john_gettext( $translated, $original_text, $domain ) {
if ( 'buddypress' !== $domain )
return $translated;
switch ( $original_text ) {
case 'All Members <span>%s</span>':
return 'All Members';
default:
return $translated;
}
}
add_filter( 'gettext', 'john_gettext', 20, 3 );
Also tried adding this code and doesn't work:
add_filter( ‘bp_get_total_member_count’, ‘bp_core_number_format’ );
Any ways to hide the member count?
gettext is not used in that context. And changing the count integer will result in a zero being shown. But you can filter the existence of a count and thereby remove it.
Try:
function john_member_count( $count, $item, $nav ) {
if ( $nav == 'directory' )
$count = false;
return $count;
}
add_filter( 'bp_nouveau_nav_has_count', 'john_member_count',30, 3 );
I'm wondering if we are able to hook into WooCommerce to set a maximum amount of stock that can be purchased for a variable product. Disregarding the individual variation stock levels once this maximum amount is reached.
For example, I have a variable product selling workshop groups. There are 4 variations, each with a stock level set at 100. This is because no group can have more than 100 people in. However, only 250 tickets are available for sale (not 400 that we might expect because of the 4x100 quantity).
So this works as far as the max 100 places per workshop group. We just need to somehow be able to limit the total stock level of all 4 variations to 250.
I had hoped enabling the parent product "Manage stock" option and setting this to 250 would work. But obviously, variations must override this. If we can hook into that and turn that back on even when variation stock management is in use that might be a nice way of solving this.
Thanks for any help.
I came up with a solution to my problem by doing the following:
Add 2 custom fields to the WooCommerce product page, which will store the max quantity of the total variations we can sell and also the max quantity of an individual variation. The code for this is:
// Modify WooCommerce Product Settings
add_action('woocommerce_product_options_inventory_product_data', 'wc_add_custom_field' );
function wc_add_custom_field() {
$fields = array('Total quantity' => 'total_quantity','Variation quantity' => 'variation_quantity');
$field_description = array('total_quantity' ='description','variation_quantity' ='description');
$field_placeholder = array('total_quantity' =>'e.g. 300','variation_quantity' =>'e.g. 100');
foreach ($fields as $key => $value) {
woocommerce_wp_text_input( array(
'id' => $value,
'label' => $key,
'description' => $field_description[$value],
'desc_tip' => 'true',
'placeholder' => $field_placeholder[$value]
) );
}
}
// Save Fields
add_action( 'save_post_product', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
update_post_meta( $post_id, 'total_quantity', $_POST['total_quantity'] );
update_post_meta( $post_id, 'variation_quantity', $_POST['variation_quantity'] );
}
Add cart/basket validation rules to stop customers being able to purchase products that exceed the value of the custom "total_quantity" field added above:
add_action( "woocommerce_add_to_cart_validation","sc_woocommerce_add_to_cart_validation", 1, 5 );
function sc_woocommerce_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id, $variations ) {
// Iterate through each variation and get the total stock remaining
$product_variable = new WC_Product_Variable($product_id);
$product_variations = $product_variable->get_available_variations();
settype($variation_stock_availability, "integer");
foreach ($product_variations as $variation) {
$variation_stock_availability = +(int)$variation['max_qty'];
}
$count_variations = count($product_variations);
$total_quantity = get_post_meta( $product_id, 'total_quantity', true );
$variation_quantity = get_post_meta( $product_id, 'variation_quantity', true );
// formula to test if any stock remaining based on sold variations
$formula = $count_variations * $variation_quantity;
$formula1 = (int)$formula + (int)$quantity;
$formula1 = $formula1 - $variation_stock_availability;
// Iterating through each cart item and use the current running quantity in the cart in the forumula
foreach (WC()->cart->get_cart() as $cart_item_key=>$cart_item ){
// count(selected category) quantity
$running_qty += (int) $cart_item['quantity'];
$formula2 = (int)$formula + (int)$running_qty;
$formula2 = $formula2 - $variation_stock_availability;
// More than allowed products in the cart is not allowed
if ($formula2 >= $total_places) {
wc_add_notice( sprintf( __( "Unfortunately there is no availability based on your selection", "donaheys" )), 'error' );
$passed = false;
return $passed;
}
}
// More than allowed products in the cart is not allowed
if ($formula1 >= $total_places) {
// Add the error
wc_add_notice( sprintf( __( "Unfortunately there is no availability based on your selection", "donaheys" )), 'error' );
$passed = false;
return $passed;
} else {
$passed = true;
return $passed;
}
$running_qty = 0;
}
The result of the above code ensures we are can set a maximum amount of stock that can be purchased for a variable product, disregarding the individual variation stock levels once this maximum amount is reached.
i'd like that when my product quantity is equal to 1, the product is out of stock ( and not when quantity is equal to 0 ).
Is it possible ?
How ?
In PrestaShop 1.6 (tested and confirmed working in v1.6.0.14) you can accomplish this by the following method, where the website will always show an available stock quantity that is the real quantity minue one. If you have 6 in stock this modification will change your website to report the stock as 5 to your customers, when you have only 1 stock available, customers will see the product with 0 quantity and marked as out of stock.
Copy the file /classes/stock/StockAvailable.php to /override/classes/stock/StockAvailable.php.
Edit the file /override/classes/stock/StockAvailable.php as follows.
At lines 357-380 is the function AvailableStock::getQuantityAvailableByProduct() that will normally read like this (formatting may vary slightly):
public static function getQuantityAvailableByProduct( $id_product,
$id_product_attribute = null, $id_shop = null ) {
if( $id_product_attribute === null ) $id_product_attribute = 0;
$skey = 'StockAvailable::getQuantityAvailableByProduct_' . (int)$id_product . '-' .
(int)$id_product_attribute . '-' . (int)$id_shop;
if( !Cache::isStored( $key )) {
$query = new DbQuery();
$query->select( 'SUM(quantity)' );
$query->from( 'stock_available' );
if( $id_product !== null ) $query->where( 'id_product = ' . (int)$id_product );
$query->where( 'id_product_attribute = ' . (int)$id_product_attribute );
$query = StockAvailable::addSqlShopRestriction( $query, $id_shop );
Cache::store( $key, (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue( $query ));
}
return Cache::retrieve( $key );
}
Replace the last line of the function beginning with the keyword return to the following:
$iStockQty = Cache::retrieve( $key );
if( $iStockQty > 0 ) $iStockQty--;
return $iStockQty;
Delete the file /cache/class_index.php so that Prestashop automatically re-creates this file taking into account the new override file.
I also found the method self::removeProductFromStockAvailable($id_product) in StockAvailable.php to do some similar stuff.