├── languages ├── pmpro-variable-pricing.mo ├── pmpro-variable-pricing-fr_FR.mo ├── pmpro-variable-pricing.pot ├── pmpro-variable-pricing.po └── pmpro-variable-pricing-fr_FR.po ├── readme.txt ├── javascript └── pmpro-variable-pricing.js └── pmpro-variable-pricing.php /languages/pmpro-variable-pricing.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangerstudios/pmpro-variable-pricing/HEAD/languages/pmpro-variable-pricing.mo -------------------------------------------------------------------------------- /languages/pmpro-variable-pricing-fr_FR.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strangerstudios/pmpro-variable-pricing/HEAD/languages/pmpro-variable-pricing-fr_FR.mo -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === Paid Memberships Pro - Variable Pricing Add On === 2 | Contributors: strangerstudios 3 | Tags: paid memberships pro, pmpro, membership, donate, donations, charity, charities 4 | Requires at least: 5.2 5 | Tested up to: 6.8 6 | Stable tag: 1.0 7 | 8 | Allow customers to set their own price when checking out for your membership levels. 9 | 10 | == Description == 11 | This plugin requires Paid Memberships Pro. 12 | 13 | == Installation == 14 | 15 | 1. Upload the `pmpro-variable-pricing` directory to the `/wp-content/plugins/` directory of your site. 16 | 1. Activate the plugin through the 'Plugins' menu in WordPress. 17 | 1. Edit the levels you want to add variable pricing to and set the "Variable Pricing" settings. 18 | 19 | == Frequently Asked Questions == 20 | 21 | = I found a bug in the plugin. = 22 | 23 | Please post it in the issues section of GitHub and we'll fix it as soon as we can. Thanks for helping. https://github.com/strangerstudios/pmpro-variable-pricing/issues 24 | 25 | == Changelog == 26 | = 1.0 - 2025-07-16 = 27 | * ENHANCEMENT: Updated the variable pricing checkout field for compatibility with PMPro v3.1+ styling. #49 (@MaximilianoRicoTabo, @kimcoleman) 28 | * ENHANCEMENT: Moved the variable pricing level settings to their own panel. #48 (@kimcoleman) 29 | * ENHANCEMENT: Added cycle period text to the checkout field and variable pricing text descriptions. #52 (@dparker1005, @kimcoleman) 30 | 31 | = 0.4.6 - 2024-01-04 = 32 | * ENHANCEMENT: Updating `

` tags to `

