Changeset 3765069
- Timestamp:
- 10/25/2026 06:28:00 PM (2 hours ago)
- Location:
- show-only-lowest-prices-in-woocommerce-variable-products
- Files:
-
- 13 added
- 3 edited
-
tags/2.4.0 (added)
-
tags/2.4.0/assets (added)
-
tags/2.4.0/assets/css (added)
-
tags/2.4.0/assets/css/admin.css (added)
-
tags/2.4.0/assets/js (added)
-
tags/2.4.0/assets/js/admin.js (added)
-
tags/2.4.0/changelog.txt (added)
-
tags/2.4.0/includes (added)
-
tags/2.4.0/includes/class-ayudawp-lowest-prices-promo-banner.php (added)
-
tags/2.4.0/readme.txt (added)
-
tags/2.4.0/show-lowest-woo-variable-prices.php (added)
-
tags/2.4.0/uninstall.php (added)
-
tags/2.4.0/wpml-config.xml (added)
-
trunk/changelog.txt (modified) (1 diff)
-
trunk/readme.txt (modified) (5 diffs)
-
trunk/show-lowest-woo-variable-prices.php (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
show-only-lowest-prices-in-woocommerce-variable-products/trunk/changelog.txt
r3653570 r3765069 3 3 For each release, see the entries below. The latest version is always at the top. 4 4 The current release notes also live in readme.txt under "== Changelog ==". 5 6 = 2.4.0 = 7 * New: Works with Scheduled Sales, Discounts and Omnibus Price History for WooCommerce, from the same author, for the prior price of the EU Omnibus Directive. With it active, the discount percentage badge is calculated on the prior price (the lowest price of the 30 days before the sale) instead of the regular price, and no badge is shown when the sale price is not lower than the prior price 8 * New: The prior price note of Scheduled Sales, Discounts and Omnibus Price History for WooCommerce goes right after the price, only once, and describes the variation shown, also in the "Up to" mode 9 * New: When Scheduled Sales, Discounts and Omnibus Price History for WooCommerce crosses out the prior price, which it does by default, the price crosses out the prior price instead of the regular one, or nothing when the sale price is not lower than it 10 * Improved: The settings page detects Scheduled Sales, Discounts and Omnibus Price History for WooCommerce, and the FAQ about the Omnibus Directive recommends it first 11 * Improved: Tested up to WooCommerce 11.2 5 12 6 13 = 2.3.0 = -
show-only-lowest-prices-in-woocommerce-variable-products/trunk/readme.txt
r3653570 r3765069 5 5 Tested up to: 7.1 6 6 Requires PHP: 7.4 7 Stable tag: 2. 3.07 Stable tag: 2.4.0 8 8 License: GPLv2+ 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 23 23 * **Sales stay visible** - The regular price is kept crossed out next to the sale price, so discounts are not lost in shop and archive pages 24 24 * **Discount badge** - Optionally show the discount percentage next to the price 25 * **EU Omnibus friendly** - With Scheduled Sales, Discounts and Omnibus Price History for WooCommerce, the discount badge is calculated on the prior price of the last 30 days, and by default the crossed out price is that prior price 25 26 * **Out of stock aware** - Leave sold out variations out of the calculation, so the price you advertise is one your customers can actually buy 26 27 * **Where it applies** - Everywhere, shop and archives only, or product pages only … … 101 102 = Does this plugin implement the EU Omnibus Directive (lowest price in the last 30 days)? = 102 103 103 No . This plugin only changes how variable product prices are displayed. It is a presentational feature: it does not track price history and it does not display the prior price (the lowest price applied during the 30 days before a price reduction) required by Directive (EU) 2019/2161, known as the Omnibus Directive. Despite the similar name of some compliance plugins, this one serves a different purpose.104 Not on its own. It only changes how variable product prices are displayed: it does not track price history or show the prior price (the lowest price applied in the 30 days before a price reduction) required by Directive (EU) 2019/2161. 104 105 105 If your store needs to comply with those rules, use a plugin built for it, such as Omnibus - show the lowest price, WC Price History or FleekCode - Omnibus Price Tracker. They work alongside this plugin without conflict: this one decides which price replaces the WooCommerce range, and the other one adds the lowest price of the last 30 days. When one of them is active you will see a notice in the settings page confirming it. 106 For that, use [Scheduled Sales, Discounts and Omnibus Price History for WooCommerce](https://wordpress.org/plugins/multiple-sale-prices-scheduler/), from the same author. It records the price history and shows the prior price, and both plugins work together: 106 107 107 Two things help here. Products on sale keep their regular price crossed out, so a price reduction stays visible instead of showing only the reduced price. And the `ayudawp_lowest_price_html` filter lets you place the price history message exactly where you want it: 108 * The discount percentage badge is calculated on the prior price, as the EU Court of Justice requires (case C-330/23). If the sale price is not lower than the prior price, no badge is shown. 109 * By default it crosses out the prior price instead of the regular one, and so does the price shown by this plugin. If the sale price is not lower than the prior price, nothing is crossed out. 110 * Its prior price note appears right after the price, once, for the variation shown. 111 112 Omnibus - show the lowest price, WC Price History and FleekCode - Omnibus Price Tracker also work alongside this plugin. The settings page tells you when one of these plugins is active. 113 114 To place the price history message exactly where you want it, use the `ayudawp_lowest_price_html` filter: 108 115 109 116 `add_filter( 'ayudawp_lowest_price_html', function ( $html, $product ) { … … 123 130 == Changelog == 124 131 125 = 2.3.0 = 126 * New: Live preview in the settings page, showing how your price will read for three situations at once: variations at different prices, the variation shown on sale, and every variation at the same price. It updates as you change the options and follows the page while you scroll 127 * Improved: Compatible with WordPress 7.1 132 = 2.4.0 = 133 Works with Scheduled Sales, Discounts and Omnibus Price History for WooCommerce for the EU Omnibus prior price: with it active, the discount badge is calculated on the lowest price of the last 30 days, and by default the crossed out price is that prior price. 134 135 * New: Works with Scheduled Sales, Discounts and Omnibus Price History for WooCommerce, from the same author, for the prior price of the EU Omnibus Directive. With it active, the discount percentage badge is calculated on the prior price (the lowest price of the 30 days before the sale) instead of the regular price, and no badge is shown when the sale price is not lower than the prior price 136 * New: The prior price note of Scheduled Sales, Discounts and Omnibus Price History for WooCommerce goes right after the price, only once, and describes the variation shown, also in the "Up to" mode 137 * New: When Scheduled Sales, Discounts and Omnibus Price History for WooCommerce crosses out the prior price, which it does by default, the price crosses out the prior price instead of the regular one, or nothing when the sale price is not lower than it 138 * Improved: The settings page detects Scheduled Sales, Discounts and Omnibus Price History for WooCommerce, and the FAQ about the Omnibus Directive recommends it first 139 * Improved: Tested up to WooCommerce 11.2 128 140 129 141 For older changelog entries, please check the [changelog.txt](https://plugins.svn.wordpress.org/show-only-lowest-prices-in-woocommerce-variable-products/trunk/changelog.txt) file … … 131 143 == Upgrade Notice == 132 144 133 = 2. 3.0 =134 Compatibility release for WordPress 7.1. The settings page now shows a live preview of the price, so you can see how it will read before saving anything.145 = 2.4.0 = 146 Works with Scheduled Sales, Discounts and Omnibus Price History for WooCommerce for the EU Omnibus prior price: with it active, the discount badge is calculated on the lowest price of the last 30 days, and by default the crossed out price is that prior price. 135 147 136 148 == Support == -
show-only-lowest-prices-in-woocommerce-variable-products/trunk/show-lowest-woo-variable-prices.php
r3653570 r3765069 5 5 * Description: Shows only the lowest price and sale in variable WooCommerce products with customizable prefix and advanced options. 6 6 * Author: Fernando Tellado 7 * Version: 2. 3.07 * Version: 2.4.0 8 8 * Author URI: https://ayudawp.com 9 9 * Text Domain: show-only-lowest-prices-in-woocommerce-variable-products … … 13 13 * Requires PHP: 7.4 14 14 * WC requires at least: 4.0 15 * WC tested up to: 11. 015 * WC tested up to: 11.2 16 16 * License: GPLv2+ 17 17 * License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 24 24 25 25 // Plugin constants. 26 define( 'AYUDAWP_LOWEST_PRICES_VERSION', '2. 3.0' );26 define( 'AYUDAWP_LOWEST_PRICES_VERSION', '2.4.0' ); 27 27 define( 'AYUDAWP_LOWEST_PRICES_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); 28 28 define( 'AYUDAWP_LOWEST_PRICES_PLUGIN_PATH', plugin_dir_path( __FILE__ ) ); … … 367 367 368 368 $space = $options['add_space_after_prefix'] ? ' ' : ''; 369 $note = ''; 369 370 370 371 switch ( $mode ) { 371 372 case 'highest': 372 $body = $this->ayudawp_format_price( $max, $max_reg, $options ); 373 $body .= $this->ayudawp_discount_badge( $max, $max_reg, $options ); 374 $body = $this->ayudawp_add_prefix( $body, $options['max_prefix_text'], $space, $same_price, $options ); 375 $amount = $max; 373 $reference = $this->ayudawp_sale_reference( $max_id, $max, $max_reg ); 374 $body = $this->ayudawp_format_price( $max, $reference['strike'], $options ); 375 $body .= $this->ayudawp_discount_badge( $max, $reference['badge'], $options ); 376 $body = $this->ayudawp_add_prefix( $body, $options['max_prefix_text'], $space, $same_price, $options ); 377 $amount = $max; 378 $note = $this->ayudawp_msps_note( $max_id, $max, $max_reg, $product ); 376 379 break; 377 380 … … 397 400 case 'lowest': 398 401 default: 399 $body = $this->ayudawp_format_price( $min, $min_reg, $options ); 400 $body .= $this->ayudawp_discount_badge( $min, $min_reg, $options ); 401 $body = $this->ayudawp_add_prefix( $body, $options['prefix_text'], $space, $same_price, $options ); 402 $amount = $min; 402 $reference = $this->ayudawp_sale_reference( $min_id, $min, $min_reg ); 403 $body = $this->ayudawp_format_price( $min, $reference['strike'], $options ); 404 $body .= $this->ayudawp_discount_badge( $min, $reference['badge'], $options ); 405 $body = $this->ayudawp_add_prefix( $body, $options['prefix_text'], $space, $same_price, $options ); 406 $amount = $min; 407 $note = $this->ayudawp_msps_note( $min_id, $min, $min_reg, $product ); 403 408 break; 404 409 } … … 411 416 412 417 $css_class = ! empty( $options['custom_css_class'] ) ? $options['custom_css_class'] : 'ayudawp-lowest-price'; 413 $html = '<span class="' . esc_attr( $css_class ) . '">' . $body . '</span>' ;418 $html = '<span class="' . esc_attr( $css_class ) . '">' . $body . '</span>' . $note; 414 419 415 420 /** … … 417 422 * 418 423 * Useful to append extra information next to the price, such as the lowest 419 * price of the last 30 days tracked by a price history plugin. 424 * price of the last 30 days tracked by a price history plugin. The prior 425 * price note of Scheduled Sales, Discounts and Omnibus Price History for WooCommerce, when there 426 * is one, is already in it, right after the price. 420 427 * 421 428 * @since 2.2.0 … … 455 462 * 456 463 * @param string|float $price Active price. 457 * @param string|float $regular Regular price of the very same variation. 464 * @param string|float $regular Price to cross out: the regular price of the very 465 * same variation, or its prior price (see 466 * ayudawp_sale_reference()). Nothing is crossed out 467 * unless it is higher than $price. 458 468 * @param array $options Plugin options. 459 469 * @return string … … 472 482 * 473 483 * @param string|float $price Active price. 474 * @param string|float $regular Regular price of the very same variation. 484 * @param string|float $regular Price the discount is measured against: the regular 485 * price of the very same variation, or its prior 486 * price (see ayudawp_sale_reference()). 475 487 * @param array $options Plugin options. 476 488 * @return string Empty string when there is no discount to show. … … 494 506 ) 495 507 ) . '</span>'; 508 } 509 510 /** 511 * Prices a sale of the shown variation is measured against. 512 * 513 * Without a price history the regular price is both the one crossed out and 514 * the one the badge is calculated on. With Scheduled Sales, Discounts and Omnibus Price History for 515 * WooCommerce active, a prior price lower than the regular one takes over 516 * the badge: the EU Court of Justice ruled that a reduction announced as a 517 * percentage is calculated on the prior price (C-330/23, September 2024). 518 * It is also the price crossed out when that plugin is set to cross out the 519 * prior price; otherwise the regular price stays crossed out and the prior 520 * price is left to its note (ayudawp_msps_note()). 521 * 522 * @param int $variation_id Shown variation. 523 * @param string|float $price Its active price, for display. 524 * @param string|float $regular Its regular price, for display. 525 * @return array { 526 * @type string|float $strike Price to cross out. 527 * @type string|float $badge Price the discount badge is calculated on. 528 * } 529 */ 530 private function ayudawp_sale_reference( $variation_id, $price, $regular ) { 531 $reference = array( 532 'strike' => $regular, 533 'badge' => $regular, 534 ); 535 536 // Not on sale: there is no reduction to measure. 537 if ( '' === $regular || (float) $regular <= (float) $price ) { 538 return $reference; 539 } 540 541 $prior = $this->ayudawp_get_msps_prior_price( $variation_id ); 542 543 if ( null === $prior || $prior >= (float) $regular ) { 544 return $reference; 545 } 546 547 $reference['badge'] = $prior; 548 549 if ( function_exists( 'ayudawp_msps_strikes_prior_price' ) && ayudawp_msps_strikes_prior_price() ) { 550 $reference['strike'] = $prior; 551 } 552 553 return $reference; 554 } 555 556 /** 557 * Prior price of a variation from Scheduled Sales, Discounts and Omnibus Price History for WooCommerce. 558 * 559 * That plugin records every price a product had and works out the lowest one 560 * applied in the days before the current price started, which is the prior 561 * price of the EU Omnibus Directive. It is asked for the price as the shop 562 * displays it, with or without tax, because that is how the prices compared 563 * here come out of get_variation_prices( true ). 564 * 565 * Only its public API is used, stable since its version 1.6.0. Earlier 566 * versions do not have it, and their prior price did not yet count the price 567 * in effect when the window opened, so nothing changes with them. 568 * 569 * @param int $variation_id Variation ID. 570 * @return float|null Prior price for display, or null when the plugin is not 571 * active or there is no earlier price to compare. 572 */ 573 private function ayudawp_get_msps_prior_price( $variation_id ) { 574 if ( ! function_exists( 'ayudawp_msps_get_prior_price' ) ) { 575 return null; 576 } 577 578 $prior = ayudawp_msps_get_prior_price( $variation_id, true ); 579 580 return is_numeric( $prior ) ? round( (float) $prior, wc_get_price_decimals() ) : null; 581 } 582 583 /** 584 * Prior price note of Scheduled Sales, Discounts and Omnibus Price History for WooCommerce for the 585 * variation shown. 586 * 587 * That plugin adds its note to the price of a variable product by itself, 588 * for the cheapest variation, unless the price already carries one. Asking 589 * for it here puts the note of the variation this plugin actually shows, 590 * which in the "Up to" mode is the most expensive one, and keeps it to one. 591 * The note comes from that plugin already escaped and following its own 592 * settings (when to show it, where, and its text). 593 * 594 * @param int $variation_id Shown variation. 595 * @param string|float $price Its active price, for display. 596 * @param string|float $regular Its regular price, for display. 597 * @param WC_Product $product Variable product being displayed. 598 * @return string Note HTML, or an empty string. 599 */ 600 private function ayudawp_msps_note( $variation_id, $price, $regular, $product ) { 601 if ( ! function_exists( 'ayudawp_msps_get_prior_price_note' ) || '' === $regular || (float) $regular <= (float) $price ) { 602 return ''; 603 } 604 605 return wp_kses_post( (string) ayudawp_msps_get_prior_price_note( $variation_id, $product->get_id() ) ); 496 606 } 497 607 … … 1073 1183 * These plugins track the lowest price of the last 30 days required by the EU 1074 1184 * Omnibus Directive, which this plugin does not do. Detection is done against 1075 * the active plugins list to avoid guessing class or constant names. 1076 * 1077 * @return string Plugin name, or an empty string when none is active. 1185 * the active plugins list to avoid guessing class or constant names, in the 1186 * order of the list below: Scheduled Sales, Discounts and Omnibus Price History goes first because 1187 * it is the one this plugin works with beyond sharing the price. 1188 * 1189 * @return string Plugin folder, or an empty string when none is active. 1078 1190 */ 1079 1191 private function ayudawp_get_price_history_plugin() { 1080 $known = array(1081 'omnibus' => 'Omnibus — show the lowest price',1082 'wc-price-history' => 'WC Price History',1083 'product-price-history' => 'Product Price History for WooCommerce',1084 'fleekcode-omnibus' => 'FleekCode – Omnibus Price Tracker',1085 );1086 1087 1192 $active = (array) get_option( 'active_plugins', array() ); 1088 1193 … … 1091 1196 } 1092 1197 1093 foreach ( $active as $plugin_file ) {1094 $folder = dirname( $plugin_file ); 1095 1096 if ( i sset( $known[ $folder ]) ) {1097 return $ known[ $folder ];1198 $active_folders = array_map( 'dirname', $active ); 1199 1200 foreach ( array_keys( $this->ayudawp_price_history_plugins() ) as $folder ) { 1201 if ( in_array( $folder, $active_folders, true ) ) { 1202 return $folder; 1098 1203 } 1099 1204 } … … 1103 1208 1104 1209 /** 1210 * Known price history plugins. 1211 * 1212 * @return array Plugin folder => plugin name. 1213 */ 1214 private function ayudawp_price_history_plugins() { 1215 return array( 1216 'multiple-sale-prices-scheduler' => 'Scheduled Sales, Discounts and Omnibus Price History for WooCommerce', 1217 'omnibus' => 'Omnibus — show the lowest price', 1218 'wc-price-history' => 'WC Price History', 1219 'product-price-history' => 'Product Price History for WooCommerce', 1220 'fleekcode-omnibus' => 'FleekCode – Omnibus Price Tracker', 1221 ); 1222 } 1223 1224 /** 1105 1225 * Notice explaining how this plugin coexists with a price history plugin. 1106 1226 */ 1107 1227 private function ayudawp_render_price_history_notice() { 1108 $plugin_name = $this->ayudawp_get_price_history_plugin(); 1109 1110 if ( '' === $plugin_name ) { 1228 $folder = $this->ayudawp_get_price_history_plugin(); 1229 $plugins = $this->ayudawp_price_history_plugins(); 1230 1231 if ( '' === $folder ) { 1111 1232 return; 1112 1233 } … … 1118 1239 /* translators: %s: name of the detected price history plugin. */ 1119 1240 esc_html__( '%s is active on this site. Both plugins work together: this one decides which price replaces the WooCommerce range, and the other one adds the lowest price of the last 30 days required by the EU Omnibus Directive.', 'show-only-lowest-prices-in-woocommerce-variable-products' ), 1120 esc_html( $plugin _name)1241 esc_html( $plugins[ $folder ] ) 1121 1242 ); 1122 1243 ?> 1123 1244 </p> 1245 <?php if ( 'multiple-sale-prices-scheduler' === $folder ) : ?> 1246 <p> 1247 <?php esc_html_e( 'The discount percentage is calculated on that prior price instead of the regular one, as EU rules require. If that plugin is set to cross out the prior price, the price shown here crosses out the prior price too.', 'show-only-lowest-prices-in-woocommerce-variable-products' ); ?> 1248 </p> 1249 <?php endif; ?> 1124 1250 <p> 1125 1251 <?php esc_html_e( 'If the two messages end up in the wrong order, use the ayudawp_lowest_price_html filter to place them exactly where you want.', 'show-only-lowest-prices-in-woocommerce-variable-products' ); ?>
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)