` tags for better accessibility. #44 (@ipokkel) 33 | * BUG FIX: Fixed PHP warning if an empty level ID is passed to `pmprovp_get_settings()`. #43 (@dparker1005) 34 | * REFACTOR: No longer pulling the checkout level from the `$_REQUEST` variable. #43 (@dparker1005) 35 | * REFACTOR: Now using `get_option()` instead of `pmpro_getOption()`. #42 (@JarrydLong) 36 | 37 | = 0.4.5 - 2023-01-30 = 38 | * ENHANCEMENT: Improved translation logic within the plugin and translated some missing strings. 39 | * ENHANCEMENT: Updated French translation (@paullaffitte). 40 | * BUG FIX: Fixed an issue where PHP sessions were interfering with the REST API. 41 | 42 | = .4.4 - 2020-04-09 = 43 | * BUG FIX: Fixed issue where non variable pricing levels would still be able to adjust the price via query parameters. 44 | 45 | = .4.3 = 46 | * SECURITY: Escape and sanitization of strings. 47 | * ENHANCEMENT: Show inline-warning if criteria is not met for variable pricing. 48 | * ENHANCEMENT: Support right-handed currency symbol positioning. 49 | * BUG FIX: Fixed issue where JavaScript would load on pages that did not have the variable pricing input enabled. 50 | 51 | = .4.2 = 52 | * BUG FIX: Fixed fatal error crash when PMPro is not activated. 53 | * BUG FIX: Fixed issue where the variable price was not being loaded from SESSION for PayPal Express and other offsite gateways. 54 | 55 | = .4.1 = 56 | * ENHANCEMENT: French translation files. (Thanks, Alfonso Sánchez Uzábal) 57 | * ENHANCEMENT: Consistent plugin titles and URLs 58 | * ENHANCEMENT: WordPress Coding Standards 59 | 60 | = .4 = 61 | * BUG FIX: Allow blank variable price input (i.e. use the minimum price) 62 | * BUG FIX/FEATURE: Fixed logic for hiding/showing billing fields if the price is free or not. 63 | * FEATURE: Properly formatted translatable text 64 | * FEATURE: Added translation domain labels 65 | * FEATURE: Added language file load (when applicable) 66 | * FEATURE: Added suggested price setting. 67 | * FEATURE: No longer embedding JS in frontend sources/page. 68 | * FEATURE: Priority of JS register/enqueue operation means you can unhook the Variable Prices JavaScript if needed 69 | 70 | = .3.1 = 71 | * BUG: Now hiding Variable Pricing options on checkout review page. 72 | 73 | = .3 = 74 | * Now storing price in session for offsite gateways like PayPal and 2Checkout. 75 | 76 | = .2 = 77 | * Updated JS logic to hide/show billing to work for PayPal, PayPal Express, and Stripe (with no billing fields) gateway options. 78 | -------------------------------------------------------------------------------- /languages/pmpro-variable-pricing.pot: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Paid Memberships Pro 2 | # This file is distributed under the same license as the Paid Memberships Pro - Variable Pricing Add On plugin. 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: Paid Memberships Pro - Variable Pricing Add On 1.0\n" 6 | "Report-Msgid-Bugs-To: info@paidmembershipspro.com\n" 7 | "Last-Translator: Paid Memberships Pro \n" 8 | "Language-Team: Paid Memberships Pro \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "POT-Creation-Date: 2025-07-16T19:07:44+00:00\n" 13 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 | "X-Generator: WP-CLI 2.12.0\n" 15 | "X-Domain: pmpro-variable-pricing\n" 16 | 17 | #. Plugin Name of the plugin 18 | #: pmpro-variable-pricing.php 19 | #: pmpro-variable-pricing.php:117 20 | msgid "Paid Memberships Pro - Variable Pricing Add On" 21 | msgstr "" 22 | 23 | #. Plugin URI of the plugin 24 | #: pmpro-variable-pricing.php 25 | msgid "https://www.paidmembershipspro.com/add-ons/variable-pricing-add-on/" 26 | msgstr "" 27 | 28 | #. Description of the plugin 29 | #: pmpro-variable-pricing.php 30 | msgid "Allow customers to set their own price when checking out for your membership levels." 31 | msgstr "" 32 | 33 | #. Author of the plugin 34 | #: pmpro-variable-pricing.php 35 | msgid "Paid Memberships Pro" 36 | msgstr "" 37 | 38 | #. Author URI of the plugin 39 | #: pmpro-variable-pricing.php 40 | msgid "https://www.paidmembershipspro.com" 41 | msgstr "" 42 | 43 | #: pmpro-variable-pricing.php:80 44 | msgid "Variable Pricing Settings" 45 | msgstr "" 46 | 47 | #: pmpro-variable-pricing.php:84 48 | msgid "If variable pricing is enabled, users will be able to set their own price at checkout. That price will override any initial payment and billing amount values you set on this level. You can set the minimum, maximum, and suggested price for this level." 49 | msgstr "" 50 | 51 | #: pmpro-variable-pricing.php:88 52 | msgid "Enable" 53 | msgstr "" 54 | 55 | #: pmpro-variable-pricing.php:90 56 | msgid "Enable Variable Pricing" 57 | msgstr "" 58 | 59 | #: pmpro-variable-pricing.php:94 60 | msgid "Min Price" 61 | msgstr "" 62 | 63 | #: pmpro-variable-pricing.php:100 64 | msgid "Max Price" 65 | msgstr "" 66 | 67 | #: pmpro-variable-pricing.php:103 68 | msgid "Leave this blank to allow any maximum amount." 69 | msgstr "" 70 | 71 | #: pmpro-variable-pricing.php:107 72 | msgid "Suggested Price" 73 | msgstr "" 74 | 75 | #: pmpro-variable-pricing.php:110 76 | msgid "You may leave this blank." 77 | msgstr "" 78 | 79 | #: pmpro-variable-pricing.php:117 80 | #: pmpro-variable-pricing.php:196 81 | msgid "Variable Pricing" 82 | msgstr "" 83 | 84 | #. translators: %s: Link to Variable Pricing doc. 85 | #: pmpro-variable-pricing.php:119 86 | #, php-format 87 | msgid "Learn more about %s." 88 | msgstr "" 89 | 90 | #. translators: %1$s - min price, %2$s - max price 91 | #: pmpro-variable-pricing.php:227 92 | #, php-format 93 | msgid "Between %1$s and %2$s." 94 | msgstr "" 95 | 96 | #. translators: %1$s - min price, %2$s - max price, %3$s - billing period 97 | #: pmpro-variable-pricing.php:234 98 | #, php-format 99 | msgid "Between %1$s and %2$s per %3$s." 100 | msgstr "" 101 | 102 | #. translators: %1$s - min price, %2$s - max price, %3$d - cycle number, %4$s - billing period 103 | #: pmpro-variable-pricing.php:242 104 | #, php-format 105 | msgid "Between %1$s and %2$s every %3$d %4$s." 106 | msgstr "" 107 | 108 | #. translators: %s - min price 109 | #: pmpro-variable-pricing.php:253 110 | #, php-format 111 | msgid "Minimum price of %s or higher." 112 | msgstr "" 113 | 114 | #. translators: %1$s - min price, %2$s - billing period 115 | #: pmpro-variable-pricing.php:259 116 | #, php-format 117 | msgid "Minimum price of %1$s per %2$s." 118 | msgstr "" 119 | 120 | #. translators: %1$s - min price, %2$d - cycle number, %3$s - billing period 121 | #: pmpro-variable-pricing.php:266 122 | #, php-format 123 | msgid "Minimum price of %1$s every %2$d %3$s." 124 | msgstr "" 125 | 126 | #. translators: %s - max price 127 | #: pmpro-variable-pricing.php:276 128 | #, php-format 129 | msgid "Maximum price of %s or lower." 130 | msgstr "" 131 | 132 | #. translators: %1$s - max price, %2$s - billing period 133 | #: pmpro-variable-pricing.php:282 134 | #, php-format 135 | msgid "Maximum price of %1$s per %2$s." 136 | msgstr "" 137 | 138 | #. translators: %1$s - max price, %2$d - cycle number, %3$s - billing period 139 | #: pmpro-variable-pricing.php:289 140 | #, php-format 141 | msgid "Maximum price of %1$s every %2$d %3$s." 142 | msgstr "" 143 | 144 | #: pmpro-variable-pricing.php:297 145 | msgid "Any." 146 | msgstr "" 147 | 148 | #. translators: %s - billing period 149 | #: pmpro-variable-pricing.php:301 150 | #, php-format 151 | msgid "Any price per %s." 152 | msgstr "" 153 | 154 | #. translators: %1$d - cycle number, %2$s - billing period 155 | #: pmpro-variable-pricing.php:307 156 | #, php-format 157 | msgid "Any price every %1$d %2$s." 158 | msgstr "" 159 | 160 | #. translators: %s - suggested price 161 | #: pmpro-variable-pricing.php:320 162 | #, php-format 163 | msgid "Suggested Price: %s." 164 | msgstr "" 165 | 166 | #. translators: %1$s - suggested price, %2$s - billing period 167 | #: pmpro-variable-pricing.php:326 168 | #, php-format 169 | msgid "Suggested Price: %1$s per %2$s." 170 | msgstr "" 171 | 172 | #. translators: %1$s - suggested price, %2$d - cycle number, %3$s - billing period 173 | #: pmpro-variable-pricing.php:333 174 | #, php-format 175 | msgid "Suggested Price: %1$s every %2$d %3$s." 176 | msgstr "" 177 | 178 | #: pmpro-variable-pricing.php:381 179 | #, php-format 180 | msgid "Enter a price between %1$s and %2$s." 181 | msgstr "" 182 | 183 | #: pmpro-variable-pricing.php:387 184 | #, php-format 185 | msgid "Enter a minimum price of %s or higher." 186 | msgstr "" 187 | 188 | #: pmpro-variable-pricing.php:392 189 | #, php-format 190 | msgid "Enter a price of %s or lower." 191 | msgstr "" 192 | 193 | #: pmpro-variable-pricing.php:396 194 | msgid "Enter a price for your membership" 195 | msgstr "" 196 | 197 | #: pmpro-variable-pricing.php:407 198 | #, php-format 199 | msgid "Your Price (%s)" 200 | msgstr "" 201 | 202 | #: pmpro-variable-pricing.php:411 203 | msgid "Your Price" 204 | msgstr "" 205 | 206 | #: pmpro-variable-pricing.php:425 207 | msgid "Membership Pricing" 208 | msgstr "" 209 | 210 | #: pmpro-variable-pricing.php:434 211 | msgid "Required Field" 212 | msgstr "" 213 | 214 | #. translators: %s - period. 215 | #: pmpro-variable-pricing.php:443 216 | #, php-format 217 | msgid "per %s" 218 | msgstr "" 219 | 220 | #. translators: %1$d - number, %2$s - period. 221 | #: pmpro-variable-pricing.php:446 222 | #, php-format 223 | msgid "every %1$d %2$s" 224 | msgstr "" 225 | 226 | #: pmpro-variable-pricing.php:513 227 | #, php-format 228 | msgid "The lowest accepted price is %1$s%2$s. Please enter a new amount." 229 | msgstr "" 230 | 231 | #: pmpro-variable-pricing.php:521 232 | #, php-format 233 | msgid "The highest accepted price is %1$s%2$s. Please enter a new amount." 234 | msgstr "" 235 | 236 | #: pmpro-variable-pricing.php:632 237 | msgid "View Documentation" 238 | msgstr "" 239 | 240 | #: pmpro-variable-pricing.php:632 241 | msgid "Docs" 242 | msgstr "" 243 | 244 | #: pmpro-variable-pricing.php:633 245 | msgid "Visit Customer Support Forum" 246 | msgstr "" 247 | 248 | #: pmpro-variable-pricing.php:633 249 | msgid "Support" 250 | msgstr "" 251 | -------------------------------------------------------------------------------- /javascript/pmpro-variable-pricing.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2017. - Stranger Studios, LLC - Thomas Sjolshagen 4 | * ALL RIGHTS RESERVED 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | * 19 | */ 20 | 21 | // some vars for keeping track of whether or not we show billing 22 | var pmpro_gateway_billing; 23 | var pmpro_pricing_billing; 24 | 25 | // this var is used by several pmpro add ons to keep track of whether or not the billing fields are required 26 | if ( pmpro_require_billing == null ) { 27 | var pmpro_require_billing = true; 28 | } 29 | 30 | // keep track of our obect 31 | var PMProVariablePricing; 32 | 33 | // this script will hide show billing fields based on the price set 34 | jQuery( document ).ready( 35 | function() { 36 | "use strict"; 37 | PMProVariablePricing = { 38 | init: function() { 39 | 40 | // setup these global vars 41 | pmpro_gateway_billing = pmprovp.settings.gateway_billing; 42 | pmpro_pricing_billing = pmprovp.settings.pricing_billing; 43 | 44 | // some vars 45 | this.no_billing_gateways = ['paypalstandard', 'paypalexpress', 'twocheckout', 'check']; 46 | this.priceElem = jQuery( '#price' ); 47 | this.addressFields = jQuery( '#pmpro_billing_address_fields' ); 48 | this.paymentInfo = jQuery( '#pmpro_payment_information_fields' ); 49 | this.paymentMethod = jQuery( '#pmpro_payment_method' ); 50 | this.regSubmitSpan = jQuery( '#pmpro_submit_span' ); 51 | this.ppeSubmitSpan = jQuery( '#pmpro_paypalexpress_checkout' ); 52 | this.vp_data = JSON.parse( pmprovp.vp_data ); 53 | 54 | // bind check to price field 55 | this.price_timer = null; 56 | this.priceElem.bind( 57 | 'keyup change', function() { 58 | // use our global var name here, since we're in a closure 59 | PMProVariablePricing.price_timer = setTimeout( PMProVariablePricing.checkForFree, 500 ); 60 | PMProVariablePricing.price_timer = setTimeout( PMProVariablePricing.checkPrice, 500 ); 61 | 62 | } 63 | ); 64 | 65 | // get gateway value and bind check to gateway field 66 | if (typeof this.paymentMethod == 'object') { 67 | this.gateway = jQuery( 'input[name=gateway]:checked' ).val(); 68 | jQuery( 'input[name=gateway]' ).bind( 69 | 'click', function() { 70 | // use our global var name here, since we're in a closure 71 | PMProVariablePricing.price_timer = setTimeout( PMProVariablePricing.checkForFree, 500 ); 72 | PMProVariablePricing.price_timer = setTimeout( PMProVariablePricing.checkPrice, 500 ); 73 | } 74 | ); 75 | } else { 76 | this.gateway = pmprovp.settings.gateway; 77 | } 78 | 79 | // check when page loads too 80 | this.checkForFree(); 81 | }, 82 | checkForFree: function() { 83 | 84 | // get the current price 85 | var price = parseFloat( PMProVariablePricing.priceElem.val() ); 86 | if (price > 0) { 87 | pmpro_pricing_billing = true; 88 | } else { 89 | pmpro_pricing_billing = false; 90 | } 91 | 92 | // if there is a payment method radio, get the current gateway 93 | if (typeof PMProVariablePricing.paymentMethod == 'object') { 94 | PMProVariablePricing.gateway = jQuery( 'input[name=gateway]:checked' ).val(); 95 | 96 | // some gateways require billing fields, others don't 97 | if (PMProVariablePricing.no_billing_gateways.indexOf( PMProVariablePricing.gateway ) > -1) { 98 | pmpro_gateway_billing = false; 99 | } else { 100 | pmpro_gateway_billing = true; 101 | } 102 | } 103 | 104 | // figure out if we should show the billing fields 105 | if (pmpro_gateway_billing && pmpro_pricing_billing) { 106 | PMProVariablePricing.addressFields.show(); 107 | PMProVariablePricing.paymentInfo.show(); 108 | pmpro_require_billing = true; 109 | } else { 110 | PMProVariablePricing.addressFields.hide(); 111 | PMProVariablePricing.paymentInfo.hide(); 112 | PMProVariablePricing.paymentMethod.hide(); 113 | pmpro_require_billing = false; 114 | } 115 | 116 | // toggle the payment method box if available and which type of checkout button shown 117 | if (pmpro_pricing_billing) { 118 | PMProVariablePricing.paymentMethod.show(); 119 | if (PMProVariablePricing.gateway == 'paypalexpress' || PMProVariablePricing.gateway == 'paypalstandard') { 120 | PMProVariablePricing.regSubmitSpan.hide(); 121 | PMProVariablePricing.ppeSubmitSpan.show(); 122 | } else { 123 | PMProVariablePricing.ppeSubmitSpan.hide(); 124 | PMProVariablePricing.regSubmitSpan.show(); 125 | } 126 | } else { 127 | PMProVariablePricing.ppeSubmitSpan.hide(); 128 | PMProVariablePricing.regSubmitSpan.show(); 129 | } 130 | }, 131 | checkPrice: function() { 132 | 133 | // Site-defined pricing variables. 134 | const min_price = PMProVariablePricing.vp_data.min_price; 135 | const max_price = PMProVariablePricing.vp_data.max_price; 136 | 137 | // Price entered on checkout. 138 | const vp_price = PMProVariablePricing.priceElem.val(); 139 | 140 | // Form field elements and values. 141 | const priceInput = document.querySelector( 'input#price' ); 142 | const value = parseFloat( vp_price ); 143 | const minPrice = parseFloat( min_price ); 144 | const maxPrice = parseFloat( max_price ); 145 | const priceDescription = document.querySelector( '#pmprovp-price-description' ); 146 | 147 | // Clear validity and return early if empty 148 | if ( !vp_price ) { 149 | priceInput.setCustomValidity(''); 150 | priceInput.classList.remove('pmpro_form_input-error'); 151 | return; 152 | } 153 | 154 | // Return early if no min or max price is set. 155 | if ( !min_price && !max_price ) { 156 | return; 157 | } 158 | 159 | // Invalid number 160 | if ( isNaN( value ) ) { 161 | priceInput.setCustomValidity(priceDescription.textContent); 162 | priceInput.classList.add('pmpro_form_input-error'); 163 | return; 164 | } 165 | 166 | // Check values against constraints. 167 | let isValid = true; 168 | 169 | if ( min_price && max_price ) { 170 | isValid = value >= minPrice && value <= maxPrice; 171 | } else if ( min_price && !max_price ) { 172 | isValid = value >= minPrice; 173 | } else if ( !min_price && max_price ) { 174 | isValid = value <= maxPrice; 175 | } 176 | 177 | if ( isValid ) { 178 | priceInput.setCustomValidity(''); 179 | priceInput.classList.remove('pmpro_form_input-error'); 180 | } else { 181 | priceInput.setCustomValidity(priceDescription.textContent); 182 | priceInput.classList.add('pmpro_form_input-error'); 183 | } 184 | } 185 | } 186 | 187 | PMProVariablePricing.init(); 188 | } 189 | ); 190 | -------------------------------------------------------------------------------- /languages/pmpro-variable-pricing.po: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Paid Memberships Pro 2 | # This file is distributed under the same license as the Paid Memberships Pro - Variable Pricing Add On plugin. 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: Paid Memberships Pro - Variable Pricing Add On 1.0\n" 6 | "Report-Msgid-Bugs-To: info@paidmembershipspro.com\n" 7 | "Last-Translator: Paid Memberships Pro \n" 8 | "Language-Team: Paid Memberships Pro \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "POT-Creation-Date: 2025-07-16T19:07:44+00:00\n" 13 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 | "X-Generator: WP-CLI 2.12.0\n" 15 | "X-Domain: pmpro-variable-pricing\n" 16 | 17 | #. Plugin Name of the plugin 18 | #: pmpro-variable-pricing.php 19 | #: pmpro-variable-pricing.php:117 20 | msgid "Paid Memberships Pro - Variable Pricing Add On" 21 | msgstr "" 22 | 23 | #. Plugin URI of the plugin 24 | #: pmpro-variable-pricing.php 25 | msgid "https://www.paidmembershipspro.com/add-ons/variable-pricing-add-on/" 26 | msgstr "" 27 | 28 | #. Description of the plugin 29 | #: pmpro-variable-pricing.php 30 | msgid "Allow customers to set their own price when checking out for your membership levels." 31 | msgstr "" 32 | 33 | #. Author of the plugin 34 | #: pmpro-variable-pricing.php 35 | msgid "Paid Memberships Pro" 36 | msgstr "" 37 | 38 | #. Author URI of the plugin 39 | #: pmpro-variable-pricing.php 40 | msgid "https://www.paidmembershipspro.com" 41 | msgstr "" 42 | 43 | #: pmpro-variable-pricing.php:69 44 | #: pmpro-variable-pricing.php:167 45 | #: pmpro-variable-pricing.php:117 46 | #: pmpro-variable-pricing.php:196 47 | msgid "Variable Pricing" 48 | msgstr "" 49 | 50 | #: pmpro-variable-pricing.php:70 51 | msgid "If variable pricing is enabled, users will be able to set their own price at checkout. That price will override any initial payment and billing amount values you set on this level. You can set the minimum, maxium, and suggested price for this level." 52 | msgstr "" 53 | 54 | #: pmpro-variable-pricing.php:75 55 | msgid "Enable:" 56 | msgstr "" 57 | 58 | #: pmpro-variable-pricing.php:77 59 | #: pmpro-variable-pricing.php:90 60 | msgid "Enable Variable Pricing" 61 | msgstr "" 62 | 63 | #: pmpro-variable-pricing.php:81 64 | msgid "Min Price:" 65 | msgstr "" 66 | 67 | #: pmpro-variable-pricing.php:87 68 | msgid "Max Price:" 69 | msgstr "" 70 | 71 | #: pmpro-variable-pricing.php:90 72 | #: pmpro-variable-pricing.php:103 73 | msgid "Leave this blank to allow any maximum amount." 74 | msgstr "" 75 | 76 | #: pmpro-variable-pricing.php:94 77 | msgid "Suggested Price:" 78 | msgstr "" 79 | 80 | #: pmpro-variable-pricing.php:97 81 | #: pmpro-variable-pricing.php:110 82 | msgid "You may leave this blank." 83 | msgstr "" 84 | 85 | #. translators: %1$s - min price, %2$s - max price 86 | #: pmpro-variable-pricing.php:196 87 | #: pmpro-variable-pricing.php:227 88 | #, php-format 89 | msgid "Between %1$s and %2$s." 90 | msgstr "" 91 | 92 | #. translators: %s - min price 93 | #: pmpro-variable-pricing.php:202 94 | #: pmpro-variable-pricing.php:253 95 | #, php-format 96 | msgid "Minimum price of %s or higher." 97 | msgstr "" 98 | 99 | #: pmpro-variable-pricing.php:207 100 | msgid "%s or lower." 101 | msgstr "" 102 | 103 | #: pmpro-variable-pricing.php:211 104 | msgid "Any" 105 | msgstr "" 106 | 107 | #. translators: %s - suggested price 108 | #: pmpro-variable-pricing.php:218 109 | #: pmpro-variable-pricing.php:320 110 | #, php-format 111 | msgid "Suggested Price: %s." 112 | msgstr "" 113 | 114 | #: pmpro-variable-pricing.php:258 115 | #: pmpro-variable-pricing.php:381 116 | #, php-format 117 | msgid "Enter a price between %1$s and %2$s." 118 | msgstr "" 119 | 120 | #: pmpro-variable-pricing.php:264 121 | #: pmpro-variable-pricing.php:387 122 | #, php-format 123 | msgid "Enter a minimum price of %s or higher." 124 | msgstr "" 125 | 126 | #: pmpro-variable-pricing.php:269 127 | #: pmpro-variable-pricing.php:392 128 | #, php-format 129 | msgid "Enter a price of %s or lower." 130 | msgstr "" 131 | 132 | #: pmpro-variable-pricing.php:273 133 | #: pmpro-variable-pricing.php:396 134 | msgid "Enter a price for your membership" 135 | msgstr "" 136 | 137 | #: pmpro-variable-pricing.php:284 138 | msgid "Your price: %s" 139 | msgstr "" 140 | 141 | #: pmpro-variable-pricing.php:288 142 | msgid "Your price:" 143 | msgstr "" 144 | 145 | #: pmpro-variable-pricing.php:359 146 | #: pmpro-variable-pricing.php:360 147 | #: pmpro-variable-pricing.php:513 148 | #, php-format 149 | msgid "The lowest accepted price is %1$s%2$s. Please enter a new amount." 150 | msgstr "" 151 | 152 | #: pmpro-variable-pricing.php:367 153 | #: pmpro-variable-pricing.php:368 154 | #: pmpro-variable-pricing.php:521 155 | #, php-format 156 | msgid "The highest accepted price is %1$s%2$s. Please enter a new amount." 157 | msgstr "" 158 | 159 | #: pmpro-variable-pricing.php:478 160 | #: pmpro-variable-pricing.php:479 161 | #: pmpro-variable-pricing.php:632 162 | msgid "View Documentation" 163 | msgstr "" 164 | 165 | #: pmpro-variable-pricing.php:478 166 | #: pmpro-variable-pricing.php:479 167 | #: pmpro-variable-pricing.php:632 168 | msgid "Docs" 169 | msgstr "" 170 | 171 | #: pmpro-variable-pricing.php:479 172 | #: pmpro-variable-pricing.php:480 173 | #: pmpro-variable-pricing.php:633 174 | msgid "Visit Customer Support Forum" 175 | msgstr "" 176 | 177 | #: pmpro-variable-pricing.php:479 178 | #: pmpro-variable-pricing.php:480 179 | #: pmpro-variable-pricing.php:633 180 | msgid "Support" 181 | msgstr "" 182 | 183 | #: pmpro-variable-pricing.php:80 184 | msgid "Variable Pricing Settings" 185 | msgstr "" 186 | 187 | #: pmpro-variable-pricing.php:84 188 | msgid "If variable pricing is enabled, users will be able to set their own price at checkout. That price will override any initial payment and billing amount values you set on this level. You can set the minimum, maximum, and suggested price for this level." 189 | msgstr "" 190 | 191 | #: pmpro-variable-pricing.php:88 192 | msgid "Enable" 193 | msgstr "" 194 | 195 | #: pmpro-variable-pricing.php:94 196 | msgid "Min Price" 197 | msgstr "" 198 | 199 | #: pmpro-variable-pricing.php:100 200 | msgid "Max Price" 201 | msgstr "" 202 | 203 | #: pmpro-variable-pricing.php:107 204 | msgid "Suggested Price" 205 | msgstr "" 206 | 207 | #. translators: %s: Link to Variable Pricing doc. 208 | #: pmpro-variable-pricing.php:119 209 | #, php-format 210 | msgid "Learn more about %s." 211 | msgstr "" 212 | 213 | #. translators: %1$s - min price, %2$s - max price, %3$s - billing period 214 | #: pmpro-variable-pricing.php:234 215 | #, php-format 216 | msgid "Between %1$s and %2$s per %3$s." 217 | msgstr "" 218 | 219 | #. translators: %1$s - min price, %2$s - max price, %3$d - cycle number, %4$s - billing period 220 | #: pmpro-variable-pricing.php:242 221 | #, php-format 222 | msgid "Between %1$s and %2$s every %3$d %4$s." 223 | msgstr "" 224 | 225 | #. translators: %1$s - min price, %2$s - billing period 226 | #: pmpro-variable-pricing.php:259 227 | #, php-format 228 | msgid "Minimum price of %1$s per %2$s." 229 | msgstr "" 230 | 231 | #. translators: %1$s - min price, %2$d - cycle number, %3$s - billing period 232 | #: pmpro-variable-pricing.php:266 233 | #, php-format 234 | msgid "Minimum price of %1$s every %2$d %3$s." 235 | msgstr "" 236 | 237 | #. translators: %s - max price 238 | #: pmpro-variable-pricing.php:276 239 | #, php-format 240 | msgid "Maximum price of %s or lower." 241 | msgstr "" 242 | 243 | #. translators: %1$s - max price, %2$s - billing period 244 | #: pmpro-variable-pricing.php:282 245 | #, php-format 246 | msgid "Maximum price of %1$s per %2$s." 247 | msgstr "" 248 | 249 | #. translators: %1$s - max price, %2$d - cycle number, %3$s - billing period 250 | #: pmpro-variable-pricing.php:289 251 | #, php-format 252 | msgid "Maximum price of %1$s every %2$d %3$s." 253 | msgstr "" 254 | 255 | #: pmpro-variable-pricing.php:297 256 | msgid "Any." 257 | msgstr "" 258 | 259 | #. translators: %s - billing period 260 | #: pmpro-variable-pricing.php:301 261 | #, php-format 262 | msgid "Any price per %s." 263 | msgstr "" 264 | 265 | #. translators: %1$d - cycle number, %2$s - billing period 266 | #: pmpro-variable-pricing.php:307 267 | #, php-format 268 | msgid "Any price every %1$d %2$s." 269 | msgstr "" 270 | 271 | #. translators: %1$s - suggested price, %2$s - billing period 272 | #: pmpro-variable-pricing.php:326 273 | #, php-format 274 | msgid "Suggested Price: %1$s per %2$s." 275 | msgstr "" 276 | 277 | #. translators: %1$s - suggested price, %2$d - cycle number, %3$s - billing period 278 | #: pmpro-variable-pricing.php:333 279 | #, php-format 280 | msgid "Suggested Price: %1$s every %2$d %3$s." 281 | msgstr "" 282 | 283 | #: pmpro-variable-pricing.php:407 284 | #, php-format 285 | msgid "Your Price (%s)" 286 | msgstr "" 287 | 288 | #: pmpro-variable-pricing.php:411 289 | msgid "Your Price" 290 | msgstr "" 291 | 292 | #: pmpro-variable-pricing.php:425 293 | msgid "Membership Pricing" 294 | msgstr "" 295 | 296 | #: pmpro-variable-pricing.php:434 297 | msgid "Required Field" 298 | msgstr "" 299 | 300 | #. translators: %s - period. 301 | #: pmpro-variable-pricing.php:443 302 | #, php-format 303 | msgid "per %s" 304 | msgstr "" 305 | 306 | #. translators: %1$d - number, %2$s - period. 307 | #: pmpro-variable-pricing.php:446 308 | #, php-format 309 | msgid "every %1$d %2$s" 310 | msgstr "" 311 | -------------------------------------------------------------------------------- /languages/pmpro-variable-pricing-fr_FR.po: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2025 Paid Memberships Pro 2 | # This file is distributed under the same license as the Paid Memberships Pro - Variable Pricing Add On plugin. 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: Paid Memberships Pro - Variable Pricing Add On 1.0\n" 6 | "Report-Msgid-Bugs-To: info@paidmembershipspro.com\n" 7 | "Last-Translator: Paid Memberships Pro \n" 8 | "Language-Team: Paid Memberships Pro \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "POT-Creation-Date: 2025-07-16T19:07:44+00:00\n" 13 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 14 | "X-Generator: WP-CLI 2.12.0\n" 15 | "X-Domain: pmpro-variable-pricing\n" 16 | 17 | #. Plugin Name of the plugin 18 | #: pmpro-variable-pricing.php 19 | #: pmpro-variable-pricing.php:117 20 | msgid "Paid Memberships Pro - Variable Pricing Add On" 21 | msgstr "Paid Memberships Pro - Add-On pour Prix Variables" 22 | 23 | #. Plugin URI of the plugin 24 | #: pmpro-variable-pricing.php 25 | msgid "https://www.paidmembershipspro.com/add-ons/variable-pricing-add-on/" 26 | msgstr "" 27 | 28 | #. Description of the plugin 29 | #: pmpro-variable-pricing.php 30 | msgid "Allow customers to set their own price when checking out for your membership levels." 31 | msgstr "Autoriser les clients à choisir leur propre prix lors du choix de niveau d'adhésion." 32 | 33 | #. Author of the plugin 34 | #: pmpro-variable-pricing.php 35 | msgid "Paid Memberships Pro" 36 | msgstr "" 37 | 38 | #. Author URI of the plugin 39 | #: pmpro-variable-pricing.php 40 | msgid "https://www.paidmembershipspro.com" 41 | msgstr "" 42 | 43 | #: pmpro-variable-pricing.php:66 44 | #: pmpro-variable-pricing.php:164 45 | #: pmpro-variable-pricing.php:69 46 | #: pmpro-variable-pricing.php:167 47 | #: pmpro-variable-pricing.php:117 48 | #: pmpro-variable-pricing.php:196 49 | msgid "Variable Pricing" 50 | msgstr "Tarification variable" 51 | 52 | #: pmpro-variable-pricing.php:67 53 | #: pmpro-variable-pricing.php:70 54 | msgid "If variable pricing is enabled, users will be able to set their own price at checkout. That price will override any initial payment and billing amount values you set on this level. You can set the minimum, maxium, and suggested price for this level." 55 | msgstr "Si la tarification variable est activée, les utilisateurs pourront définir leur propre prix à la caisse. Ce prix remplace toutes les valeurs de paiement initial et de montant de facturation que vous avez définies à ce niveau. Vous pouvez définir le minimum, le maximum et le prix suggéré pour ce niveau." 56 | 57 | #: pmpro-variable-pricing.php:72 58 | #: pmpro-variable-pricing.php:75 59 | msgid "Enable:" 60 | msgstr "Activer :" 61 | 62 | #: pmpro-variable-pricing.php:74 63 | #: pmpro-variable-pricing.php:77 64 | #: pmpro-variable-pricing.php:90 65 | msgid "Enable Variable Pricing" 66 | msgstr "Activer la tarification variable" 67 | 68 | #: pmpro-variable-pricing.php:78 69 | #: pmpro-variable-pricing.php:81 70 | msgid "Min Price:" 71 | msgstr "Prix minimal :" 72 | 73 | #: pmpro-variable-pricing.php:84 74 | #: pmpro-variable-pricing.php:87 75 | msgid "Max Price:" 76 | msgstr "Prix maximal :" 77 | 78 | #: pmpro-variable-pricing.php:87 79 | #: pmpro-variable-pricing.php:90 80 | #: pmpro-variable-pricing.php:103 81 | msgid "Leave this blank to allow any maximum amount." 82 | msgstr "Laissez ce champ vide pour ne pas avoir de montant maximal." 83 | 84 | #: pmpro-variable-pricing.php:91 85 | #: pmpro-variable-pricing.php:94 86 | msgid "Suggested Price:" 87 | msgstr "Prix suggéré :" 88 | 89 | #: pmpro-variable-pricing.php:94 90 | #: pmpro-variable-pricing.php:97 91 | #: pmpro-variable-pricing.php:110 92 | msgid "You may leave this blank." 93 | msgstr "Vous pouvez laisser ce champ vide." 94 | 95 | #. translators: %1$s - min price, %2$s - max price 96 | #: pmpro-variable-pricing.php:193 97 | #: pmpro-variable-pricing.php:196 98 | #: pmpro-variable-pricing.php:227 99 | #, php-format 100 | msgid "Between %1$s and %2$s." 101 | msgstr "Entre %1$s et %2$s." 102 | 103 | #. translators: %s - min price 104 | #: pmpro-variable-pricing.php:199 105 | #: pmpro-variable-pricing.php:202 106 | #: pmpro-variable-pricing.php:253 107 | #, php-format 108 | msgid "Minimum price of %s or higher." 109 | msgstr "Prix minimum de %s ou plus." 110 | 111 | #: pmpro-variable-pricing.php:204 112 | #: pmpro-variable-pricing.php:207 113 | msgid "%s or lower." 114 | msgstr "%s ou moins." 115 | 116 | #: pmpro-variable-pricing.php:208 117 | #: pmpro-variable-pricing.php:211 118 | msgid "Any" 119 | msgstr "Peu importe" 120 | 121 | #. translators: %s - suggested price 122 | #: pmpro-variable-pricing.php:215 123 | #: pmpro-variable-pricing.php:218 124 | #: pmpro-variable-pricing.php:320 125 | #, php-format 126 | msgid "Suggested Price: %s." 127 | msgstr "Prix suggéré: %s." 128 | 129 | #: pmpro-variable-pricing.php:255 130 | #: pmpro-variable-pricing.php:258 131 | #: pmpro-variable-pricing.php:381 132 | #, php-format 133 | msgid "Enter a price between %1$s and %2$s." 134 | msgstr "Entrez un prix entre %1$s et %2$s." 135 | 136 | #: pmpro-variable-pricing.php:261 137 | #: pmpro-variable-pricing.php:264 138 | #: pmpro-variable-pricing.php:387 139 | #, php-format 140 | msgid "Enter a minimum price of %s or higher." 141 | msgstr "Entrez un prix minimum de %s ou plus." 142 | 143 | #: pmpro-variable-pricing.php:266 144 | #: pmpro-variable-pricing.php:269 145 | #: pmpro-variable-pricing.php:392 146 | #, php-format 147 | msgid "Enter a price of %s or lower." 148 | msgstr "Entrez un prix de %s%s ou plus." 149 | 150 | #: pmpro-variable-pricing.php:270 151 | #: pmpro-variable-pricing.php:273 152 | #: pmpro-variable-pricing.php:396 153 | msgid "Enter a price for your membership" 154 | msgstr "Entrez un prix pour votre adhésion" 155 | 156 | #: pmpro-variable-pricing.php:281 157 | #: pmpro-variable-pricing.php:284 158 | msgid "Your price: %s" 159 | msgstr "Votre prix : %s" 160 | 161 | #: pmpro-variable-pricing.php:285 162 | #: pmpro-variable-pricing.php:288 163 | msgid "Your price:" 164 | msgstr "Votre prix :" 165 | 166 | #: pmpro-variable-pricing.php:364 167 | #: pmpro-variable-pricing.php:367 168 | #: pmpro-variable-pricing.php:368 169 | #: pmpro-variable-pricing.php:521 170 | #, php-format 171 | msgid "The highest accepted price is %1$s%2$s. Please enter a new amount." 172 | msgstr "Le prix le plus élevé accepté est %1$s%2$s. Veuillez entrer un nouveau montant." 173 | 174 | #~ msgid "Error: You tried to set the price on a level that doesn't have variable pricing. Please try again." 175 | #~ msgstr "Erreur: Vous avez essayé de définir le prix à un niveau qui n'a pas de prix variable. Veuillez réessayer." 176 | 177 | #: pmpro-variable-pricing.php:359 178 | #: pmpro-variable-pricing.php:479 179 | #: pmpro-variable-pricing.php:360 180 | #: pmpro-variable-pricing.php:513 181 | #, php-format 182 | #~ msgid "The lowest accepted price is %1$s%2$s. Please enter a new amount." 183 | #~ msgstr "Le prix accepté le plus bas est %1$s%2$s. Veuillez entrer un nouveau montant." 184 | 185 | #: pmpro-variable-pricing.php:478 186 | #: pmpro-variable-pricing.php:479 187 | #: pmpro-variable-pricing.php:632 188 | #~ msgid "View Documentation" 189 | #~ msgstr "Afficher la documentation" 190 | 191 | #: pmpro-variable-pricing.php:478 192 | #: pmpro-variable-pricing.php:479 193 | #: pmpro-variable-pricing.php:632 194 | #~ msgid "Docs" 195 | #~ msgstr "Documentation" 196 | 197 | #: pmpro-variable-pricing.php:479 198 | #: pmpro-variable-pricing.php:480 199 | #: pmpro-variable-pricing.php:633 200 | #~ msgid "Visit Customer Support Forum" 201 | #~ msgstr "Visitez le forum de support client" 202 | 203 | #: pmpro-variable-pricing.php:480 204 | #: pmpro-variable-pricing.php:633 205 | #~ msgid "Support" 206 | #~ msgstr "Support" 207 | 208 | #: pmpro-variable-pricing.php:80 209 | msgid "Variable Pricing Settings" 210 | msgstr "" 211 | 212 | #: pmpro-variable-pricing.php:84 213 | msgid "If variable pricing is enabled, users will be able to set their own price at checkout. That price will override any initial payment and billing amount values you set on this level. You can set the minimum, maximum, and suggested price for this level." 214 | msgstr "" 215 | 216 | #: pmpro-variable-pricing.php:88 217 | msgid "Enable" 218 | msgstr "" 219 | 220 | #: pmpro-variable-pricing.php:94 221 | msgid "Min Price" 222 | msgstr "" 223 | 224 | #: pmpro-variable-pricing.php:100 225 | msgid "Max Price" 226 | msgstr "" 227 | 228 | #: pmpro-variable-pricing.php:107 229 | msgid "Suggested Price" 230 | msgstr "" 231 | 232 | #. translators: %s: Link to Variable Pricing doc. 233 | #: pmpro-variable-pricing.php:119 234 | #, php-format 235 | msgid "Learn more about %s." 236 | msgstr "" 237 | 238 | #. translators: %1$s - min price, %2$s - max price, %3$s - billing period 239 | #: pmpro-variable-pricing.php:234 240 | #, php-format 241 | msgid "Between %1$s and %2$s per %3$s." 242 | msgstr "" 243 | 244 | #. translators: %1$s - min price, %2$s - max price, %3$d - cycle number, %4$s - billing period 245 | #: pmpro-variable-pricing.php:242 246 | #, php-format 247 | msgid "Between %1$s and %2$s every %3$d %4$s." 248 | msgstr "" 249 | 250 | #. translators: %1$s - min price, %2$s - billing period 251 | #: pmpro-variable-pricing.php:259 252 | #, php-format 253 | msgid "Minimum price of %1$s per %2$s." 254 | msgstr "" 255 | 256 | #. translators: %1$s - min price, %2$d - cycle number, %3$s - billing period 257 | #: pmpro-variable-pricing.php:266 258 | #, php-format 259 | msgid "Minimum price of %1$s every %2$d %3$s." 260 | msgstr "" 261 | 262 | #. translators: %s - max price 263 | #: pmpro-variable-pricing.php:276 264 | #, php-format 265 | msgid "Maximum price of %s or lower." 266 | msgstr "" 267 | 268 | #. translators: %1$s - max price, %2$s - billing period 269 | #: pmpro-variable-pricing.php:282 270 | #, php-format 271 | msgid "Maximum price of %1$s per %2$s." 272 | msgstr "" 273 | 274 | #. translators: %1$s - max price, %2$d - cycle number, %3$s - billing period 275 | #: pmpro-variable-pricing.php:289 276 | #, php-format 277 | msgid "Maximum price of %1$s every %2$d %3$s." 278 | msgstr "" 279 | 280 | #: pmpro-variable-pricing.php:297 281 | msgid "Any." 282 | msgstr "" 283 | 284 | #. translators: %s - billing period 285 | #: pmpro-variable-pricing.php:301 286 | #, php-format 287 | msgid "Any price per %s." 288 | msgstr "" 289 | 290 | #. translators: %1$d - cycle number, %2$s - billing period 291 | #: pmpro-variable-pricing.php:307 292 | #, php-format 293 | msgid "Any price every %1$d %2$s." 294 | msgstr "" 295 | 296 | #. translators: %1$s - suggested price, %2$s - billing period 297 | #: pmpro-variable-pricing.php:326 298 | #, php-format 299 | msgid "Suggested Price: %1$s per %2$s." 300 | msgstr "" 301 | 302 | #. translators: %1$s - suggested price, %2$d - cycle number, %3$s - billing period 303 | #: pmpro-variable-pricing.php:333 304 | #, php-format 305 | msgid "Suggested Price: %1$s every %2$d %3$s." 306 | msgstr "" 307 | 308 | #: pmpro-variable-pricing.php:407 309 | #, php-format 310 | msgid "Your Price (%s)" 311 | msgstr "" 312 | 313 | #: pmpro-variable-pricing.php:411 314 | msgid "Your Price" 315 | msgstr "" 316 | 317 | #: pmpro-variable-pricing.php:425 318 | msgid "Membership Pricing" 319 | msgstr "" 320 | 321 | #: pmpro-variable-pricing.php:434 322 | msgid "Required Field" 323 | msgstr "" 324 | 325 | #. translators: %s - period. 326 | #: pmpro-variable-pricing.php:443 327 | #, php-format 328 | msgid "per %s" 329 | msgstr "" 330 | 331 | #. translators: %1$d - number, %2$s - period. 332 | #: pmpro-variable-pricing.php:446 333 | #, php-format 334 | msgid "every %1$d %2$s" 335 | msgstr "" 336 | -------------------------------------------------------------------------------- /pmpro-variable-pricing.php: -------------------------------------------------------------------------------- 1 | 0, 39 | 'min_price' => '', 40 | 'max_price' => '', 41 | 'suggested_price' => '', 42 | ); 43 | 44 | $existing_settings = empty( $level_id ) ? array() : get_option( "pmprovp_{$level_id}", array() ); 45 | 46 | return array_merge( $defaults, $existing_settings ); 47 | } 48 | 49 | /* 50 | Min Price and Max Price Fields on the edit levels page 51 | */ 52 | // fields on edit page 53 | function pmprovp_pmpro_membership_level_after_other_settings() { 54 | global $pmpro_currency_symbol; 55 | $level_id = intval( $_REQUEST['edit'] ); 56 | if ( $level_id > 0 ) { 57 | $vpfields = pmprovp_get_settings( $level_id ); 58 | $variable_pricing = $vpfields['variable_pricing']; 59 | $min_price = $vpfields['min_price']; 60 | $max_price = $vpfields['max_price']; 61 | $suggested_price = $vpfields['suggested_price']; 62 | } else { 63 | $variable_pricing = 0; 64 | $min_price = ''; 65 | $max_price = ''; 66 | $suggested_price = ''; 67 | } 68 | if ( ! empty( $variable_pricing ) ) { 69 | $section_visibility = 'visible'; 70 | $section_activated = 'true'; 71 | } else { 72 | $section_visibility = 'hidden'; 73 | $section_activated = 'false'; 74 | } 75 | ?> 76 |
77 |
78 | 82 |
83 |
> 84 |

85 | 86 | 87 | 88 | 89 | 92 | 93 | 94 | 95 | 98 | 99 | 100 | 101 | 105 | 106 | 107 | 108 | 112 | 113 | 114 |
90 | /> 91 |
96 | 97 |
102 | 103 |

104 |
109 | 110 |

111 |
115 |

116 | ' . esc_html__( 'Variable Pricing', 'pmpro-variable-pricing' ) . ''; 118 | // translators: %s: Link to Variable Pricing doc. 119 | printf( esc_html__('Learn more about %s.', 'pmpro-variable-pricing' ), $variable_pricing_link ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 120 | ?> 121 |

122 |
123 |
124 | 143 | $variable_pricing, 157 | 'min_price' => $min_price, 158 | 'max_price' => $max_price, 159 | 'suggested_price' => $suggested_price, 160 | ) 161 | ); 162 | } 163 | add_action( 'pmpro_save_membership_level', 'pmprovp_pmpro_save_membership_level' ); 164 | 165 | /* 166 | Show form at checkout. 167 | */ 168 | // override level cost text on checkout page 169 | function pmprovp_pmpro_level_cost_text( $text, $level ) { 170 | global $pmpro_pages, $pmpro_review; 171 | 172 | // Bail if we are not on the checkout page. 173 | if ( is_page( $pmpro_pages['checkout'] ) && ! did_action( 'pmpro_after_checkout' ) ) { 174 | // Bail if we are in the review step. 175 | if ( $pmpro_review ) { 176 | return $text; 177 | } 178 | 179 | $vpfields = pmprovp_get_settings( $level->id ); 180 | if ( ! empty( $vpfields ) && ! empty( $vpfields['variable_pricing'] ) ) { 181 | $text = ''; 182 | } 183 | } 184 | 185 | return $text; 186 | } 187 | add_filter( 'pmpro_level_cost_text', 'pmprovp_pmpro_level_cost_text', 10, 2 ); 188 | 189 | 190 | /** 191 | * Display Variable Price details column on Membership Levels Settings Page 192 | * 193 | */ 194 | function pmprovp_pmpro_membership_levels_table_extra_cols_header( $level ) { 195 | ?> 196 | 197 | 206 | 207 | id ); 210 | 211 | // No variable pricing? Show "--" and return. 212 | if ( empty( $vpfields ) || empty( $vpfields['variable_pricing'] ) ) { 213 | echo '--'; 214 | return; 215 | } 216 | 217 | // Get the variable pricing data from the level. 218 | $min_price = $vpfields['min_price']; 219 | $max_price = $vpfields['max_price']; 220 | $suggested_price = $vpfields['suggested_price']; 221 | 222 | // Setup price text description based on price ranges. 223 | if ( ! empty( $max_price ) && ! empty( $min_price ) ) { 224 | if ( empty( $level->billing_amount ) || $level->billing_amount <= 0 ) { 225 | $price_text_description = sprintf( 226 | // translators: %1$s - min price, %2$s - max price 227 | __( 'Between %1$s and %2$s.', 'pmpro-variable-pricing' ), 228 | esc_html( pmpro_formatPrice( $vpfields['min_price'] ) ), 229 | esc_html( pmpro_formatPrice( $vpfields['max_price'] ) ) 230 | ); 231 | } elseif ( $level->cycle_number == 1 ) { 232 | $price_text_description = sprintf( 233 | // translators: %1$s - min price, %2$s - max price, %3$s - billing period 234 | __( 'Between %1$s and %2$s per %3$s.', 'pmpro-variable-pricing' ), 235 | esc_html( pmpro_formatPrice( $vpfields['min_price'] ) ), 236 | esc_html( pmpro_formatPrice( $vpfields['max_price'] ) ), 237 | esc_html( pmpro_translate_billing_period( $level->cycle_period, $level->cycle_number ) ) 238 | ); 239 | } else { 240 | $price_text_description = sprintf( 241 | // translators: %1$s - min price, %2$s - max price, %3$d - cycle number, %4$s - billing period 242 | __( 'Between %1$s and %2$s every %3$d %4$s.', 'pmpro-variable-pricing' ), 243 | esc_html( pmpro_formatPrice( $vpfields['min_price'] ) ), 244 | esc_html( pmpro_formatPrice( $vpfields['max_price'] ) ), 245 | esc_html( $level->cycle_number ), 246 | esc_html( pmpro_translate_billing_period( $level->cycle_period, $level->cycle_number ) ) 247 | ); 248 | } 249 | } elseif( ! empty( $min_price ) && empty( $max_price ) ) { 250 | if ( empty( $level->billing_amount ) || $level->billing_amount <= 0 ) { 251 | $price_text_description = sprintf( 252 | // translators: %s - min price 253 | __( 'Minimum price of %s or higher.', 'pmpro-variable-pricing' ), 254 | esc_html( pmpro_formatPrice( $vpfields['min_price'] ) ) 255 | ); 256 | } elseif ( $level->cycle_number == 1 ) { 257 | $price_text_description = sprintf( 258 | // translators: %1$s - min price, %2$s - billing period 259 | __( 'Minimum price of %1$s per %2$s.', 'pmpro-variable-pricing' ), 260 | esc_html( pmpro_formatPrice( $vpfields['min_price'] ) ), 261 | esc_html( pmpro_translate_billing_period( $level->cycle_period, $level->cycle_number ) ) 262 | ); 263 | } else { 264 | $price_text_description = sprintf( 265 | // translators: %1$s - min price, %2$d - cycle number, %3$s - billing period 266 | __( 'Minimum price of %1$s every %2$d %3$s.', 'pmpro-variable-pricing' ), 267 | esc_html( pmpro_formatPrice( $vpfields['min_price'] ) ), 268 | esc_html( $level->cycle_number ), 269 | esc_html( pmpro_translate_billing_period( $level->cycle_period, $level->cycle_number ) ) 270 | ); 271 | } 272 | } elseif( ! empty( $max_price ) && empty( $min_price ) ) { 273 | if ( empty( $level->billing_amount ) || $level->billing_amount <= 0 ) { 274 | $price_text_description = sprintf( 275 | // translators: %s - max price 276 | __( 'Maximum price of %s or lower.', 'pmpro-variable-pricing' ), 277 | esc_html( pmpro_formatPrice( $vpfields['max_price'] ) ) 278 | ); 279 | } elseif ( $level->cycle_number == 1 ) { 280 | $price_text_description = sprintf( 281 | // translators: %1$s - max price, %2$s - billing period 282 | __( 'Maximum price of %1$s per %2$s.', 'pmpro-variable-pricing' ), 283 | esc_html( pmpro_formatPrice( $vpfields['max_price'] ) ), 284 | esc_html( pmpro_translate_billing_period( $level->cycle_period, $level->cycle_number ) ) 285 | ); 286 | } else { 287 | $price_text_description = sprintf( 288 | // translators: %1$s - max price, %2$d - cycle number, %3$s - billing period 289 | __( 'Maximum price of %1$s every %2$d %3$s.', 'pmpro-variable-pricing' ), 290 | esc_html( pmpro_formatPrice( $vpfields['max_price'] ) ), 291 | esc_html( $level->cycle_number ), 292 | esc_html( pmpro_translate_billing_period( $level->cycle_period, $level->cycle_number ) ) 293 | ); 294 | } 295 | } else { 296 | if ( empty( $level->billing_amount ) || $level->billing_amount <= 0 ) { 297 | $price_text_description = __( 'Any.', 'pmpro-variable-pricing' ); 298 | } elseif ( $level->cycle_number == 1 ) { 299 | $price_text_description = sprintf( 300 | // translators: %s - billing period 301 | __( 'Any price per %s.', 'pmpro-variable-pricing' ), 302 | esc_html( pmpro_translate_billing_period( $level->cycle_period, $level->cycle_number ) ) 303 | ); 304 | } else { 305 | $price_text_description = sprintf( 306 | // translators: %1$d - cycle number, %2$s - billing period 307 | __( 'Any price every %1$d %2$s.', 'pmpro-variable-pricing' ), 308 | esc_html( $level->cycle_number ), 309 | esc_html( pmpro_translate_billing_period( $level->cycle_period, $level->cycle_number ) ) 310 | ); 311 | } 312 | } 313 | 314 | // Show suggested price if specified. 315 | if ( ! empty( $suggested_price ) ) { 316 | $price_text_description .= '
'; 317 | if ( empty( $level->billing_amount) || $level->billing_amount <= 0 ) { 318 | $price_text_description .= sprintf( 319 | // translators: %s - suggested price 320 | __( 'Suggested Price: %s.', 'pmpro-variable-pricing' ), 321 | esc_html( pmpro_formatPrice( $vpfields['suggested_price'] ) ) 322 | ); 323 | } elseif ( $level->cycle_number == 1 ) { 324 | $price_text_description .= sprintf( 325 | // translators: %1$s - suggested price, %2$s - billing period 326 | __( 'Suggested Price: %1$s per %2$s.', 'pmpro-variable-pricing' ), 327 | esc_html( pmpro_formatPrice( $vpfields['suggested_price'] ) ), 328 | esc_html( pmpro_translate_billing_period( $level->cycle_period, $level->cycle_number ) ) 329 | ); 330 | } else { 331 | $price_text_description .= sprintf( 332 | // translators: %1$s - suggested price, %2$d - cycle number, %3$s - billing period 333 | __( 'Suggested Price: %1$s every %2$d %3$s.', 'pmpro-variable-pricing' ), 334 | esc_html( pmpro_formatPrice( $vpfields['suggested_price'] ) ), 335 | esc_html( $level->cycle_number ), 336 | esc_html( pmpro_translate_billing_period( $level->cycle_period, $level->cycle_number ) ) 337 | ); 338 | } 339 | } 340 | 341 | // Display the price text and suggested price in the row. 342 | echo esc_html( $price_text_description ); 343 | ?> 344 | 345 | id ); 360 | 361 | // no variable pricing? just return 362 | if ( empty( $vpfields ) || empty( $vpfields['variable_pricing'] ) ) { 363 | return; 364 | } 365 | 366 | // okay, now we're showing the form 367 | $min_price = $vpfields['min_price']; 368 | $max_price = $vpfields['max_price']; 369 | $suggested_price = $vpfields['suggested_price']; 370 | 371 | 372 | if ( isset( $_REQUEST['price'] ) ) { 373 | $price = preg_replace( '[^0-9\.]', '', floatval( $_REQUEST['price'] ) ); 374 | } else { 375 | $price = $suggested_price; 376 | } 377 | 378 | // setup price text description based on price ranges 379 | if ( ! empty( $max_price ) && ! empty( $min_price ) ) { 380 | $price_text_description = sprintf( 381 | __( 'Enter a price between %1$s and %2$s.', 'pmpro-variable-pricing' ), 382 | esc_html( pmpro_formatPrice( $vpfields['min_price'] ) ), 383 | esc_html( pmpro_formatPrice( $vpfields['max_price'] ) ) 384 | ); 385 | } elseif( ! empty( $min_price ) && empty( $max_price ) ) { 386 | $price_text_description = sprintf( 387 | __( 'Enter a minimum price of %s or higher.', 'pmpro-variable-pricing' ), 388 | esc_html( pmpro_formatPrice( $vpfields['min_price'] ) ) 389 | ); 390 | } elseif( ! empty( $max_price ) && empty( $min_price ) ) { 391 | $price_text_description = sprintf( 392 | __( 'Enter a price of %s or lower.', 'pmpro-variable-pricing' ), 393 | esc_html( pmpro_formatPrice( $vpfields['max_price'] ) ) 394 | ); 395 | } else { 396 | $price_text_description = __( 'Enter a price for your membership', 'pmpro-variable-pricing' ); 397 | } 398 | 399 | /** 400 | * @filter pmpropvp_checkout_price_description - Filter to modify the variable price description text 401 | * @param string $price_text_description 402 | */ 403 | $price_text_description = apply_filters( 'pmpropvp_checkout_price_description', $price_text_description ); 404 | 405 | if ( empty( $pmpro_currencies[$pmpro_currency]['position'] ) || $pmpro_currencies[$pmpro_currency]['position'] == 'left' ) { 406 | $price_text = sprintf( 407 | __( 'Your Price (%s)', 'pmpro-variable-pricing' ), 408 | esc_html( $pmpro_currency_symbol ) 409 | ); 410 | } else { 411 | $price_text = __( 'Your Price', 'pmpro-variable-pricing' ); 412 | } 413 | 414 | /** 415 | * @filter pmprovp_checkout_price_input_label - Filter to modify the label for the Variable Price input box on the checkout page 416 | * @param string $price_text 417 | */ 418 | $price_text = apply_filters( 'pmprovp_checkout_price_input_label', $price_text ); 419 | 420 | ?> 421 |
422 |
423 |
424 | 425 |

426 |
427 |
428 |
429 | 430 |
431 |
432 | 436 |
437 | 438 | billing_amount ) && $pmpro_level->billing_amount > 0 ) { 441 | if ( 1 == $pmpro_level->cycle_number ) { 442 | // translators: %s - period. 443 | echo esc_html( sprintf( __( 'per %s', 'pmpro-variable-pricing' ), pmpro_translate_billing_period( $pmpro_level->cycle_period, $pmpro_level->cycle_number ) ) ); 444 | } else { 445 | // translators: %1$d - number, %2$s - period. 446 | echo esc_html( sprintf( __( 'every %1$d %2$s', 'pmpro-variable-pricing' ), $pmpro_level->cycle_number, pmpro_translate_billing_period( $pmpro_level->cycle_period, $pmpro_level->cycle_number ) ) ); 447 | } 448 | } 449 | ?> 450 |
451 |
452 |
453 |
454 |
455 |
456 | id ); 464 | 465 | // Make sure level has variable pricing. 466 | if ( empty( $vpfields ) || empty( $vpfields['variable_pricing'] ) ) { 467 | return $level; 468 | } 469 | 470 | if ( isset( $_REQUEST['price'] ) ) { 471 | $price = preg_replace( '[^0-9\.\,]', '', floatval( $_REQUEST['price'] ) ); 472 | } 473 | 474 | if ( isset( $price ) ) { 475 | $level->initial_payment = $price; 476 | 477 | if ( $level->billing_amount > 0 ) { 478 | $level->billing_amount = $price; 479 | } 480 | } 481 | 482 | return $level; 483 | } 484 | add_filter( 'pmpro_checkout_level', 'pmprovp_pmpro_checkout_level' ); 485 | 486 | /** 487 | * Check if price is between min and max value. 488 | * If no max value is set, set it to unlimited. 489 | */ 490 | function pmprovp_pmpro_registration_checks( $continue ) { 491 | // only bother if we are continuing already 492 | if ( $continue ) { 493 | global $pmpro_currency_symbol, $pmpro_msg, $pmpro_msgt; 494 | 495 | // was a price passed in? 496 | if ( isset( $_REQUEST['price'] ) ) { 497 | // get values 498 | $level = pmpro_getLevelAtCheckout(); 499 | $level_id = empty( $level->id ) ? null : intval( $level->id ); 500 | $vpfields = pmprovp_get_settings( $level_id ); 501 | 502 | // Bail if the Variable Pricing is not set for this level. 503 | if( empty( $vpfields['variable_pricing'] ) ){ 504 | return $continue; 505 | } 506 | 507 | // get price 508 | $price = preg_replace( '[^0-9\.]', '', floatval( $_REQUEST['price'] ) ); 509 | 510 | // check that the price falls between the min and max 511 | if ( (double) $price < (double) $vpfields['min_price'] ) { 512 | $pmpro_msg = sprintf( 513 | __( 'The lowest accepted price is %1$s%2$s. Please enter a new amount.', 'pmpro-variable-pricing' ), 514 | esc_html( $pmpro_currency_symbol ), 515 | esc_html( $vpfields['min_price'] ) 516 | ); 517 | $pmpro_msgt = 'pmpro_error'; 518 | $continue = false; 519 | } elseif ( ! empty( $vpfields['max_price'] ) && ( (double) $price > (double) $vpfields['max_price'] ) ) { 520 | $pmpro_msg = sprintf( 521 | __( 'The highest accepted price is %1$s%2$s. Please enter a new amount.', 'pmpro-variable-pricing' ), 522 | esc_html( $pmpro_currency_symbol ), 523 | esc_html( $vpfields['max_price'] ) 524 | ); 525 | $pmpro_msgt = 'pmpro_error'; 526 | $continue = false; 527 | } 528 | 529 | // all good! 530 | } 531 | } 532 | 533 | return $continue; 534 | } 535 | add_filter( 'pmpro_registration_checks', 'pmprovp_pmpro_registration_checks' ); 536 | 537 | // save fields in session for PayPal Express/etc 538 | function pmprovp_pmpro_paypalexpress_session_vars() { 539 | if ( ! empty( $_REQUEST['price'] ) ) { 540 | $_SESSION['price'] = floatval( $_REQUEST['price'] ); 541 | } else { 542 | $_SESSION['price'] = ''; 543 | } 544 | } 545 | add_action( 'pmpro_paypalexpress_session_vars', 'pmprovp_pmpro_paypalexpress_session_vars' ); 546 | add_action( 'pmpro_before_send_to_twocheckout', 'pmprovp_pmpro_paypalexpress_session_vars', 10, 2 ); 547 | 548 | // Load fields from session if available. 549 | function pmprovp_init_load_session_vars() { 550 | if(function_exists('pmpro_start_session')) { 551 | pmpro_start_session(); 552 | } 553 | 554 | if ( empty( $_REQUEST['price'] ) && ! empty( $_SESSION['price'] ) ) { 555 | $_REQUEST['price'] = floatval( $_SESSION['price'] ); 556 | } 557 | } 558 | add_action( 'pmpro_checkout_preheader_before_get_level_at_checkout', 'pmprovp_init_load_session_vars', 5 ); 559 | 560 | /** 561 | * Register and set variables for JavaScript 562 | */ 563 | function pmprovp_load_scripts() { 564 | 565 | global $gateway, $pmpro_level; 566 | 567 | if ( empty( $pmpro_level ) ) { 568 | return; 569 | } 570 | 571 | // get variable pricing info 572 | $vpfields = pmprovp_get_settings( $pmpro_level->id ); 573 | 574 | // no variable pricing? just return 575 | if ( empty( $vpfields ) || empty( $vpfields['variable_pricing'] ) ) { 576 | return; 577 | } 578 | 579 | // Bail if PMPro is not loaded. 580 | if ( ! function_exists( 'pmpro_getGateway' ) ) { 581 | return; 582 | } 583 | 584 | if ( empty( $gateway ) ) { 585 | $gateway = get_option( 'pmpro_gateway' ); 586 | } 587 | 588 | wp_register_script( 'pmprovp', plugins_url( 'javascript/pmpro-variable-pricing.js', __FILE__ ), array( 'jquery' ), PMPROVP_VERSION, true ); 589 | 590 | wp_localize_script( 591 | 'pmprovp', 'pmprovp', array( 592 | 'settings' => array( 593 | 'gateway' => pmpro_getGateway(), 594 | 'gateway_billing' => ( in_array( $gateway, array( 'paypalexpress', 'twocheckout' ) ) !== false ) ? 'false' : 'true', 595 | ), 596 | 'pricing_billing' => ! pmpro_isLevelFree( $pmpro_level ) ? 'true' : 'false', 597 | 'vp_data' => wp_json_encode( $vpfields ) 598 | ) 599 | ); 600 | } 601 | add_action( 'wp_enqueue_scripts', 'pmprovp_load_scripts', 5 ); 602 | 603 | /** 604 | * Split register/localize and enqueue operation to simplify unhooking JS from plugin if needed 605 | */ 606 | function pmprovp_enqueue_scripts() { 607 | 608 | global $pmpro_level; 609 | 610 | if ( empty( $pmpro_level ) ) { 611 | return; 612 | } 613 | 614 | // get variable pricing info 615 | $vpfields = pmprovp_get_settings( $pmpro_level->id ); 616 | 617 | // no variable pricing? just return 618 | if ( empty( $vpfields ) || empty( $vpfields['variable_pricing'] ) ) { 619 | return; 620 | } 621 | 622 | wp_enqueue_script( 'pmprovp' ); 623 | } 624 | add_action( 'wp_enqueue_scripts', 'pmprovp_enqueue_scripts', 15 ); 625 | 626 | /* 627 | Function to add links to the plugin row meta 628 | */ 629 | function pmprovp_plugin_row_meta( $links, $file ) { 630 | if ( strpos( $file, 'pmpro-variable-pricing.php' ) !== false ) { 631 | $new_links = array( 632 | '' . esc_html__( 'Docs', 'pmpro-variable-pricing' ) . '', 633 | '' . esc_html__( 'Support', 'pmpro-variable-pricing' ) . '', 634 | ); 635 | $links = array_merge( $links, $new_links ); 636 | } 637 | return $links; 638 | } 639 | add_filter( 'plugin_row_meta', 'pmprovp_plugin_row_meta', 10, 2 ); 640 | 641 | --------------------------------------------------------------------------------