Version Description
- 2022-01-13 =
- BUG FIX: Fixed issue on some MySQL setups that would throw an error about the primary key in the pmpro_memberships_pages and pmpro_memberships_categories tables.
Download this release
Release Info
Developer | strangerstudios |
Plugin | Paid Memberships Pro |
Version | 2.7.1 |
Comparing to | |
See all releases |
Code changes from version 2.4.5 to 2.7.1
- CHANGELOG.txt +294 -1
- adminpages/admin_header.php +9 -4
- adminpages/advancedsettings.php +34 -17
- adminpages/dashboard.php +11 -7
- adminpages/discountcodes.php +147 -49
- adminpages/emailsettings.php +6 -38
- adminpages/emailtemplates.php +207 -0
- adminpages/functions.php +26 -5
- adminpages/license.php +22 -31
- adminpages/membershiplevels.php +149 -24
- adminpages/memberslist.php +1 -1
- adminpages/orders-csv.php +8 -0
- adminpages/orders.php +207 -111
- adminpages/pagesettings.php +84 -15
- adminpages/paymentsettings.php +12 -5
- adminpages/reports/login.php +10 -5
- adminpages/reports/memberships.php +2 -19
- adminpages/reports/sales.php +24 -9
- adminpages/templates/orders-email.php +25 -21
- adminpages/templates/orders-print.php +18 -14
- blocks/blocks.php +23 -3
- blocks/membership/block.js +32 -19
- classes/class-deny-network-activation.php +16 -4
- classes/class-pmpro-admin-activity-email.php +7 -5
- classes/class-pmpro-members-list-table.php +7 -8
- classes/class-pmpro-site-health.php +548 -0
- classes/class.memberorder.php +193 -17
- classes/class.pmproemail.php +180 -180
- classes/gateways/class.pmprogateway.php +6 -6
- classes/gateways/class.pmprogateway_authorizenet.php +8 -8
- classes/gateways/class.pmprogateway_braintree.php +49 -11
- classes/gateways/class.pmprogateway_check.php +6 -6
- classes/gateways/class.pmprogateway_cybersource.php +8 -8
- classes/gateways/class.pmprogateway_payflowpro.php +42 -4
- classes/gateways/class.pmprogateway_paypal.php +18 -10
- classes/gateways/class.pmprogateway_paypalexpress.php +261 -90
- classes/gateways/class.pmprogateway_paypalstandard.php +5 -4
- classes/gateways/class.pmprogateway_stripe.php +3201 -1773
- classes/gateways/class.pmprogateway_twocheckout.php +6 -4
- css/admin.css +646 -284
- css/blocks.editor.css +9 -1
- css/frontend.css +64 -1
- email/admin_change.html +0 -7
- email/admin_change_admin.html +0 -5
- email/billable_invoice.html +0 -6
- email/billing.html +0 -16
- email/billing_admin.html +0 -17
- email/billing_failure.html +0 -3
- email/billing_failure_admin.html +0 -6
- email/cancel.html +0 -6
- email/cancel_admin.html +0 -8
- email/checkout_check.html +0 -19
- email/checkout_check_admin.html +0 -17
- email/checkout_express.html +0 -15
- email/checkout_express_admin.html +0 -14
- email/checkout_free.html +0 -9
- email/checkout_free_admin.html +0 -8
- email/checkout_freetrial.html +0 -20
- email/checkout_freetrial_admin.html +0 -19
- email/checkout_paid.html +0 -24
- email/checkout_paid_admin.html +0 -23
- email/checkout_trial.html +0 -24
- email/checkout_trial_admin.html +0 -23
- email/credit_card_expiring.html +0 -13
- email/default.html +0 -1
- email/footer.html +0 -4
- email/header.html +0 -1
- email/invoice.html +0 -19
- email/membership_expired.html +0 -7
- email/membership_expiring.html +0 -6
- email/payment_action.html +0 -4
- email/payment_action_admin.html +0 -7
- email/trial_ending.html +0 -8
- includes/addons.php +3 -3
- includes/admin.php +29 -9
- includes/adminpages.php +16 -9
- includes/capabilities.php +1 -0
- includes/compatibility.php +106 -39
- includes/compatibility/beaver-builder.php +4 -0
- includes/compatibility/divi.php +93 -0
- includes/compatibility/elementor/class-pmpro-elementor-content-restriction.php +8 -2
- includes/compatibility/jetpack.php +31 -0
- includes/content.php +25 -15
- includes/currencies.php +9 -1
- includes/deprecated.php +133 -2
- includes/email-templates.php +536 -0
- includes/email.php +460 -29
- includes/functions.php +702 -127
- includes/init.php +11 -8
- includes/lib/Braintree/README.md +0 -134
- includes/lib/Braintree/composer.json +0 -36
- includes/lib/Braintree/lib/Braintree/Util.php +1 -1
- includes/lib/Stripe/README.md +0 -266
- includes/lib/name-parser.php +28 -9
- includes/lib/stripe-apple-pay/apple-developer-merchantid-domain-association +1 -0
- includes/lib/stripe-apple-pay/stripe-apple-pay.php +46 -0
- includes/license.php +100 -146
- includes/localization.php +10 -5
- includes/login.php +121 -78
- includes/metaboxes.php +23 -3
- includes/notifications.php +9 -5
- includes/profile.php +281 -34
- includes/recaptcha.php +137 -84
- includes/rest-api.php +285 -37
- includes/scripts.php +65 -56
- includes/services.php +11 -2
- includes/setup.sql +20 -4
- includes/spam.php +192 -0
- includes/updates/upgrade_2_4.php +46 -20
- includes/updates/upgrade_2_6.php +46 -0
- includes/upgradecheck.php +82 -37
- js/blocks.build.js +1883 -1
- js/pmpro-admin.js +290 -13
- js/pmpro-login.js +8 -2
- js/pmpro-stripe.js +128 -35
- languages/email/de_DE/admin_change.html +3 -3
- languages/email/de_DE/admin_change_admin.html +1 -1
- languages/email/de_DE/billing.html +4 -4
- languages/email/de_DE/billing_admin.html +2 -2
- languages/email/de_DE/billing_failure.html +2 -2
- languages/email/de_DE/billing_failure_admin.html +1 -1
- languages/email/de_DE/cancel.html +2 -2
- languages/email/de_DE/cancel_admin.html +2 -2
- languages/email/de_DE/checkout_check.html +3 -3
- languages/email/de_DE/checkout_check_admin.html +2 -2
- languages/email/de_DE/checkout_express.html +3 -3
- languages/email/de_DE/checkout_express_admin.html +2 -2
- languages/email/de_DE/checkout_free.html +2 -2
- languages/email/de_DE/checkout_free_admin.html +1 -1
- languages/email/de_DE/checkout_freetrial.html +3 -3
- languages/email/de_DE/checkout_freetrial_admin.html +2 -2
- languages/email/de_DE/checkout_paid.html +4 -4
- languages/email/de_DE/checkout_paid_admin.html +2 -2
- languages/email/de_DE/checkout_trial.html +4 -4
- languages/email/de_DE/checkout_trial_admin.html +2 -2
- languages/email/de_DE/credit_card_expiring.html +2 -2
- languages/email/de_DE/footer.html +1 -1
- languages/email/de_DE/invoice.html +4 -4
- languages/email/de_DE/membership_expired.html +2 -2
- languages/email/de_DE/membership_expiring.html +2 -2
- languages/email/de_DE/trial_ending.html +3 -3
- languages/gettext.sh +6 -0
- languages/paid-memberships-pro-ca.mo +0 -0
- languages/paid-memberships-pro-ca.po +167 -59
CHANGELOG.txt
CHANGED
@@ -1,7 +1,300 @@
|
|
1 |
== Changelog ==
|
2 |
-
= 2.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
* SECURITY: Updated escaping in the pmpro_getLevelAtCheckout and pmpro_checkDiscountCode functions as extra precaution against SQL injections. (Thanks, WPScan)
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
= 2.4.4 - 2020-09-02 =
|
6 |
* BUG FIX: Fixed fatal error that sometimes occurred on the payment settings page when using PHP 5.6 or earlier.
|
7 |
* BUG FIX: Fixed fatal errors that showed up on the frontend invoice page.
|
1 |
== Changelog ==
|
2 |
+
= 2.7.1 - 2022-01-13 =
|
3 |
+
* BUG FIX: Fixed issue on some MySQL setups that would throw an error about the primary key in the pmpro_memberships_pages and pmpro_memberships_categories tables.
|
4 |
+
|
5 |
+
= 2.7 - 2022-01-13 =
|
6 |
+
* FEATURE: Added a "Spam Protection" option to the advanced settings page. When used, IP addresses are blocked from checkout if there are more than 10 failsures within 15 minutes. (@ideadude)
|
7 |
+
* ENHANCEMENT: Checkouts with Stripe will now reuse Stripe Products and Prices. (@dparker1005)
|
8 |
+
* ENHANCEMENT: User profile now links to Stripe customer so that subscriptions can easily be directly updated in Stripe rather than through Subscriptions Updates which is now deprecated. (@dparker1005)
|
9 |
+
* ENHANCEMENT: Improved usability of the Require Membership metabox for sites with a large number of levels. #1885 #1692 (@kimcoleman)
|
10 |
+
* ENHANCEMENT: Include reCAPTCHA on Billing Page form. #1884 (@ideadude)
|
11 |
+
* ENHANCEMENT: Membership pages URLs are now included in the Site Health Information. (@JarrydLong)
|
12 |
+
* BUG FIX/ENHANCEMENT: Set the default for the `pmpro_send_200_http_response` filter to `false` instead of `true` to reduce impact of the functionality on sites that don't need it. #1868 (@dparker1005)
|
13 |
+
* BUG FIX/ENHANCEMENT: Consolidated the "Free memberships only" option into the "All memberships" option for enabling reCAPTCHA to ensure that paid memberships with discounts that make the membership $0 cost show reCAPTCHA consistently. #1878 #1840 (@JarrydLong)
|
14 |
+
* BUG FIX: Resolved PHP 8 fatal error with Authorize.net Silent Post handling. #1899 (@ZebulanStanphill)
|
15 |
+
* BUG FIX: The new filter `pmpro_admin_pagesetting_post_type` replaces the now deprecated filter `pmpro_admin_pagesetting_post_type_array` to allows setting one specific post type instead of always getting the first from an array. #1866 #1865 (@ipokkel)
|
16 |
+
* BUG FIX: Resolved issue where users may not be linked to their Stripe customer. (@dparker1005)
|
17 |
+
* BUG FIX: Now including all levels (public and hidden) in the Paid Memberships Pro section of Site Health information. #1898 (@kimcoleman)
|
18 |
+
* BUG FIX: Set cancelled/error status from PayPal Express IPN even when an order has no user. #1897 (@mircobabini)
|
19 |
+
* BUG FIX: Ensure styles are removed from excerpts generated for protected content. #1894 (@sc0ttkclark)
|
20 |
+
* BUG FIX: Various text adjustments for readability. #1892 (@kimcoleman)
|
21 |
+
* BUG FIX: Set primary key for `wp_pmpro_memberships_categories` and `wp_pmpro_memberships_pages` tables. #1891 (@ideadude)
|
22 |
+
* BUG FIX: Fixes around the `pmpro_manage_memberslist_columns` filter to accommodate sites that aren't in English. #1879 #1876 (@JarrydLong)
|
23 |
+
* BUG FIX: Use the correct cancel method when cancelling an oder through PayPal Standard IPN requests. Fixes compatibility with PMPro Cancel on Next Payment Date add on. #1882 (@mircobabini)
|
24 |
+
* BUG FIX: Discount code expiration date is now properly being used in the REST API. #1877 (@JarrydLong)
|
25 |
+
* BUG FIX: Remove the `SHIPTOPHONENUM` parameter sent to PayPal Website Payments API and encode all parameters passed into API updates. #1883 (@dparker1005)
|
26 |
+
* BUG FIX: Resolve timezone issue with Stripe subscriptions to resolve problems where trials would receive an extra day depending on the time of checkout. #1874 (@dparker1005)
|
27 |
+
* BUG FIX: Now using a single product per level and a single Stripe price per payment amount to prevent duplicate products and prices. #1824 (@dparker1005)
|
28 |
+
* REFACTOR: Organized and simplified Stripe gateway class. (@dparker1005)
|
29 |
+
|
30 |
+
= 2.6.7 - 2022-01-06 =
|
31 |
* SECURITY: Updated escaping in the pmpro_getLevelAtCheckout and pmpro_checkDiscountCode functions as extra precaution against SQL injections. (Thanks, WPScan)
|
32 |
|
33 |
+
= 2.6.6 - 2021-11-18 =
|
34 |
+
* SECURITY: Updated escaping on the discount codes page in the dashboard to prevent XSS attacks. #1867 (Thanks, Erwan from WPScan)
|
35 |
+
* BUG FIX/ENHANCEMENT: Added code to remove duplicate active rows in the pmpro_memberships_users table after level change. This might have happened e.g. if users were purchasing a level via the WooCommerce Add On multiple times. #1860 (@dlparker1005)
|
36 |
+
* BUG FIX/ENHANCEMENT: Improved the REST API endpoints to better support Zapier native requirements. #1862 (@andrewlimaza)
|
37 |
+
* BUG FIX: Fixed PHP notices in the name parser library. #1861 (@sc0ttkclark)
|
38 |
+
|
39 |
+
= 2.6.5 - 2021-11-12 =
|
40 |
+
* ENHANCEMENT: Introduced new action `pmpro_before_commit_express_checkout` to allow additional changes after an order has been saved but before sending customer to PayPal Express checkout. #1852 (@mircobabini)
|
41 |
+
* BUG FIX/ENHANCEMENT: Added login compatibility for Jetpack WordPress.com SSO when using the PMPro login page. #1848 (@sc0ttkclark)
|
42 |
+
* BUG FIX: Fixed PHP notices from status headers when server protocol information is unavailable. #1849 (@dparker1005)
|
43 |
+
* BUG FIX: Fixed metadata compatibility for membership levels and orders when calling `get_pmpro_membership_level_meta()` and `get_pmpro_membership_order_meta()` so they support getting all meta values for all keys. #1853 (@mircobabini)
|
44 |
+
* BUG FIX: Escape all Webhook communication debug output coming from gateways. #1855 (@ideadude, Victor Garcia)
|
45 |
+
|
46 |
+
= 2.6.4 - 2021-11-02 =
|
47 |
+
* ENHANCEMENT: Now including some information from the htaccess file in Site Health, including whether a getfile.php script is defined or if caching is being used. (@sc0ttkclark)
|
48 |
+
* ENHANCEMENT: Now including some of the PMPro-related PHP constants in the Site Health. (@sc0ttkclark)
|
49 |
+
* ENHNACEMENT: Now including the minimum PHP version (5.6 currently) in the readme.txt so it's shared on the WordPress.org page. (@sc0ttkclark)
|
50 |
+
* ENHANCEMENT: Added scrollable classes to the member history shown on user profile edit page in the dashboard. (@kimcoleman)
|
51 |
+
* BUG FIX/ENHANCEMENT: Now sending a 200 OK status message early when the Stripe webhook is running to avoid timeout issues. We may use this new pmpro_send_200_http_response in the other webhook/IPN handlers later on. (@dparker1005)
|
52 |
+
* BUG FIX/EHNANCEMENT: Removed the "fee" info from the edit user page. This was often misleading. The fee is still shown on the members list and frontend account page. Future updates will include work to make sure the fee is more accurate in cases where subscriptions or levels are being changed by admins after checkout. (@ideadude)
|
53 |
+
* BUG FIX/ENHANCEMENT: Once again enqueuing the admin.css file on all WP admin pages. This fixes issues where styles weren't being applied to the edit user/profile page in the dashboard. (@ideadude)
|
54 |
+
* BUG FIX/ENHANCEMENT: Removed the "Member Value Report". We didn't intend to move this over from the old Member History add on. The report was inaccurate and had optimization issues. (@kimcoleman)
|
55 |
+
* BUG FIX/ENHANCEMENT: Added login compatibility for wordpress.com hosted sites. This fixes some issues with wordpress.com's SSO when using the PMPro login page. (@sc0ttkclark)
|
56 |
+
* BUG FIX: Fixed issue introduced in 2.6.3 where memberships were not being cancelled when cancelled at PayPal. (@mircobabini)
|
57 |
+
* BUG FIX: Now including time when calculating profile start date. In the past, we would set it to 00:00:00 which could add or remove a few hours from the subscription. (@dparker1005)
|
58 |
+
* BUG FIX: Fixed issue where enddates were incorrectly set sometimes when expiration period was "Hour". (@kimwhite)
|
59 |
+
|
60 |
+
= 2.6.3 - 2021-10-11 =
|
61 |
+
* ENHANCEMENT: Now passing "app" information to Stripe through API calls. (@dparker1005)
|
62 |
+
* ENHANCEMENT: Updated PayPal IPN to detect messages for refunds to at least log it. (@mircobabini)
|
63 |
+
* ENHANCEMENT: Updated PayPal IPN to differentiate between cases where the initial payment failed vs a subscription was cancelled. (@mircobabini)
|
64 |
+
* ENHANCEMENT: Better styling of the membership levels history when empty. (@mircobabini)
|
65 |
+
* BUG FIX/ENHANCEMENT: Now showing better error messages when license key checks fail due to connection issues. (@ideadude)
|
66 |
+
* BUG FIX: Improved PayPal API integration to handle cases where PayPal is returning encoding errors but still processing payments and subscriptions. (@mircobabini)
|
67 |
+
* BUG FIX: Fixed issue where the Stripe sandbox key wasn't saved properly when using Stripe connect. (@dparker1005)
|
68 |
+
* BUG FIX: Fixed issue where a double $$ was showing up in specific emails. (@andrewlimaza)
|
69 |
+
* BUG FIX: Fixed warnings in various webhook and IPN handlers. (@ideadude)
|
70 |
+
* BUG FIX: Fixed warning in the admin activity email cron job. (@andrewlimaza)
|
71 |
+
|
72 |
+
= 2.6.2 - 2021-09-17 =
|
73 |
+
* ENHANCEMENT: Made username the first column in the members list. This helps with the mobile view. #1764 (@dparker1005)
|
74 |
+
* BUG FIX/ENHANCEMENT: Will now block uninstall.php from running if an older version of PMPro is deleted from the plugins page. #1773 (@mircobabini)
|
75 |
+
* BUG FIX/ENAHCEMENT: Expanded the allowed HTML for pmpro_kses to support email templates and added a pmpro_kses filter. #1770 (@sc0ttkclark)
|
76 |
+
* BUG FIX/ENHANCEMENT: Updated the CSS for "clickable" labels in checkbox lists. #1752 (@kimcoleman)
|
77 |
+
* BUG FIX: Fixed bug with sending test emails from the email templates page. #1765 (@ideadude)
|
78 |
+
* BUG FIX: Added the !!membership_level_confirmation_message!! var to the list on the email tempaltes page. #1783 (@kimwhite)
|
79 |
+
* BUG FIX: Updated the SendWP link per their new dashboard area. #1777 (@kimcoleman)
|
80 |
+
* BUG FIX: Fixed bug where PMPro-related usermeta was sometimes blanked out if those fields weren't present at checkout, e.g. when a logged in user was checking out. #1762 (@andrewlimaza)
|
81 |
+
* BUG FIX: Fixed issue where gateway-related notices weren't showing up on the discount codes page. #1757 (@mircobabini)
|
82 |
+
* BUG FIX: Fixed some design issues with the member history tables. #1753 (@mircobabini)
|
83 |
+
* BUG FIX: Fixed issues where the option to block subscribers from the dashboard would interfere with other plugins, e.g. the MailPoet plugin. #1749 (@sc0ttkclark)
|
84 |
+
* BUG FIX: Fixed issues where the RTL stylesheets might not load if your theme overrode frontend.css or admin.css but didn't have the RTL equivalents. (@ideadude, @sc0ttkclark)
|
85 |
+
|
86 |
+
= 2.6.1.1 - 2021-08-25 =
|
87 |
+
* BUG FIX: Fixed issue with PMPro blocks not showing up in the block editor.
|
88 |
+
* REFACTOR: Some JS functions and element IDs and names have been prefixed with pmpro_ to avoid conflicts.
|
89 |
+
|
90 |
+
= 2.6.1 - 2021-08-24 =
|
91 |
+
* SECURITY: Added capability checks to further tighten security around email template settings. (@ideadude, @sc0ttkclark)
|
92 |
+
* SECURITY: Added a pmpro_kses function and using that to sanitize email template bodies and all email bodies before sending. (@ideadude, @sc0ttkclark)
|
93 |
+
* ENHANCEMENT: Added Email Templates link to PMPro Dashboard for getting started. #1722 (@kimcoleman)
|
94 |
+
* ENHANCEMENT: All actions in the admin list tables are now filterable for Discount Codes (`pmpro_discountcodes_row_actions`), Membership Levels (`pmpro_membershiplevels_row_actions`), and Orders (`pmpro_orders_user_row_actions`). #1686 (@sc0ttkclark, @mircobabini)
|
95 |
+
* BUG FIX: Ensure our admin scripts/styles only load on PMPro admin pages. #1724 (@sc0ttkclark)
|
96 |
+
* BUG FIX: Remove unused code in `pmpro_comments_filter()` that was triggering a PHP warning. #1730 (@freax)
|
97 |
+
* BUG FIX: Stop turning on autoloading for PMPro options when saving them. #1719 (@freax)
|
98 |
+
* BUG FIX: Prevent fatal error for PHP 8 in `pmpro_email_templates_email_data()` to strictly check for `WP_User` objects. #1729 (@ZebulanStanphill)
|
99 |
+
* BUG FIX: Fix problem where `pmpro_round_price()` would not take into account currencies with decimals set to 0. #1732 (@dparker1005, @ipokkel, @sc0ttkclark)
|
100 |
+
* BUG FIX: Clarify that Stripe Legacy keys remain connected and will continue to work. #1735 (@dparker1005, @sc0ttkclark)
|
101 |
+
|
102 |
+
= 2.6 - 2021-08-12 =
|
103 |
+
* FEATURE: Updated Stripe integration to use Stripe Connect. See [Gateway Fees](https://www.paidmembershipspro.com/gateway/stripe/#tab-fees) for information about transaction fees for Stripe Connect and our platform fee for those without an active Plus/Unlimited license.
|
104 |
+
* FEATURE: Improved REST API endpoints to support Zapier integration natively.
|
105 |
+
* FEATURE: You can now set levels to expire after a certain number of hours, and can set users to expire at a specific time down to the minute.
|
106 |
+
* FEATURE: The Member History Add On has been merged into the core PMPro plugin. A table of the user's membership and order history is shown on the edit user page of the admin dashboard.
|
107 |
+
* FEATURE: The Email Templates Add On has been merged into the core PMPro plugin. You can edit PMPro-related email templates from the Memberships -> Settings -> Email Templates page in the admin dashboard.
|
108 |
+
* FEATURE: You can now use PMPro blocks in the new widget area of WP 5.8.
|
109 |
+
* BUG FIX/ENHANCEMENT: Establishing style for scrollable boxes throughout core plugin.
|
110 |
+
* BUG FIX/ENHANCEMENT: Using HTTPS to set the pmpro_visit cookie if over HTTPS. (Thanks, freax on GitHub)
|
111 |
+
* BUG FIX: Fixed fatal error in PHP 8 when deleting a Stripe webhook. (Thanks, Zebulan Stanphill)
|
112 |
+
* BUG FIX: Fixed warnings shown on the widget page when using WP 5.8+.
|
113 |
+
|
114 |
+
= 2.5.10.2 - 2021-08-02 =
|
115 |
+
* ENHANCEMENT: New scripts to use WP CLI to update pot and po/mo files.
|
116 |
+
* BUG FIX/ENHANCEMENT: Updated cancellation logic to support upcoming Cancel on Next Payment Date Add On changes.
|
117 |
+
* BUG FIX/ENHANCEMENT: Making sure to use the correct security setting when calling setcookie from an HTTPS site. (Thanks, freax on GitHub)
|
118 |
+
* BUG FIX: Now archiving Stripe products after checkout. We create a unique product for each checkout, and these would clutter up the Stripe reports.
|
119 |
+
* BUG FIX: Fixing data erasure and data export request action for login page.
|
120 |
+
* BUG FIX: Fixed issue where PMPro settings on Elementor elements could override the "should_render" setting incorrectly. (Thanks, codezz on GitHub)
|
121 |
+
* BUG FIX: Now catching the case where you try to email an invoice for an order that has no user.
|
122 |
+
|
123 |
+
= 2.5.10.1 - 2021-07-05 =
|
124 |
+
* BUG FIX/ENHANCEMENT: The 'Edit Code: %s' string on the discount codes page is now wrapped for translation.
|
125 |
+
* BUG FIX: Fixed issue with the getfile.php script introduced in 2.5.10.
|
126 |
+
|
127 |
+
= 2.5.10 - 2021-06-25 =
|
128 |
+
* SECURITY: Fixed XSS vulnerability on the edit order page in the dashboard. (Thanks, Scott Kingsley Clark)
|
129 |
+
* ENHANCEMENT: Improved escaping and localization for the message returned when clicking to apply discount code.
|
130 |
+
* ENHANCEMENT: Now hiding gateway setting API keys behind asterisks.
|
131 |
+
* ENHANCEMENT: Added some extra hooks to the edit membership levels page in the dashboard: pmpro_membership_level_after_billing_details_settings, pmpro_membership_level_after_other_settings, pmpro_membership_level_after_content_settings.
|
132 |
+
* ENHANCEMENT: Added a pmpro_after_order_settings_table hook to the edit order page in the dashboard.
|
133 |
+
* BUG FIX/ENHANCEMENT: Now passing a CARDONFILE parameter with PayPal Payflow payment and subscription transactions.
|
134 |
+
* BUG FIX/ENHANCEMENT: Using the wp.passwordStrength.userInputDisallowedList function from WP 4.5 if available.
|
135 |
+
* BUG FIX/EHNANCEMENT: Now making sure that the pmpro_update_order and pmpro_updated_order hooks fire whenever an order is updated in the DB.
|
136 |
+
* BUG FIX: Fixed issue in getfile script where parameters in the URL would cause File not found errors.
|
137 |
+
* BUG FIX: Fixed how the PayPal IPN handler handles cases where a subscription is set up correctly but the initial payment failed. We now correctly cancel these users and mark their order as error.
|
138 |
+
* BUG FIX: Improved error handling in the PayPal Express integration, particularly when a subscriptions PROFILESTATUS is missing.
|
139 |
+
* BUG FIX: User registered date is now shown in local time.
|
140 |
+
* BUG FIX: Fixed issue where the deprecated pmpro_getClassForField function wasn't returning a value properly. (Thanks, Elena Draculet)
|
141 |
+
* BUG FIX: Updated the pmpro_sort_levels_by_order function to use level IDs for keys, since some code expects that for level arrays. This matches the behavior we had before introducing this function.
|
142 |
+
* BUG FIX: Updated the pmpro_changeMembershipLevel function always set the order status to error if that was passed in as the "old level status".
|
143 |
+
* BUG FIX: Fixed warning in searches/pages when PMPro pages is not set.
|
144 |
+
* BUG FIX: Fixed warnings being generated when using PHP 8 and Divi
|
145 |
+
* BUG FIX: Fixed warnings related to PayPal Express session variables.
|
146 |
+
|
147 |
+
= 2.5.9.1 - 2021-05-12 =
|
148 |
+
* BUG FIX/ENHANCEMENT: Updated pmpro_changeMembershipLevel() to return null if the user's level is not changed. For the past 2 vesions, we've been returning true in these cases, which caused PMPro to send emails to the admin when the edit use page was saved, even if there was no level change. This change has been backported to versions 2.5.8 and 2.5.9.
|
149 |
+
|
150 |
+
= 2.5.9 - 2021-05-05 =
|
151 |
+
* ENHANCEMENT: Adjusting style for prices and price parts shown on the frontend.
|
152 |
+
* ENHANCEMENT: Adjusting HTML for links in the Orders table in the dashboard.
|
153 |
+
* BUG FIX: Reverted the change to the pmpro_is_checkout() function. Since we default to the first available level, calling pmpro_getLevelForCheckout() was causing pmpro_is_checkout to return true on ALL pages. This disrupted a lot of functionality.
|
154 |
+
* BUG FIX: Fixed warnings in the pmpro_getLevelAtCheckout() function.
|
155 |
+
* BUG FIX: Fixed issue where "All Time Sales" was showing up as 0, even when there were sales.
|
156 |
+
|
157 |
+
= 2.5.8 - 2021-04-30 =
|
158 |
+
* ENHANCEMENT: Added `pmpro_membership_content_filter` filter to let other plugins change how PMPro filters member content.
|
159 |
+
* ENHANCEMENT: Improved de_DE email template translation. (Thanks, biker238 on GitHub)
|
160 |
+
* ENHANCEMENT: Added `pmpro_change_level` filter.
|
161 |
+
* ENHANCEMENT: Improved display of prices on invoices and added pmpro_display_price_parts function and filters so plugins like the upcoming AvaTax add on can add subtotals to the price displays.
|
162 |
+
* ENHANCEMENT: Added a pmpro_after_all_membesrhip_level_changes hook that fires at the end of the page load and can be used to process all membership changes in bulk.
|
163 |
+
* ENHANCEMENT: The "User" column on the orders page now shows the username and email.
|
164 |
+
* ENHANCEMENT: Added a pmpro_stripe_create_subscription_array filter. (Thanks, ermGit on GitHub)
|
165 |
+
* BUG FIX/ENHANCEMENT: pmpro_change_level returns true now if the function is called to change a user’s level to one they already have.
|
166 |
+
* BUG FIX/ENHANCEMENT: No longer calling $order->updateTimestamp() on orders adminpage.
|
167 |
+
* BUG FIX/ENHANCEMENT: Updated conditional to check ‘street’ instead of ‘name’ when displaying billing address on Invoice/Confirmation.
|
168 |
+
* BUG FIX/ENHANCEMENT: Improved localization and added missing strings to translation.
|
169 |
+
* BUG FIX/ENHANCEMENT: Updated to use `get_user_locale1 to load localization.
|
170 |
+
* BUG FIX/ENHANCEMENT: Now Preserving existing values for `post__not_in` and `category__not_in` when filtering search and archive queries.
|
171 |
+
* BUG FIX/ENHANCEMENT: Fixed sorting of the Membership Level column on the Users List table in the WP admin dashboard.
|
172 |
+
* BUG FIX/ENHANCEMENT: Added a pmpro_sort_levels_by_order function and using it in various places to make sure levels are listed in the order they are in on the PMPro settings page.
|
173 |
+
* BUG FIX/ENHANCEMENT: Added an extra check in the pmpro_is_checkout function that helps with issues that were coming up in some add ons.
|
174 |
+
* BUG FIX/ENHANCEMENT: The level cache now takes into account the $include_active parameter.
|
175 |
+
* BUG FIX/ENHANCEMENT: The CSS class is now properly added to the body tag when a PMPro page block is used on a page.
|
176 |
+
* BUG FIX/EHNANCEMENT: Better timezone handling in sales reports.
|
177 |
+
* BUG FIX/ENHANCEMENT: Fixed a few places where we might think a free order was paid if using a currency with more or less than 2 decimal places.
|
178 |
+
* BUG FIX: Fixed deprecated jQuery functions in pmpro-admin.js.
|
179 |
+
* BUG FIX: Fixed warning for a missing/deleted level in the pmpro_post_classes function.
|
180 |
+
* BUG FIX: Default `pmpro_longform_address` to true on Billing Information page.
|
181 |
+
* BUG FIX: Fixed `pmpro_twocheckout_validate` filter.
|
182 |
+
* BUG FIX: Fixed variables passed to the `pmpro_discount_code_used` filter.
|
183 |
+
* BUG FIX: CZK currency should have 2 decimals.
|
184 |
+
* BUG FIX: Avoiding a redirect loop if the login page is deleted. (Thanks, George Stephanis)
|
185 |
+
* BUG FIX: Fixed the password reset link in new user notification email when not using pretty permalinks.
|
186 |
+
* BUG FIX: Fixed issues with password reset URLs on multisite networks.
|
187 |
+
* BUG FIX: Fixed the issue where sales weren't showing up on report charts sometimes on the 31st of the month.
|
188 |
+
|
189 |
+
= 2.5.7 - 2021-03-10 =
|
190 |
+
* ENHANCEMENT: Added a pmpro_checkout_message filter that can be used to filter error messages shown at checkout.
|
191 |
+
* BUG FIX/ENHANCEMENT: Now making sure some billing address fields are available for the billing failure emails sent during the PayPal IPN handler.
|
192 |
+
* BUG FIX/ENHANCEMENT: Fixed issues where HTML entities were shown in level prices in some places when using certain currencies. All prices are sent through a special pmpro_escape_price function that allows div, span, and sup tags with id and class attributes. Also removed from unneeded small tags and grey coloring of prices in certain spots.
|
193 |
+
* BUG FIX: Now cancelling membership when a SUBSCRIPTION_CANCELED message is sent to the Braintree webhook handler. In the past, we incorrectly sent the payment failed email instead.
|
194 |
+
* BUG FIX: Fixed display issues with the Require Membership block. The level select field has been swapped with a list of checkboxes.
|
195 |
+
* BUG FIX: Fixed warnings that occurred when processing failed payments in webhook and IPN handlers.
|
196 |
+
* BUG FIX: Fixed our Braintree class so we will only attempt to update a user's credit card and address when the getCustomer method is called at checkout or during a billing update.
|
197 |
+
* BUG FIX: Fixed issue where refreshing the checkout review page when using PayPal Express caused the associated order to be updated again. Now the order status is updated to review and only updates again when the user confirms.
|
198 |
+
* BUG FIX: Avoiding warnings when the pmpro_url function is used if the PMPro pages haven't been set up yet. (Thanks, Thomas Sjolshagen)
|
199 |
+
* REFACTOR: Updated the pmpro_getSpecificMembershipLevelForUser( $user_id, $level_id ) function so both fields are required. Will still default to the current user if null is passed for the $user_id.
|
200 |
+
|
201 |
+
= 2.5.6 - 2021-03-05 =
|
202 |
+
* SECURITY: Now sanitizing and escaping the `order` parameter when filtering the users table in the dashboard. (Thanks, Gen Sato)
|
203 |
+
* BUG FIX/ENHANCEMENT: Now hiding the ApplePay/GooglePay "Payment Request" buttons when the main checkout form is submitted. This helps to prevent double checkouts.
|
204 |
+
* BUG FIX: Fixed missing membership data in the billing failed email.
|
205 |
+
|
206 |
+
= 2.5.5 - 2021-02-22 =
|
207 |
+
* SECURITY: Better sanitization of parameters on some REST API endpoints.
|
208 |
+
* SECURITY: Now showing reCAPTCHA field at checkout even for logged in users.
|
209 |
+
* ENHANCEMENT: Added find_billing_address() method to the MemberOrder class. This will look for the address on the last order with the same sub id or in user meta.
|
210 |
+
* ENHANCEMENT: Better styling for invoices shown on the frontend.
|
211 |
+
* ENHANCEMENT: No longer forcing column width % in the members list table.
|
212 |
+
* ENHANCEMENT: Added a pmpro_doing_webhook action that is fired at the beginning of our webhook/IPN handlers.
|
213 |
+
* ENHANCEMENT: Added a pmpro_membership_level_after_billing_details_settings hook to the edit membership level page. This hook should now be used to add billing related settings.
|
214 |
+
* BUG FIX/ENHANCEMENT: Allowing order total to be set to 0, even if there is a subtotal and tax amount.
|
215 |
+
* BUG FIX/ENHANCEMENT: Stripe checkout fields will now use the language set in the Stripe settings.
|
216 |
+
* BUG FIX/ENHANCEMENT: The URL check in our notifications code now accepts arrays (e.g. to see if a URL has one of a group of top level domains). This fixes a warning some may have seen in error logs.
|
217 |
+
* BUG FIX: Fixed issues where totals on PayPal recurring payments were sometimes incorrect if both an mt_gross and amount field were passed via IPN.
|
218 |
+
|
219 |
+
= 2.5.4 - 2021-01-28 =
|
220 |
+
* ENHANCEMENT: Bump license year 2021 - 10 years.
|
221 |
+
* ENHANCEMENT: Now passing billing street in `pmpro_tax` filter.
|
222 |
+
* ENHANCEMENT: Prefixed our pmpro_stripeResponseHandler function to avoid conflicts.
|
223 |
+
* ENHANCEMENT: Added getRealPaymentTransactionId method to PayPal Express gateway class to recover a missing transaction ID.
|
224 |
+
* ENHANCEMENT: Added `pmpro_checkout_before_form` action to hook anything before the membership checkout form.
|
225 |
+
* ENHANCEMENT: Added avatar as a valid field type for the [pmpro_member] shortcode.
|
226 |
+
* ENHANCEMENT: Changed license key field to text type and unmasked. Masking implied the key was hashed before saving which is not true.
|
227 |
+
* ENHANCEMENT: Added`pmpro_discount_code_used` action hook for when a discount code is used.
|
228 |
+
* ENHANCEMENT: Stripe will now pull billing address info for recurring orders from webhooks.
|
229 |
+
* BUG FIX/ENHANCEMENT: Improved user interface, error handling, and messages in the frontend password reset process.
|
230 |
+
* BUG FIX/ENHANCEMENT: Added a space between state and zip code in billing info.
|
231 |
+
* BUG FIX/ENHANCEMENT: Now rounding amount sent with Stripe payment request button.
|
232 |
+
* BUG FIX/ENHANCEMENT: Improved `pmpro_check_plugin_version` function to also check a specific value of the `get_plugin_data` array.
|
233 |
+
* BUG FIX/ENHANCEMENT: Added `pmpro_membership_levelmeta` and `pmpro_membership_ordermeta` tables to uninstall process.
|
234 |
+
* BUG FIX/ENHANCEMENT: Escaped things in SQL queries in 2Checkout INS service handler.
|
235 |
+
* BUG FIX/ENHANCEMENT: Cleaned up levels page template and added MMPU compatibility.
|
236 |
+
* BUG FIX/ENHANCEMENT: Fixed pagination and export issues with a discount code filter on the Orders admin page.
|
237 |
+
* BUG FIX/ENHANCEMENT: Prefixed our `pmpro_stripeResponseHandler` function to avoid conflicts with other Stripe code that may not be prefixed.
|
238 |
+
* BUG FIX/ENHANCEMENT: Cleaned up conditionals and escaping improvements in the `pmpro_redirect_to_logged_in` function.
|
239 |
+
* BUG FIX/ENHANCEMENT: Fixed deprecation notices for sites running PHP 8.
|
240 |
+
* BUG FIX/ENHANCEMENT: Improved SQL query format in the applydiscountcode service.
|
241 |
+
* BUG FIX: Fixed issues with ReCAPTCHA v2 and certain gateways.
|
242 |
+
* BUG FIX: Fixed bug where blog name was not showing in Admin Activity email.
|
243 |
+
* BUG FIX: Improved incorrect PHP doc blocks.
|
244 |
+
* BUG FIX: Fixed an issue on some sites where password reset link in email was incorrect.
|
245 |
+
* BUG FIX: Fixed level change issues during 2Checkout checkout.
|
246 |
+
* BUG FIX: Fixed issue where `checkout_levels` REST API endpoint could return the wrong initial payment
|
247 |
+
* BUG FIX: Fixed undefined notice for timestamp variable in the Stripe gateway class.
|
248 |
+
* BUG FIX: Avoiding warnings when user ids are in the memberships_users table, but a user doesn't exist.
|
249 |
+
* BUG FIX: Now setting the correct value for membership_id in the admin change emails.
|
250 |
+
|
251 |
+
= 2.5.3 - 2021-01-26 =
|
252 |
+
* SECURITY: Fixed indirect object reference vulnerability where order information, including customer names, email addresses, and order numbers could be accessed by non-admin WordPress users. (Thanks, WP Plugins Team)
|
253 |
+
* SECURITY: Now checking ReCAPTCHA validation before enabling the submit button on the checkout form when using ReCAPTCHA v2. This helps to keep bad actors from testing credit cards on your checkout page. We were already doing a similar check when using ReCAPTCHA v3. Further updates to rate limit credit card failures are planned.
|
254 |
+
|
255 |
+
= 2.5.2 - 2020-10-23 =
|
256 |
+
* BUG FIX: Fixed issue where the RECAPTCHA library wasn't being loaded early enough to validate at checkout.
|
257 |
+
* BUG FIX: Fixed issue where code in the Stripe class was unsetting some required fields, even if Stripe was not being used at checkout.
|
258 |
+
|
259 |
+
= 2.5.1 - 2020-10-16 =
|
260 |
+
* SECURITY: Fixed XSS vulnerability on the Members List page of the dashboard. (Thanks, Ron Masas from Checkmarx.com)
|
261 |
+
* ENHANCEMENT: Add Ukrainian Hryvnia currency. (Thanks, Mirco Babini)
|
262 |
+
* ENHANCEMENT: Added a "non-members" option to the Beaver Build module.
|
263 |
+
* BUG FIX: Fixed issue where only USD and US were allowed with Stripe's GooglePay/ApplePay buttons.
|
264 |
+
* BUG FIX: Fixed issue where some profile fields, e.g. those added with Register Helper, were accidentally updated or removed when accessing the frontend profile page.
|
265 |
+
* BUG FIX: Fixed issue with tracking discount code uses when using the 2Checkout gateway. (Thanks, karambk on GitHub)
|
266 |
+
* BUG FIX: No longer running excerpts through wpautop when a more tag is used.
|
267 |
+
|
268 |
+
= 2.5 - 2020-10-02 =
|
269 |
+
* FEATURE: When using the Stripe Gateway, you may now allow users to pay using Apple Pay, Google Pay, or Microsoft Pay depending on their browser. Enable this feature from the payment settings page.
|
270 |
+
* FEATURE: Added Divi Builder compatibility.
|
271 |
+
* FEATURE: Updated the Braintree Gateway class to be able to use the Braintree API for the pmpro_next_payment() function. Note, for performance reasons, you must call this method directly or enable it by hooking it up with code like `add_filter('pmpro_next_payment', array('PMProGateway_braintree', 'pmpro_next_payment'), 10, 3);`
|
272 |
+
* FEATURE: Added ordermeta tables and functions. We will wait about a year for all users to upgrade before using these widespread. (Thanks, Mirco Babini)
|
273 |
+
* ENHANCEMENT: The "short" version of the level cost text for a free level is now "Free" instead of "0.00 now".
|
274 |
+
* ENHANCEMENT: Added a `get_original_subscription_order` method to the MemberOrder class. This will return the first order in a subscription when called from a recurring order.
|
275 |
+
* ENHANCEMENT: Removed the old style license nags.
|
276 |
+
* BUG FIX/ENHANCEMENT: Using microtime and a static counter int to make sure our order and discount codes are unique. In the past very high traffic sites could run into duplicates if two checkouts happened at the exact same second.
|
277 |
+
* BUG FIX/ENHANCEMENT: Adjust order delete prompt to support other locales.
|
278 |
+
* BUG FIX/ENHANCEMENT: Better handling of tax amounts in recurring payments, e.g. when using the PMPro VAT Tax add on.
|
279 |
+
* BUG FIX/ENHANCEMENT: Optimized how often we hit the Stripe API when events on the checkout page could potentially update the price of checkout.
|
280 |
+
* BUG FIX/ENHANCEMENT: The checkout_levels api call now takes `level` as param.
|
281 |
+
* BUG FIX/ENHANCEMENT: No longer running sanitize_text_field on password fields. This would break passwords that had strings of characters resembling html tags.
|
282 |
+
* BUG FIX/ENHANCEMENT: Now warning admins if the Stripe billing period is longer than 1 year. Billing periods greater than 1 year are not allowed by Stripe.
|
283 |
+
* BUG FIX/ENHANCEMENT: Now detecting when a Stripe webhook is set up for an older version of the Stripe API and showing a notice with a link to update.
|
284 |
+
* BUG FIX/ENHANCEMENT: Adding MAXFAILEDPAYMENTS=1 to PayPal add subscription requests. This tells PayPal to cancel a subscription after the first failed payment. In our experience, the automatic retries rarely worked well. This change fixes issues with subscriptions going out of sync or users retaining access to your site when their payment has failed. Members still receive the payment failed email, which prompts users to return to the site to renew.
|
285 |
+
* BUG FIX/ENHANCEMENT: Fixing some issues where we are adding extra break tags into the password reset email. There are still some issues like this when using certain plugins. We are working on a general fix.
|
286 |
+
* BUG FIX/ENHANCEMENT: Removed the "coupon amount" field from the edit order page. These were hold outs from the 2007! ecommerce plugin PMPro was forked from. You can set the pmpro_orders_show_coupon_amounts filter to __return_true to show these fields again if you were using them for tracking things in your custom code.
|
287 |
+
* BUG FIX: Fixed MMPU compatibility when using discount codes.
|
288 |
+
* BUG FIX: No longer filtering the wp login url when on wp-login.php. This fixes issues with iThemes Security 2FA.
|
289 |
+
* BUG FIX: Fixed issues where the Stripe webhook was not being updated sometimes when clicking the button to update.
|
290 |
+
* BUG FIX: Fixed some notices and warnings when using Braintree.
|
291 |
+
* BUG FIX: Now resetting memberslist page number when changing shown level.
|
292 |
+
* BUG FIX: Now ensuring that the discount code field updates, update the Request Button price.
|
293 |
+
* BUG FIX: Fixed issue where non-pretty permalinks may break frontend password resets.
|
294 |
+
* BUG FIX: Fixed invoice links on the account page. (Thanks, Mateusz Hołtyn)
|
295 |
+
* BUG FIX: Fixed incorrect label "for" attribute for uninstall setting.
|
296 |
+
* BUG FIX: Fixed issue where some free plugins distributed by PMPro would show warnings about requiring a Plus license.
|
297 |
+
|
298 |
= 2.4.4 - 2020-09-02 =
|
299 |
* BUG FIX: Fixed fatal error that sometimes occurred on the payment settings page when using PHP 5.6 or earlier.
|
300 |
* BUG FIX: Fixed fatal errors that showed up on the frontend invoice page.
|
adminpages/admin_header.php
CHANGED
@@ -193,7 +193,7 @@
|
|
193 |
?>
|
194 |
<script>
|
195 |
jQuery(document).ready(function() {
|
196 |
-
jQuery.get('<?php echo
|
197 |
if(data && data != 'NULL')
|
198 |
jQuery('#pmpro_notifications').html(data);
|
199 |
});
|
@@ -211,6 +211,7 @@
|
|
211 |
'pmpro-pagesettings',
|
212 |
'pmpro-paymentsettings',
|
213 |
'pmpro-emailsettings',
|
|
|
214 |
'pmpro-advancedsettings',
|
215 |
'pmpro-addons',
|
216 |
'pmpro-license'
|
@@ -234,7 +235,7 @@
|
|
234 |
<?php } ?>
|
235 |
|
236 |
<?php if(current_user_can('pmpro_membershiplevels')) { ?>
|
237 |
-
<a href="<?php echo admin_url('admin.php?page=pmpro-membershiplevels');?>" class="nav-tab<?php if( in_array( $view, array( 'pmpro-membershiplevels', 'pmpro-discountcodes', 'pmpro-pagesettings', 'pmpro-paymentsettings', 'pmpro-emailsettings', 'pmpro-advancedsettings' ) ) ) { ?> nav-tab-active<?php } ?>"><?php _e('Settings', 'paid-memberships-pro' );?></a>
|
238 |
<?php } ?>
|
239 |
|
240 |
<?php if(current_user_can('pmpro_addons')) { ?>
|
@@ -246,7 +247,7 @@
|
|
246 |
<?php } ?>
|
247 |
</nav>
|
248 |
|
249 |
-
<?php if( $view == 'pmpro-membershiplevels' || $view == 'pmpro-discountcodes' || $view == 'pmpro-pagesettings' || $view == 'pmpro-paymentsettings' || $view == 'pmpro-emailsettings' || $view == 'pmpro-advancedsettings' ) { ?>
|
250 |
<ul class="subsubsub">
|
251 |
<?php if(current_user_can('pmpro_membershiplevels')) { ?>
|
252 |
<li><a href="<?php echo admin_url('admin.php?page=pmpro-membershiplevels');?>" title="<?php _e('Membership Levels', 'paid-memberships-pro' );?>" class="<?php if($view == 'pmpro-membershiplevels') { ?>current<?php } ?>"><?php _e('Levels', 'paid-memberships-pro' );?></a> | </li>
|
@@ -265,7 +266,11 @@
|
|
265 |
<?php } ?>
|
266 |
|
267 |
<?php if(current_user_can('pmpro_emailsettings')) { ?>
|
268 |
-
<li><a href="<?php echo admin_url('admin.php?page=pmpro-emailsettings');?>" title="<?php _e('Email Settings', 'paid-memberships-pro' );?>" class="<?php if($view == 'pmpro-emailsettings') { ?>current<?php } ?>"><?php _e('Email', 'paid-memberships-pro' );?></a> | </li>
|
|
|
|
|
|
|
|
|
269 |
<?php } ?>
|
270 |
|
271 |
<?php if(current_user_can('pmpro_advancedsettings')) { ?>
|
193 |
?>
|
194 |
<script>
|
195 |
jQuery(document).ready(function() {
|
196 |
+
jQuery.get('<?php echo admin_url( "/admin-ajax.php?action=pmpro_notifications" . $specific_notification ); ?>', function(data) {
|
197 |
if(data && data != 'NULL')
|
198 |
jQuery('#pmpro_notifications').html(data);
|
199 |
});
|
211 |
'pmpro-pagesettings',
|
212 |
'pmpro-paymentsettings',
|
213 |
'pmpro-emailsettings',
|
214 |
+
'pmpro-emailtemplates',
|
215 |
'pmpro-advancedsettings',
|
216 |
'pmpro-addons',
|
217 |
'pmpro-license'
|
235 |
<?php } ?>
|
236 |
|
237 |
<?php if(current_user_can('pmpro_membershiplevels')) { ?>
|
238 |
+
<a href="<?php echo admin_url('admin.php?page=pmpro-membershiplevels');?>" class="nav-tab<?php if( in_array( $view, array( 'pmpro-membershiplevels', 'pmpro-discountcodes', 'pmpro-pagesettings', 'pmpro-paymentsettings', 'pmpro-emailsettings', 'pmpro-emailtemplates', 'pmpro-advancedsettings' ) ) ) { ?> nav-tab-active<?php } ?>"><?php _e('Settings', 'paid-memberships-pro' );?></a>
|
239 |
<?php } ?>
|
240 |
|
241 |
<?php if(current_user_can('pmpro_addons')) { ?>
|
247 |
<?php } ?>
|
248 |
</nav>
|
249 |
|
250 |
+
<?php if( $view == 'pmpro-membershiplevels' || $view == 'pmpro-discountcodes' || $view == 'pmpro-pagesettings' || $view == 'pmpro-paymentsettings' || $view == 'pmpro-emailsettings' || $view == 'pmpro-emailtemplates' || $view == 'pmpro-advancedsettings' ) { ?>
|
251 |
<ul class="subsubsub">
|
252 |
<?php if(current_user_can('pmpro_membershiplevels')) { ?>
|
253 |
<li><a href="<?php echo admin_url('admin.php?page=pmpro-membershiplevels');?>" title="<?php _e('Membership Levels', 'paid-memberships-pro' );?>" class="<?php if($view == 'pmpro-membershiplevels') { ?>current<?php } ?>"><?php _e('Levels', 'paid-memberships-pro' );?></a> | </li>
|
266 |
<?php } ?>
|
267 |
|
268 |
<?php if(current_user_can('pmpro_emailsettings')) { ?>
|
269 |
+
<li><a href="<?php echo admin_url('admin.php?page=pmpro-emailsettings');?>" title="<?php _e('Email Settings', 'paid-memberships-pro' );?>" class="<?php if($view == 'pmpro-emailsettings') { ?>current<?php } ?>"><?php _e('Email Settings', 'paid-memberships-pro' );?></a> | </li>
|
270 |
+
<?php } ?>
|
271 |
+
|
272 |
+
<?php if(current_user_can('pmpro_emailtemplates')) { ?>
|
273 |
+
<li><a href="<?php echo admin_url('admin.php?page=pmpro-emailtemplates');?>" title="<?php _e('Email Templates', 'paid-memberships-pro' );?>" class="<?php if($view == 'pmpro-emailtemplates') { ?>current<?php } ?>"><?php _e('Email Templates', 'paid-memberships-pro' );?></a> | </li>
|
274 |
<?php } ?>
|
275 |
|
276 |
<?php if(current_user_can('pmpro_advancedsettings')) { ?>
|
adminpages/advancedsettings.php
CHANGED
@@ -38,6 +38,7 @@
|
|
38 |
|
39 |
// Checkout settings.
|
40 |
pmpro_setOption("tospage");
|
|
|
41 |
pmpro_setOption("recaptcha");
|
42 |
pmpro_setOption("recaptcha_version");
|
43 |
pmpro_setOption("recaptcha_publickey");
|
@@ -83,6 +84,7 @@
|
|
83 |
|
84 |
// Checkout settings.
|
85 |
$tospage = pmpro_getOption("tospage");
|
|
|
86 |
$recaptcha = pmpro_getOption("recaptcha");
|
87 |
$recaptcha_version = pmpro_getOption("recaptcha_version");
|
88 |
$recaptcha_publickey = pmpro_getOption("recaptcha_publickey");
|
@@ -236,6 +238,19 @@
|
|
236 |
<p class="description"><?php _e('If yes, create a WordPress page containing your TOS agreement and assign it using the dropdown above.', 'paid-memberships-pro' );?></p>
|
237 |
</td>
|
238 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
239 |
<tr>
|
240 |
<th scope="row" valign="top">
|
241 |
<label for="recaptcha"><?php _e('Use reCAPTCHA?', 'paid-memberships-pro' );?>:</label>
|
@@ -243,8 +258,8 @@
|
|
243 |
<td>
|
244 |
<select id="recaptcha" name="recaptcha" onchange="pmpro_updateRecaptchaTRs();">
|
245 |
<option value="0" <?php if(!$recaptcha) { ?>selected="selected"<?php } ?>><?php _e('No', 'paid-memberships-pro' );?></option>
|
246 |
-
|
247 |
-
<option value="2" <?php if($recaptcha
|
248 |
</select>
|
249 |
<p class="description"><?php _e('A free reCAPTCHA key is required.', 'paid-memberships-pro' );?> <a href="https://www.google.com/recaptcha/admin/create"><?php _e('Click here to signup for reCAPTCHA', 'paid-memberships-pro' );?></a>.</p>
|
250 |
</td>
|
@@ -355,7 +370,16 @@ if ( function_exists( 'pmpro_displayAds' ) && pmpro_displayAds() ) {
|
|
355 |
<label for="hideadslevels"><?php _e('Choose Levels to Hide Ads From', 'paid-memberships-pro' );?>:</label>
|
356 |
</th>
|
357 |
<td>
|
358 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
359 |
<?php
|
360 |
$hideadslevels = pmpro_getOption("hideadslevels");
|
361 |
if(!is_array($hideadslevels))
|
@@ -363,24 +387,18 @@ if ( function_exists( 'pmpro_displayAds' ) && pmpro_displayAds() ) {
|
|
363 |
|
364 |
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ";
|
365 |
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
|
|
366 |
foreach($levels as $level)
|
367 |
{
|
368 |
?>
|
369 |
-
<div class="
|
|
|
|
|
|
|
370 |
<?php
|
371 |
}
|
372 |
?>
|
373 |
</div>
|
374 |
-
<script>
|
375 |
-
jQuery('.checkbox_box input').click(function(event) {
|
376 |
-
event.stopPropagation()
|
377 |
-
});
|
378 |
-
|
379 |
-
jQuery('.checkbox_box div.clickable').click(function() {
|
380 |
-
var checkbox = jQuery(this).find(':checkbox');
|
381 |
-
checkbox.attr('checked', !checkbox.attr('checked'));
|
382 |
-
});
|
383 |
-
</script>
|
384 |
</td>
|
385 |
</tr>
|
386 |
<?php if(is_multisite()) { ?>
|
@@ -469,7 +487,7 @@ if ( function_exists( 'pmpro_displayAds' ) && pmpro_displayAds() ) {
|
|
469 |
?>
|
470 |
<tr>
|
471 |
<th scope="row" valign="top">
|
472 |
-
<label for="
|
473 |
</th>
|
474 |
<td>
|
475 |
<select id="uninstall" name="uninstall">
|
@@ -519,8 +537,7 @@ if ( function_exists( 'pmpro_displayAds' ) && pmpro_displayAds() ) {
|
|
519 |
}
|
520 |
pmpro_updateRecaptchaTRs();
|
521 |
</script>
|
522 |
-
</div> <!-- end pmpro_admin_section-other-settings -->
|
523 |
-
|
524 |
<p class="submit">
|
525 |
<input name="savesettings" type="submit" class="button button-primary" value="<?php _e('Save Settings', 'paid-memberships-pro' );?>" />
|
526 |
</p>
|
38 |
|
39 |
// Checkout settings.
|
40 |
pmpro_setOption("tospage");
|
41 |
+
pmpro_setOption("spamprotection");
|
42 |
pmpro_setOption("recaptcha");
|
43 |
pmpro_setOption("recaptcha_version");
|
44 |
pmpro_setOption("recaptcha_publickey");
|
84 |
|
85 |
// Checkout settings.
|
86 |
$tospage = pmpro_getOption("tospage");
|
87 |
+
$spamprotection = pmpro_getOption("spamprotection");
|
88 |
$recaptcha = pmpro_getOption("recaptcha");
|
89 |
$recaptcha_version = pmpro_getOption("recaptcha_version");
|
90 |
$recaptcha_publickey = pmpro_getOption("recaptcha_publickey");
|
238 |
<p class="description"><?php _e('If yes, create a WordPress page containing your TOS agreement and assign it using the dropdown above.', 'paid-memberships-pro' );?></p>
|
239 |
</td>
|
240 |
</tr>
|
241 |
+
<tr>
|
242 |
+
<th scope="row" valign="top">
|
243 |
+
<label for="spamprotection"><?php _e('Enable Spam Protection?', 'paid-memberships-pro' );?>:</label>
|
244 |
+
</th>
|
245 |
+
<td>
|
246 |
+
<select id="spamprotection" name="spamprotection">
|
247 |
+
<option value="0" <?php if(!$spamprotection) { ?>selected="selected"<?php } ?>><?php _e('No', 'paid-memberships-pro' );?></option>
|
248 |
+
<!-- For reference, removed the Yes - Free memberships only. option -->
|
249 |
+
<option value="2" <?php if( $spamprotection > 0 ) { ?>selected="selected"<?php } ?>><?php _e('Yes - Enable Spam Protection', 'paid-memberships-pro' );?></option>
|
250 |
+
</select>
|
251 |
+
<p class="description"><?php printf( __( 'Block IPs from checkout if there are more than %d failures within %d minutes.', 'paid-memberships-pro' ), PMPRO_SPAM_ACTION_NUM_LIMIT, round(PMPRO_SPAM_ACTION_TIME_LIMIT/60,2) );?></p>
|
252 |
+
</td>
|
253 |
+
</tr>
|
254 |
<tr>
|
255 |
<th scope="row" valign="top">
|
256 |
<label for="recaptcha"><?php _e('Use reCAPTCHA?', 'paid-memberships-pro' );?>:</label>
|
258 |
<td>
|
259 |
<select id="recaptcha" name="recaptcha" onchange="pmpro_updateRecaptchaTRs();">
|
260 |
<option value="0" <?php if(!$recaptcha) { ?>selected="selected"<?php } ?>><?php _e('No', 'paid-memberships-pro' );?></option>
|
261 |
+
<!-- For reference, removed the Yes - Free memberships only. option -->
|
262 |
+
<option value="2" <?php if( $recaptcha > 0 ) { ?>selected="selected"<?php } ?>><?php _e('Yes - All memberships.', 'paid-memberships-pro' );?></option>
|
263 |
</select>
|
264 |
<p class="description"><?php _e('A free reCAPTCHA key is required.', 'paid-memberships-pro' );?> <a href="https://www.google.com/recaptcha/admin/create"><?php _e('Click here to signup for reCAPTCHA', 'paid-memberships-pro' );?></a>.</p>
|
265 |
</td>
|
370 |
<label for="hideadslevels"><?php _e('Choose Levels to Hide Ads From', 'paid-memberships-pro' );?>:</label>
|
371 |
</th>
|
372 |
<td>
|
373 |
+
<?php
|
374 |
+
// Build the selectors for the checkbox list based on number of levels.
|
375 |
+
$classes = array();
|
376 |
+
$classes[] = "pmpro_checkbox_box";
|
377 |
+
if ( count( $levels ) > 5 ) {
|
378 |
+
$classes[] = "pmpro_scrollable";
|
379 |
+
}
|
380 |
+
$class = implode( ' ', array_unique( $classes ) );
|
381 |
+
?>
|
382 |
+
<div class="<?php echo esc_attr( $class ); ?>">
|
383 |
<?php
|
384 |
$hideadslevels = pmpro_getOption("hideadslevels");
|
385 |
if(!is_array($hideadslevels))
|
387 |
|
388 |
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ";
|
389 |
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
390 |
+
$levels = pmpro_sort_levels_by_order( $levels );
|
391 |
foreach($levels as $level)
|
392 |
{
|
393 |
?>
|
394 |
+
<div class="pmpro_clickable">
|
395 |
+
<input type="checkbox" id="hideadslevels_<?php echo esc_attr( $level->id ); ?>" name="hideadslevels[]" value="<?php echo esc_attr( $level->id); ?>" <?php checked( in_array( $level->id, $hideadslevels ), true ); ?>>
|
396 |
+
<label for="hideadslevels_<?php echo esc_attr( $level->id ); ?>"><?php echo esc_html( $level->name ); ?></label>
|
397 |
+
</div>
|
398 |
<?php
|
399 |
}
|
400 |
?>
|
401 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
402 |
</td>
|
403 |
</tr>
|
404 |
<?php if(is_multisite()) { ?>
|
487 |
?>
|
488 |
<tr>
|
489 |
<th scope="row" valign="top">
|
490 |
+
<label for="uninstall"><?php _e('Uninstall PMPro on deletion?', 'paid-memberships-pro' );?></label>
|
491 |
</th>
|
492 |
<td>
|
493 |
<select id="uninstall" name="uninstall">
|
537 |
}
|
538 |
pmpro_updateRecaptchaTRs();
|
539 |
</script>
|
540 |
+
</div> <!-- end pmpro_admin_section-other-settings -->
|
|
|
541 |
<p class="submit">
|
542 |
<input name="savesettings" type="submit" class="button button-primary" value="<?php _e('Save Settings', 'paid-memberships-pro' );?>" />
|
543 |
</p>
|
adminpages/dashboard.php
CHANGED
@@ -143,6 +143,10 @@ function pmpro_dashboard_welcome_callback() { ?>
|
|
143 |
<li><a href="<?php echo admin_url( 'admin.php?page=pmpro-emailsettings' );?>"><i class="dashicons dashicons-email"></i> <?php echo esc_attr_e( 'Confirm Email Settings', 'paid-memberships-pro' );?></a></li>
|
144 |
<?php } ?>
|
145 |
|
|
|
|
|
|
|
|
|
146 |
<?php if ( current_user_can( 'pmpro_advancedsettings' ) ) { ?>
|
147 |
<li><a href="<?php echo admin_url( 'admin.php?page=pmpro-advancedsettings' );?>"><i class="dashicons dashicons-admin-settings"></i> <?php echo esc_attr_e( 'View Advanced Settings', 'paid-memberships-pro' ); ?></a></li>
|
148 |
<?php } ?>
|
@@ -178,11 +182,11 @@ function pmpro_dashboard_welcome_callback() { ?>
|
|
178 |
<?php } ?>
|
179 |
|
180 |
<?php if ( ! pmpro_license_isValid() ) { ?>
|
181 |
-
|
182 |
-
|
183 |
<?php } ?>
|
184 |
-
|
185 |
-
|
186 |
</div> <!-- end pmpro-dashboard-welcome-column -->
|
187 |
<div class="pmpro-dashboard-welcome-column">
|
188 |
<h3><?php esc_html_e( 'Get Involved', 'paid-memberships-pro' ); ?></h3>
|
@@ -244,7 +248,7 @@ function pmpro_dashboard_report_recent_members_callback() {
|
|
244 |
</strong>
|
245 |
</td>
|
246 |
<td><?php esc_attr_e( $auser->membership ); ?></td>
|
247 |
-
<td><?php echo date_i18n( get_option( 'date_format' ), strtotime( $theuser->user_registered, current_time( 'timestamp' ) ) ); ?></td>
|
248 |
<td>
|
249 |
<?php
|
250 |
if($auser->enddate)
|
@@ -295,7 +299,7 @@ function pmpro_dashboard_report_recent_orders_callback() {
|
|
295 |
<?php
|
296 |
if ( empty( $order_ids ) ) { ?>
|
297 |
<tr>
|
298 |
-
<td colspan="
|
299 |
</tr>
|
300 |
<?php } else {
|
301 |
foreach ( $order_ids as $order_id ) {
|
@@ -333,7 +337,7 @@ function pmpro_dashboard_report_recent_orders_callback() {
|
|
333 |
<?php }
|
334 |
?>
|
335 |
</td>
|
336 |
-
<td><?php echo pmpro_formatPrice( $order->total ); ?></td>
|
337 |
<td>
|
338 |
<?php echo $order->gateway; ?>
|
339 |
<?php if ( $order->gateway_environment == 'test' ) {
|
143 |
<li><a href="<?php echo admin_url( 'admin.php?page=pmpro-emailsettings' );?>"><i class="dashicons dashicons-email"></i> <?php echo esc_attr_e( 'Confirm Email Settings', 'paid-memberships-pro' );?></a></li>
|
144 |
<?php } ?>
|
145 |
|
146 |
+
<?php if ( current_user_can( 'pmpro_emailtemplates' ) ) { ?>
|
147 |
+
<li><a href="<?php echo admin_url( 'admin.php?page=pmpro-emailtemplates' );?>"><i class="dashicons dashicons-editor-spellcheck"></i> <?php echo esc_attr_e( 'Customize Email Templates', 'paid-memberships-pro' );?></a></li>
|
148 |
+
<?php } ?>
|
149 |
+
|
150 |
<?php if ( current_user_can( 'pmpro_advancedsettings' ) ) { ?>
|
151 |
<li><a href="<?php echo admin_url( 'admin.php?page=pmpro-advancedsettings' );?>"><i class="dashicons dashicons-admin-settings"></i> <?php echo esc_attr_e( 'View Advanced Settings', 'paid-memberships-pro' ); ?></a></li>
|
152 |
<?php } ?>
|
182 |
<?php } ?>
|
183 |
|
184 |
<?php if ( ! pmpro_license_isValid() ) { ?>
|
185 |
+
<p><?php esc_html_e( 'An annual support license is recommended for websites running Paid Memberships Pro.', 'paid-memberships-pro' ); ?></p>
|
186 |
+
<p><a href="https://www.paidmembershipspro.com/pricing/?utm_source=plugin&utm_medium=pmpro-dashboard&utm_campaign=pricing&utm_content=upgrade" target="_blank" class="button button-primary button-hero"><?php esc_attr_e( 'View Plans and Pricing', 'paid-memberships-pro' ); ?></a>
|
187 |
<?php } ?>
|
188 |
+
<hr />
|
189 |
+
<p><?php echo wp_kses_post( sprintf( __( 'Paid Memberships Pro and our Add Ons are distributed under the <a target="_blank" href="%s">GPLv2 license</a>. This means, among other things, that you may use the software on this site or any other site free of charge.', 'paid-memberships-pro' ), 'http://www.gnu.org/licenses/gpl-2.0.html' ) ); ?></p>
|
190 |
</div> <!-- end pmpro-dashboard-welcome-column -->
|
191 |
<div class="pmpro-dashboard-welcome-column">
|
192 |
<h3><?php esc_html_e( 'Get Involved', 'paid-memberships-pro' ); ?></h3>
|
248 |
</strong>
|
249 |
</td>
|
250 |
<td><?php esc_attr_e( $auser->membership ); ?></td>
|
251 |
+
<td><?php echo date_i18n( get_option( 'date_format' ), strtotime( get_date_from_gmt( $theuser->user_registered ), current_time( 'timestamp' ) ) ); ?></td>
|
252 |
<td>
|
253 |
<?php
|
254 |
if($auser->enddate)
|
299 |
<?php
|
300 |
if ( empty( $order_ids ) ) { ?>
|
301 |
<tr>
|
302 |
+
<td colspan="6"><p><?php _e( 'No orders found.', 'paid-memberships-pro' ); ?></p></td>
|
303 |
</tr>
|
304 |
<?php } else {
|
305 |
foreach ( $order_ids as $order_id ) {
|
337 |
<?php }
|
338 |
?>
|
339 |
</td>
|
340 |
+
<td><?php echo pmpro_escape_price( pmpro_formatPrice( $order->total ) ); ?></td>
|
341 |
<td>
|
342 |
<?php echo $order->gateway; ?>
|
343 |
<?php if ( $order->gateway_environment == 'test' ) {
|
adminpages/discountcodes.php
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
}
|
7 |
|
8 |
//vars
|
9 |
-
global $wpdb, $pmpro_currency_symbol, $pmpro_stripe_error, $pmpro_braintree_error, $pmpro_payflow_error, $pmpro_twocheckout_error;
|
10 |
|
11 |
$now = current_time( 'timestamp' );
|
12 |
|
@@ -17,6 +17,8 @@
|
|
17 |
|
18 |
if(isset($_REQUEST['copy']))
|
19 |
$copy = intval($_REQUEST['copy']);
|
|
|
|
|
20 |
|
21 |
if(isset($_REQUEST['delete']))
|
22 |
$delete = intval($_REQUEST['delete']);
|
@@ -58,7 +60,7 @@
|
|
58 |
$start = $end - $limit;
|
59 |
|
60 |
//check nonce for saving codes
|
61 |
-
if (!empty($
|
62 |
$pmpro_msgt = 'error';
|
63 |
$pmpro_msg = __("Are you sure you want to do that? Try again.", 'paid-memberships-pro' );
|
64 |
$saveid = false;
|
@@ -306,7 +308,7 @@
|
|
306 |
}
|
307 |
|
308 |
//check nonce for deleting codes
|
309 |
-
if (!empty($
|
310 |
$pmpro_msgt = 'error';
|
311 |
$pmpro_msg = __("Are you sure you want to do that? Try again.", 'paid-memberships-pro' );
|
312 |
$delete = false;
|
@@ -353,10 +355,10 @@
|
|
353 |
$pmpro_msgt = "error";
|
354 |
}
|
355 |
}
|
356 |
-
|
357 |
if( ! empty( $pmpro_msg ) && ! empty( $expiration_warning_flag ) ) {
|
358 |
$pmpro_msg .= ' <strong>' . sprintf( __( 'WARNING: A level was set with both a recurring billing amount and an expiration date. You only need to set one of these unless you really want this membership to expire after a specific time period. For more information, <a target="_blank" href="%s">see our post here</a>.', 'paid-memberships-pro' ), 'https://www.paidmembershipspro.com/important-notes-on-recurring-billing-and-expiration-dates-for-membership-levels/?utm_source=plugin&utm_medium=pmpro-discountcodes&utm_campaign=blog&utm_content=important-notes-on-recurring-billing-and-expiration-dates-for-membership-levels' ) . '</strong>';
|
359 |
-
|
360 |
if( $pmpro_msgt == 'success' ) {
|
361 |
$pmpro_msgt = 'warning';
|
362 |
}
|
@@ -415,7 +417,7 @@
|
|
415 |
$copy ),
|
416 |
OBJECT
|
417 |
);
|
418 |
-
|
419 |
$temp_code = $code;
|
420 |
}
|
421 |
|
@@ -427,7 +429,7 @@
|
|
427 |
{
|
428 |
$code = new stdClass();
|
429 |
$code->code = pmpro_getDiscountCode();
|
430 |
-
|
431 |
if( ! empty( $copy ) && $copy > 0 ) {
|
432 |
$code->starts = $temp_code->starts;
|
433 |
$code->expires = $temp_code->expires;
|
@@ -436,18 +438,18 @@
|
|
436 |
}
|
437 |
?>
|
438 |
<form action="" method="post">
|
439 |
-
<input name="saveid" type="hidden" value="<?php echo $edit?>" />
|
440 |
<?php wp_nonce_field('save', 'pmpro_discountcodes_nonce');?>
|
441 |
<table class="form-table">
|
442 |
<tbody>
|
443 |
<tr>
|
444 |
<th scope="row" valign="top"><label><?php _e('ID', 'paid-memberships-pro' );?>:</label></th>
|
445 |
-
<td><p class="description"><?php if(!empty($code->id)) echo $code->id; else echo __("This will be generated when you save.", 'paid-memberships-pro' );?></p></td>
|
446 |
</tr>
|
447 |
|
448 |
<tr>
|
449 |
<th scope="row" valign="top"><label for="code"><?php _e('Code', 'paid-memberships-pro' );?>:</label></th>
|
450 |
-
<td><input name="code" type="text" size="20" value="<?php echo
|
451 |
</tr>
|
452 |
|
453 |
<?php
|
@@ -496,8 +498,8 @@
|
|
496 |
}
|
497 |
?>
|
498 |
</select>
|
499 |
-
<input name="starts_day" type="text" size="2" value="<?php echo $selected_starts_day?>" />
|
500 |
-
<input name="starts_year" type="text" size="4" value="<?php echo $selected_starts_year?>" />
|
501 |
</td>
|
502 |
</tr>
|
503 |
|
@@ -514,15 +516,15 @@
|
|
514 |
}
|
515 |
?>
|
516 |
</select>
|
517 |
-
<input name="expires_day" type="text" size="2" value="<?php echo $selected_expires_day?>" />
|
518 |
-
<input name="expires_year" type="text" size="4" value="<?php echo $selected_expires_year?>" />
|
519 |
</td>
|
520 |
</tr>
|
521 |
|
522 |
<tr>
|
523 |
<th scope="row" valign="top"><label for="uses"><?php _e('Uses', 'paid-memberships-pro' );?>:</label></th>
|
524 |
<td>
|
525 |
-
<input name="uses" type="text" size="10" value="<?php if(!empty($code->uses)) echo
|
526 |
<p class="description"><?php _e('Leave blank for unlimited uses.', 'paid-memberships-pro' );?></p>
|
527 |
</td>
|
528 |
</tr>
|
@@ -537,6 +539,7 @@
|
|
537 |
<div class="pmpro_discount_levels">
|
538 |
<?php
|
539 |
$levels = $wpdb->get_results("SELECT * FROM $wpdb->pmpro_membership_levels");
|
|
|
540 |
foreach($levels as $level)
|
541 |
{
|
542 |
//if this level is already managed for this discount code, use the code values
|
@@ -563,10 +566,10 @@
|
|
563 |
$level_checked = false;
|
564 |
?>
|
565 |
<div class="pmpro_discount_level <?php if ( ! pmpro_check_discount_code_level_for_gateway_compatibility( $level ) ) { ?>pmpro_error<?php } ?>">
|
566 |
-
<input type="hidden" name="all_levels[]" value="<?php echo $level->id?>" />
|
567 |
-
<input type="checkbox" id="levels_<?php echo $level->id
|
568 |
-
<label for="levels_<?php echo $level->id
|
569 |
-
<div class="pmpro_discount_levels_pricing level_<?php echo $level->id?>" <?php if(empty($level->checked)) { ?>style="display: none;"<?php } ?>>
|
570 |
<table class="form-table">
|
571 |
<tbody>
|
572 |
<tr>
|
@@ -587,7 +590,7 @@
|
|
587 |
|
588 |
<tr>
|
589 |
<th scope="row" valign="top"><label><?php _e('Recurring Subscription', 'paid-memberships-pro' );?>:</label></th>
|
590 |
-
<td><input class="recurring_checkbox" id="recurring_<?php echo $level->id;?>" name="recurring[]" type="checkbox" value="<?php echo $level->id?>" <?php if(pmpro_isLevelRecurring($level)) { echo "checked='checked'"; } ?> onclick="if(jQuery(this).prop('checked')) { jQuery(this).parent().parent().siblings('.recurring_info').show(); if(!jQuery('#custom_trial_<?php echo $level->id?>').is(':checked')) jQuery(this).parent().parent().siblings('.trial_info').hide();} else jQuery(this).parent().parent().siblings('.recurring_info').hide();" /> <label for="recurring_<?php echo $level->id
|
591 |
</tr>
|
592 |
|
593 |
<tr class="recurring_info" <?php if(!pmpro_isLevelRecurring($level)) {?>style="display: none;"<?php } ?>>
|
@@ -603,7 +606,7 @@
|
|
603 |
echo $pmpro_currency_symbol;
|
604 |
?>
|
605 |
<?php _e('per', 'paid-memberships-pro' ); ?>
|
606 |
-
<input name="cycle_number[]" type="text" size="10" value="<?php echo
|
607 |
<select name="cycle_period[]">
|
608 |
<?php
|
609 |
$cycles = array( __('Day(s)', 'paid-memberships-pro' ) => 'Day', __('Week(s)', 'paid-memberships-pro' ) => 'Week', __('Month(s)', 'paid-memberships-pro' ) => 'Month', __('Year(s)', 'paid-memberships-pro' ) => 'Year' );
|
@@ -617,14 +620,16 @@
|
|
617 |
<p class="description"><?php _e('The amount to be billed one cycle after the initial payment.', 'paid-memberships-pro' );?></p>
|
618 |
<?php if($gateway == "braintree") { ?>
|
619 |
<strong <?php if(!empty($pmpro_braintree_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Braintree integration currently only supports billing periods of "Month" or "Year".', 'paid-memberships-pro' );?></strong>
|
620 |
-
<?php } ?>
|
|
|
|
|
621 |
</td>
|
622 |
</tr>
|
623 |
|
624 |
<tr class="recurring_info" <?php if(!pmpro_isLevelRecurring($level)) {?>style="display: none;"<?php } ?>>
|
625 |
<th scope="row" valign="top"><label for="billing_limit"><?php _e('Billing Cycle Limit', 'paid-memberships-pro' );?>:</label></th>
|
626 |
<td>
|
627 |
-
<input name="billing_limit[]" type="text" size="20" value="<?php echo $level->billing_limit?>" />
|
628 |
<p class="description">
|
629 |
<?php _e('The <strong>total</strong> number of recurring billing cycles for this level, including the trial period (if applicable) but not including the initial payment. Set to zero if membership is indefinite.', 'paid-memberships-pro' );?>
|
630 |
<?php if ( ( $gateway == "stripe" ) && ! function_exists( 'pmprosbl_plugin_row_meta' ) ) { ?>
|
@@ -647,7 +652,7 @@
|
|
647 |
<tr class="recurring_info" <?php if (!pmpro_isLevelRecurring($level)) echo "style='display:none;'";?>>
|
648 |
<th scope="row" valign="top"><label><?php _e('Custom Trial', 'paid-memberships-pro' );?>:</label></th>
|
649 |
<td>
|
650 |
-
<input id="custom_trial_<?php echo $level->id?>" id="custom_trial_<?php echo $level->id
|
651 |
<?php if($gateway == "twocheckout") { ?>
|
652 |
<p class="description"><strong <?php if(!empty($pmpro_twocheckout_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('2Checkout integration does not support custom trials. You can do one period trials by setting an initial payment different from the billing amount.', 'paid-memberships-pro' );?></strong></p>
|
653 |
<?php } ?>
|
@@ -667,7 +672,7 @@
|
|
667 |
echo $pmpro_currency_symbol;
|
668 |
?>
|
669 |
<?php _e('for the first', 'paid-memberships-pro' );?>
|
670 |
-
<input name="trial_limit[]" type="text" size="10" value="<?php echo
|
671 |
<?php _e('subscription payments', 'paid-memberships-pro' );?>.
|
672 |
<?php if($gateway == "stripe") { ?>
|
673 |
<p class="description"><strong <?php if(!empty($pmpro_stripe_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Stripe integration currently does not support trial amounts greater than $0.', 'paid-memberships-pro' );?></strong></p>
|
@@ -681,17 +686,19 @@
|
|
681 |
|
682 |
<tr>
|
683 |
<th scope="row" valign="top"><label><?php _e('Membership Expiration', 'paid-memberships-pro' );?>:</label></th>
|
684 |
-
<td><input id="expiration_<?php echo $level->id
|
685 |
</tr>
|
686 |
|
687 |
<tr class="expiration_info" <?php if(!pmpro_isLevelExpiring($level)) {?>style="display: none;"<?php } ?>>
|
688 |
<th scope="row" valign="top"><label for="billing_amount"><?php _e('Expires In', 'paid-memberships-pro' );?>:</label></th>
|
689 |
<td>
|
690 |
-
<input id="expiration_number" name="expiration_number[]" type="text" size="10" value="<?php echo
|
691 |
<select id="expiration_period" name="expiration_period[]">
|
692 |
<?php
|
693 |
-
|
|
|
694 |
foreach ( $cycles as $name => $value ) {
|
|
|
695 |
echo "<option value='$value'";
|
696 |
if ( $level->expiration_period == $value ) echo " selected='selected'";
|
697 |
echo ">$name</option>";
|
@@ -719,7 +726,7 @@
|
|
719 |
|
720 |
<p class="submit topborder">
|
721 |
<input name="save" type="submit" class="button button-primary" value="Save Code" />
|
722 |
-
<input name="cancel" type="button" class="button" value="Cancel" onclick="location.href='<?php echo
|
723 |
</p>
|
724 |
</form>
|
725 |
</div>
|
@@ -765,8 +772,8 @@
|
|
765 |
<p class="search-box">
|
766 |
<label class="screen-reader-text" for="post-search-input"><?php _e('Search Discount Codes', 'paid-memberships-pro' );?>:</label>
|
767 |
<input type="hidden" name="page" value="pmpro-discountcodes" />
|
768 |
-
<input id="post-search-input" type="text" value="<?php
|
769 |
-
<input class="button" type="submit" value="<?php
|
770 |
</p>
|
771 |
</form>
|
772 |
|
@@ -790,7 +797,7 @@
|
|
790 |
<td colspan="6">
|
791 |
<?php echo esc_attr_e( 'Code not found.', 'paid-memberships-pro' ); ?>
|
792 |
</td>
|
793 |
-
</tr>
|
794 |
<?php } ?>
|
795 |
<?php
|
796 |
foreach($codes as $code) {
|
@@ -799,22 +806,109 @@
|
|
799 |
<tr<?php if ( ! pmpro_check_discount_code_for_gateway_compatibility( $code->id ) ) { ?> class="pmpro_error"<?php } ?>>
|
800 |
<td><?php echo $code->id?></td>
|
801 |
<td class="has-row-actions">
|
802 |
-
<a title="<?php echo sprintf( 'Edit Code: %s', $code->code ); ?>" href="<?php echo add_query_arg( array( 'page' => 'pmpro-discountcodes', 'edit' => $code->id ), admin_url('admin.php' ) ); ?>"><?php echo $code->code?></a>
|
803 |
<div class="row-actions">
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
818 |
</div>
|
819 |
</td>
|
820 |
<td>
|
@@ -845,7 +939,11 @@
|
|
845 |
|
846 |
$level_names = array();
|
847 |
foreach( $levels as $level ) {
|
848 |
-
|
|
|
|
|
|
|
|
|
849 |
}
|
850 |
if( $level_names ) {
|
851 |
echo implode( ', ', $level_names );
|
@@ -864,7 +962,7 @@
|
|
864 |
</table>
|
865 |
|
866 |
<?php
|
867 |
-
$pagination_url =
|
868 |
echo pmpro_getPaginationString( $pn, $totalrows, $limit, 1, $pagination_url, "&limit=$limit&pn=" );
|
869 |
?>
|
870 |
|
6 |
}
|
7 |
|
8 |
//vars
|
9 |
+
global $wpdb, $pmpro_currency_symbol, $pmpro_stripe_error, $pmpro_braintree_error, $pmpro_payflow_error, $pmpro_twocheckout_error, $pmpro_pages, $gateway;
|
10 |
|
11 |
$now = current_time( 'timestamp' );
|
12 |
|
17 |
|
18 |
if(isset($_REQUEST['copy']))
|
19 |
$copy = intval($_REQUEST['copy']);
|
20 |
+
else
|
21 |
+
$copy = false;
|
22 |
|
23 |
if(isset($_REQUEST['delete']))
|
24 |
$delete = intval($_REQUEST['delete']);
|
60 |
$start = $end - $limit;
|
61 |
|
62 |
//check nonce for saving codes
|
63 |
+
if (!empty($saveid) && (empty($_REQUEST['pmpro_discountcodes_nonce']) || !check_admin_referer('save', 'pmpro_discountcodes_nonce'))) {
|
64 |
$pmpro_msgt = 'error';
|
65 |
$pmpro_msg = __("Are you sure you want to do that? Try again.", 'paid-memberships-pro' );
|
66 |
$saveid = false;
|
308 |
}
|
309 |
|
310 |
//check nonce for deleting codes
|
311 |
+
if (!empty($delete) && (empty($_REQUEST['pmpro_discountcodes_nonce']) || !check_admin_referer('delete', 'pmpro_discountcodes_nonce'))) {
|
312 |
$pmpro_msgt = 'error';
|
313 |
$pmpro_msg = __("Are you sure you want to do that? Try again.", 'paid-memberships-pro' );
|
314 |
$delete = false;
|
355 |
$pmpro_msgt = "error";
|
356 |
}
|
357 |
}
|
358 |
+
|
359 |
if( ! empty( $pmpro_msg ) && ! empty( $expiration_warning_flag ) ) {
|
360 |
$pmpro_msg .= ' <strong>' . sprintf( __( 'WARNING: A level was set with both a recurring billing amount and an expiration date. You only need to set one of these unless you really want this membership to expire after a specific time period. For more information, <a target="_blank" href="%s">see our post here</a>.', 'paid-memberships-pro' ), 'https://www.paidmembershipspro.com/important-notes-on-recurring-billing-and-expiration-dates-for-membership-levels/?utm_source=plugin&utm_medium=pmpro-discountcodes&utm_campaign=blog&utm_content=important-notes-on-recurring-billing-and-expiration-dates-for-membership-levels' ) . '</strong>';
|
361 |
+
|
362 |
if( $pmpro_msgt == 'success' ) {
|
363 |
$pmpro_msgt = 'warning';
|
364 |
}
|
417 |
$copy ),
|
418 |
OBJECT
|
419 |
);
|
420 |
+
|
421 |
$temp_code = $code;
|
422 |
}
|
423 |
|
429 |
{
|
430 |
$code = new stdClass();
|
431 |
$code->code = pmpro_getDiscountCode();
|
432 |
+
|
433 |
if( ! empty( $copy ) && $copy > 0 ) {
|
434 |
$code->starts = $temp_code->starts;
|
435 |
$code->expires = $temp_code->expires;
|
438 |
}
|
439 |
?>
|
440 |
<form action="" method="post">
|
441 |
+
<input name="saveid" type="hidden" value="<?php echo esc_attr( $edit ); ?>" />
|
442 |
<?php wp_nonce_field('save', 'pmpro_discountcodes_nonce');?>
|
443 |
<table class="form-table">
|
444 |
<tbody>
|
445 |
<tr>
|
446 |
<th scope="row" valign="top"><label><?php _e('ID', 'paid-memberships-pro' );?>:</label></th>
|
447 |
+
<td><p class="description"><?php if(!empty($code->id)) echo esc_html( $code->id ); else echo __("This will be generated when you save.", 'paid-memberships-pro' );?></p></td>
|
448 |
</tr>
|
449 |
|
450 |
<tr>
|
451 |
<th scope="row" valign="top"><label for="code"><?php _e('Code', 'paid-memberships-pro' );?>:</label></th>
|
452 |
+
<td><input name="code" type="text" size="20" value="<?php echo esc_attr( $code->code ); ?>" /></td>
|
453 |
</tr>
|
454 |
|
455 |
<?php
|
498 |
}
|
499 |
?>
|
500 |
</select>
|
501 |
+
<input name="starts_day" type="text" size="2" value="<?php echo esc_attr( $selected_starts_day ); ?>" />
|
502 |
+
<input name="starts_year" type="text" size="4" value="<?php echo esc_attr( $selected_starts_year ); ?>" />
|
503 |
</td>
|
504 |
</tr>
|
505 |
|
516 |
}
|
517 |
?>
|
518 |
</select>
|
519 |
+
<input name="expires_day" type="text" size="2" value="<?php echo esc_attr( $selected_expires_day ); ?>" />
|
520 |
+
<input name="expires_year" type="text" size="4" value="<?php echo esc_attr( $selected_expires_year ); ?>" />
|
521 |
</td>
|
522 |
</tr>
|
523 |
|
524 |
<tr>
|
525 |
<th scope="row" valign="top"><label for="uses"><?php _e('Uses', 'paid-memberships-pro' );?>:</label></th>
|
526 |
<td>
|
527 |
+
<input name="uses" type="text" size="10" value="<?php if ( ! empty( $code->uses ) ) echo esc_attr( $code->uses ); ?>" />
|
528 |
<p class="description"><?php _e('Leave blank for unlimited uses.', 'paid-memberships-pro' );?></p>
|
529 |
</td>
|
530 |
</tr>
|
539 |
<div class="pmpro_discount_levels">
|
540 |
<?php
|
541 |
$levels = $wpdb->get_results("SELECT * FROM $wpdb->pmpro_membership_levels");
|
542 |
+
$levels = pmpro_sort_levels_by_order( $levels );
|
543 |
foreach($levels as $level)
|
544 |
{
|
545 |
//if this level is already managed for this discount code, use the code values
|
566 |
$level_checked = false;
|
567 |
?>
|
568 |
<div class="pmpro_discount_level <?php if ( ! pmpro_check_discount_code_level_for_gateway_compatibility( $level ) ) { ?>pmpro_error<?php } ?>">
|
569 |
+
<input type="hidden" name="all_levels[]" value="<?php echo esc_attr( $level->id ); ?>" />
|
570 |
+
<input type="checkbox" id="levels_<?php echo esc_attr( $level->id ); ?>" name="levels[]" value="<?php echo esc_attr( $level->id ); ?>" <?php if(!empty($level->checked)) { ?>checked="checked"<?php } ?> onclick="if(jQuery(this).is(':checked')) jQuery(this).next().next().show(); else jQuery(this).next().next().hide();" />
|
571 |
+
<label for="levels_<?php echo esc_attr( $level->id ); ?>"><?php echo $level->name?></label>
|
572 |
+
<div class="pmpro_discount_levels_pricing level_<?php echo esc_attr( $level->id ); ?>" <?php if(empty($level->checked)) { ?>style="display: none;"<?php } ?>>
|
573 |
<table class="form-table">
|
574 |
<tbody>
|
575 |
<tr>
|
590 |
|
591 |
<tr>
|
592 |
<th scope="row" valign="top"><label><?php _e('Recurring Subscription', 'paid-memberships-pro' );?>:</label></th>
|
593 |
+
<td><input class="recurring_checkbox" id="recurring_<?php echo esc_attr( $level->id );?>" name="recurring[]" type="checkbox" value="<?php echo esc_attr( $level->id ); ?>" <?php if(pmpro_isLevelRecurring($level)) { echo "checked='checked'"; } ?> onclick="if(jQuery(this).prop('checked')) { jQuery(this).parent().parent().siblings('.recurring_info').show(); if(!jQuery('#custom_trial_<?php echo esc_attr( $level->id ); ?>').is(':checked')) jQuery(this).parent().parent().siblings('.trial_info').hide();} else jQuery(this).parent().parent().siblings('.recurring_info').hide();" /> <label for="recurring_<?php echo esc_attr( $level->id ); ?>"><?php _e('Check if this level has a recurring subscription payment.', 'paid-memberships-pro' );?></label></td>
|
594 |
</tr>
|
595 |
|
596 |
<tr class="recurring_info" <?php if(!pmpro_isLevelRecurring($level)) {?>style="display: none;"<?php } ?>>
|
606 |
echo $pmpro_currency_symbol;
|
607 |
?>
|
608 |
<?php _e('per', 'paid-memberships-pro' ); ?>
|
609 |
+
<input name="cycle_number[]" type="text" size="10" value="<?php echo esc_attr( $level->cycle_number ); ?>" />
|
610 |
<select name="cycle_period[]">
|
611 |
<?php
|
612 |
$cycles = array( __('Day(s)', 'paid-memberships-pro' ) => 'Day', __('Week(s)', 'paid-memberships-pro' ) => 'Week', __('Month(s)', 'paid-memberships-pro' ) => 'Month', __('Year(s)', 'paid-memberships-pro' ) => 'Year' );
|
620 |
<p class="description"><?php _e('The amount to be billed one cycle after the initial payment.', 'paid-memberships-pro' );?></p>
|
621 |
<?php if($gateway == "braintree") { ?>
|
622 |
<strong <?php if(!empty($pmpro_braintree_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Braintree integration currently only supports billing periods of "Month" or "Year".', 'paid-memberships-pro' );?></strong>
|
623 |
+
<?php } elseif($gateway == "stripe") { ?>
|
624 |
+
<p class="description"><strong <?php if(!empty($pmpro_stripe_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Stripe integration does not allow billing periods longer than 1 year.', 'paid-memberships-pro' );?></strong></p>
|
625 |
+
<?php }?>
|
626 |
</td>
|
627 |
</tr>
|
628 |
|
629 |
<tr class="recurring_info" <?php if(!pmpro_isLevelRecurring($level)) {?>style="display: none;"<?php } ?>>
|
630 |
<th scope="row" valign="top"><label for="billing_limit"><?php _e('Billing Cycle Limit', 'paid-memberships-pro' );?>:</label></th>
|
631 |
<td>
|
632 |
+
<input name="billing_limit[]" type="text" size="20" value="<?php echo esc_attr( $level->billing_limit ); ?>" />
|
633 |
<p class="description">
|
634 |
<?php _e('The <strong>total</strong> number of recurring billing cycles for this level, including the trial period (if applicable) but not including the initial payment. Set to zero if membership is indefinite.', 'paid-memberships-pro' );?>
|
635 |
<?php if ( ( $gateway == "stripe" ) && ! function_exists( 'pmprosbl_plugin_row_meta' ) ) { ?>
|
652 |
<tr class="recurring_info" <?php if (!pmpro_isLevelRecurring($level)) echo "style='display:none;'";?>>
|
653 |
<th scope="row" valign="top"><label><?php _e('Custom Trial', 'paid-memberships-pro' );?>:</label></th>
|
654 |
<td>
|
655 |
+
<input id="custom_trial_<?php echo esc_attr( $level->id ); ?>" id="custom_trial_<?php echo esc_attr( $level->id ); ?>" name="custom_trial[]" type="checkbox" value="<?php echo esc_attr( $level->id ); ?>" <?php if ( pmpro_isLevelTrial($level) ) { echo "checked='checked'"; } ?> onclick="if(jQuery(this).prop('checked')) jQuery(this).parent().parent().siblings('.trial_info').show(); else jQuery(this).parent().parent().siblings('.trial_info').hide();" /> <label for="custom_trial_<?php echo esc_attr( $level->id );?>"><?php _e('Check to add a custom trial period.', 'paid-memberships-pro' );?></label>
|
656 |
<?php if($gateway == "twocheckout") { ?>
|
657 |
<p class="description"><strong <?php if(!empty($pmpro_twocheckout_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('2Checkout integration does not support custom trials. You can do one period trials by setting an initial payment different from the billing amount.', 'paid-memberships-pro' );?></strong></p>
|
658 |
<?php } ?>
|
672 |
echo $pmpro_currency_symbol;
|
673 |
?>
|
674 |
<?php _e('for the first', 'paid-memberships-pro' );?>
|
675 |
+
<input name="trial_limit[]" type="text" size="10" value="<?php echo esc_attr( $level->trial_limit ); ?>" />
|
676 |
<?php _e('subscription payments', 'paid-memberships-pro' );?>.
|
677 |
<?php if($gateway == "stripe") { ?>
|
678 |
<p class="description"><strong <?php if(!empty($pmpro_stripe_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Stripe integration currently does not support trial amounts greater than $0.', 'paid-memberships-pro' );?></strong></p>
|
686 |
|
687 |
<tr>
|
688 |
<th scope="row" valign="top"><label><?php _e('Membership Expiration', 'paid-memberships-pro' );?>:</label></th>
|
689 |
+
<td><input id="expiration_<?php echo esc_attr( $level->id ); ?>" name="expiration[]" type="checkbox" value="<?php echo esc_attr( $level->id ); ?>" <?php if(pmpro_isLevelExpiring($level)) { echo "checked='checked'"; } ?> onclick="if(jQuery(this).is(':checked')) { jQuery(this).parent().parent().siblings('.expiration_info').show(); } else { jQuery(this).parent().parent().siblings('.expiration_info').hide();}" /> <label for="expiration_<?php echo esc_attr( $level->id ); ?>"><?php _e('Check this to set when membership access expires.', 'paid-memberships-pro' );?></label></td>
|
690 |
</tr>
|
691 |
|
692 |
<tr class="expiration_info" <?php if(!pmpro_isLevelExpiring($level)) {?>style="display: none;"<?php } ?>>
|
693 |
<th scope="row" valign="top"><label for="billing_amount"><?php _e('Expires In', 'paid-memberships-pro' );?>:</label></th>
|
694 |
<td>
|
695 |
+
<input id="expiration_number" name="expiration_number[]" type="text" size="10" value="<?php echo esc_attr( $level->expiration_number ); ?>" />
|
696 |
<select id="expiration_period" name="expiration_period[]">
|
697 |
<?php
|
698 |
+
|
699 |
+
$cycles = array( __('Hour(s)', 'paid-memberships-pro' ) => 'Hour', __('Day(s)', 'paid-memberships-pro' ) => 'Day', __('Week(s)', 'paid-memberships-pro' ) => 'Week', __('Month(s)', 'paid-memberships-pro' ) => 'Month', __('Year(s)', 'paid-memberships-pro' ) => 'Year' );
|
700 |
foreach ( $cycles as $name => $value ) {
|
701 |
+
|
702 |
echo "<option value='$value'";
|
703 |
if ( $level->expiration_period == $value ) echo " selected='selected'";
|
704 |
echo ">$name</option>";
|
726 |
|
727 |
<p class="submit topborder">
|
728 |
<input name="save" type="submit" class="button button-primary" value="Save Code" />
|
729 |
+
<input name="cancel" type="button" class="button" value="Cancel" onclick="location.href='<?php echo admin_url( '/admin.php?page=pmpro-discountcodes')?>';" />
|
730 |
</p>
|
731 |
</form>
|
732 |
</div>
|
772 |
<p class="search-box">
|
773 |
<label class="screen-reader-text" for="post-search-input"><?php _e('Search Discount Codes', 'paid-memberships-pro' );?>:</label>
|
774 |
<input type="hidden" name="page" value="pmpro-discountcodes" />
|
775 |
+
<input id="post-search-input" type="text" value="<?php echo esc_attr( wp_unslash( $s ) ); ?>" name="s" size="30" />
|
776 |
+
<input class="button" type="submit" value="<?php esc_attr_e('Search', 'paid-memberships-pro' );?>" id="search-submit "/>
|
777 |
</p>
|
778 |
</form>
|
779 |
|
797 |
<td colspan="6">
|
798 |
<?php echo esc_attr_e( 'Code not found.', 'paid-memberships-pro' ); ?>
|
799 |
</td>
|
800 |
+
</tr>
|
801 |
<?php } ?>
|
802 |
<?php
|
803 |
foreach($codes as $code) {
|
806 |
<tr<?php if ( ! pmpro_check_discount_code_for_gateway_compatibility( $code->id ) ) { ?> class="pmpro_error"<?php } ?>>
|
807 |
<td><?php echo $code->id?></td>
|
808 |
<td class="has-row-actions">
|
809 |
+
<a title="<?php echo esc_attr( sprintf( __( 'Edit Code: %s', 'paid-memberships-pro' ), $code->code ) ); ?>" href="<?php echo esc_url( add_query_arg( array( 'page' => 'pmpro-discountcodes', 'edit' => $code->id ), admin_url('admin.php' ) ) ); ?>"><?php echo $code->code?></a>
|
810 |
<div class="row-actions">
|
811 |
+
<?php
|
812 |
+
$delete_text = esc_html(
|
813 |
+
sprintf(
|
814 |
+
// translators: %s is the Discount Code.
|
815 |
+
__( 'Are you sure you want to delete the %s discount code? The subscriptions for existing users will not change, but new users will not be able to use this code anymore.', 'paid-memberships-pro' ),
|
816 |
+
$code->code
|
817 |
+
)
|
818 |
+
);
|
819 |
+
|
820 |
+
$delete_nonce_url = wp_nonce_url(
|
821 |
+
add_query_arg(
|
822 |
+
[
|
823 |
+
'page' => 'pmpro-discountcodes',
|
824 |
+
'delete' => $code->id,
|
825 |
+
],
|
826 |
+
admin_url( 'admin.php' )
|
827 |
+
),
|
828 |
+
'delete',
|
829 |
+
'pmpro_discountcodes_nonce'
|
830 |
+
);
|
831 |
+
|
832 |
+
$actions = [
|
833 |
+
'edit' => sprintf(
|
834 |
+
'<a title="%1$s" href="%2$s">%3$s</a>',
|
835 |
+
esc_attr__( 'Edit', 'paid-memberships-pro' ),
|
836 |
+
esc_url(
|
837 |
+
add_query_arg(
|
838 |
+
[
|
839 |
+
'page' => 'pmpro-discountcodes',
|
840 |
+
'edit' => $code->id,
|
841 |
+
],
|
842 |
+
admin_url( 'admin.php' )
|
843 |
+
)
|
844 |
+
),
|
845 |
+
esc_html__( 'Edit', 'paid-memberships-pro' )
|
846 |
+
),
|
847 |
+
'copy' => sprintf(
|
848 |
+
'<a title="%1$s" href="%2$s">%3$s</a>',
|
849 |
+
esc_attr__( 'Copy', 'paid-memberships-pro' ),
|
850 |
+
esc_url(
|
851 |
+
add_query_arg(
|
852 |
+
[
|
853 |
+
'page' => 'pmpro-discountcodes',
|
854 |
+
'edit' => - 1,
|
855 |
+
'copy' => $code->id,
|
856 |
+
],
|
857 |
+
admin_url( 'admin.php' )
|
858 |
+
)
|
859 |
+
),
|
860 |
+
esc_html__( 'Copy', 'paid-memberships-pro' )
|
861 |
+
),
|
862 |
+
'delete' => sprintf(
|
863 |
+
'<a title="%1$s" href="%2$s">%3$s</a>',
|
864 |
+
esc_attr__( 'Delete', 'paid-memberships-pro' ),
|
865 |
+
'javascript:pmpro_askfirst(\'' . esc_js( $delete_text ) . '\', \'' . esc_js( $delete_nonce_url ) . '\'); void(0);',
|
866 |
+
esc_html__( 'Delete', 'paid-memberships-pro' )
|
867 |
+
),
|
868 |
+
];
|
869 |
+
|
870 |
+
if ( 0 < (int) $uses ) {
|
871 |
+
$actions['orders'] = sprintf(
|
872 |
+
'<a title="%1$s" href="%2$s">%3$s</a>',
|
873 |
+
esc_attr__( 'View Orders', 'paid-memberships-pro' ),
|
874 |
+
esc_url(
|
875 |
+
add_query_arg(
|
876 |
+
[
|
877 |
+
'page' => 'pmpro-orders',
|
878 |
+
'discount-code' => $code->id,
|
879 |
+
'filter' => 'with-discount-code',
|
880 |
+
],
|
881 |
+
admin_url( 'admin.php' )
|
882 |
+
)
|
883 |
+
),
|
884 |
+
esc_html__( 'Orders', 'paid-memberships-pro' )
|
885 |
+
);
|
886 |
+
}
|
887 |
+
|
888 |
+
/**
|
889 |
+
* Filter the extra actions for this discount code.
|
890 |
+
*
|
891 |
+
* @since 2.6.2
|
892 |
+
*
|
893 |
+
* @param array $actions The list of actions.
|
894 |
+
* @param object $code The discount code data.
|
895 |
+
*/
|
896 |
+
$actions = apply_filters( 'pmpro_discountcodes_row_actions', $actions, $code );
|
897 |
+
|
898 |
+
$actions_html = [];
|
899 |
+
|
900 |
+
foreach ( $actions as $action => $link ) {
|
901 |
+
$actions_html[] = sprintf(
|
902 |
+
'<span class="%1$s">%2$s</span>',
|
903 |
+
esc_attr( $action ),
|
904 |
+
$link
|
905 |
+
);
|
906 |
+
}
|
907 |
+
|
908 |
+
if ( ! empty( $actions_html ) ) {
|
909 |
+
echo implode( ' | ', $actions_html );
|
910 |
+
}
|
911 |
+
?>
|
912 |
</div>
|
913 |
</td>
|
914 |
<td>
|
939 |
|
940 |
$level_names = array();
|
941 |
foreach( $levels as $level ) {
|
942 |
+
if ( ! empty( $pmpro_pages['checkout'] ) ) {
|
943 |
+
$level_names[] = '<a title="' . pmpro_url( 'checkout', '?level=' . $level->id . '&discount_code=' . $code->code) . '" target="_blank" href="' . pmpro_url( 'checkout', '?level=' . $level->id . '&discount_code=' . $code->code) . '">' . $level->name . '</a>';
|
944 |
+
} else {
|
945 |
+
$level_names[] = $level->name;
|
946 |
+
}
|
947 |
}
|
948 |
if( $level_names ) {
|
949 |
echo implode( ', ', $level_names );
|
962 |
</table>
|
963 |
|
964 |
<?php
|
965 |
+
$pagination_url = admin_url( "/admin.php?page=pmpro-discountcodes&s=" . $s );
|
966 |
echo pmpro_getPaginationString( $pn, $totalrows, $limit, 1, $pagination_url, "&limit=$limit&pn=" );
|
967 |
?>
|
968 |
|
adminpages/emailsettings.php
CHANGED
@@ -9,6 +9,8 @@
|
|
9 |
|
10 |
//get/set settings
|
11 |
global $pmpro_pages;
|
|
|
|
|
12 |
|
13 |
//check nonce for saving settings
|
14 |
if (!empty($_REQUEST['savesettings']) && (empty($_REQUEST['pmpro_emailsettings_nonce']) || !check_admin_referer('savesettings', 'pmpro_emailsettings_nonce'))) {
|
@@ -116,20 +118,6 @@
|
|
116 |
</table>
|
117 |
<p class="submit"><input name="savesettings" type="submit" class="button-primary" value="<?php esc_attr_e( 'Save All Settings', 'paid-memberships-pro' ); ?>" /></p>
|
118 |
<hr />
|
119 |
-
<div class="pmpro_admin_section pmpro_admin_section-email-content">
|
120 |
-
<h2><?php _e( 'Customizing Email Content', 'paid-memberships-pro' ); ?></h2>
|
121 |
-
<p><?php
|
122 |
-
$allowed_email_customizing_html = array (
|
123 |
-
'a' => array (
|
124 |
-
'href' => array(),
|
125 |
-
'target' => array(),
|
126 |
-
'title' => array(),
|
127 |
-
),
|
128 |
-
);
|
129 |
-
echo sprintf( wp_kses( __( 'There are several ways to modify the appearance of your Paid Memberships Pro emails. We recommend using the free <a href="%s" title="Paid Memberships Pro - Email Templates Admin Editor Add On" target="_blank">Email Templates Admin Editor Add On</a>, which allows you to modify the email header, footer, subject, and body content for all member and admin communications. <a title="Paid Memberships Pro - Member Communications" target="_blank" href="%s">Click here to learn more about Paid Memberships Pro emails</a>.', 'paid-memberships-pro' ), $allowed_email_customizing_html ), 'https://www.paidmembershipspro.com/add-ons/email-templates-admin-editor/?utm_source=plugin&utm_medium=pmpro-emailsettings&utm_campaign=add-ons&utm_content=email-templates-admin-editor', 'http://www.paidmembershipspro.com/documentation/member-communications/?utm_source=plugin&utm_medium=pmpro-emailsettings&utm_campaign=documentation&utm_content=member-communications' );
|
130 |
-
?></p>
|
131 |
-
</div> <!-- end pmpro_admin_section-email-content -->
|
132 |
-
<hr />
|
133 |
<div class="pmpro_admin_section pmpro_admin_section-email-deliverability">
|
134 |
<h2><?php _e( 'Email Deliverability', 'paid-memberships-pro' ); ?></h2>
|
135 |
|
@@ -158,7 +146,7 @@
|
|
158 |
$sendwp_email_forwarding = function_exists( 'sendwp_forwarding_enabled' ) && sendwp_forwarding_enabled() ? true : false;
|
159 |
|
160 |
// Messages for connected or not.
|
161 |
-
$connected = __( 'Your site is connected to SendWP.', 'paid-memberships-pro' ) . " <a href='https://sendwp.com/
|
162 |
$disconnected = ' ' . sprintf( __( 'Please enable email sending inside %s.', 'paid-memberships-pro' ), '<a href="' . admin_url('/tools.php?page=sendwp') . '">SendWP Settings</a>' );
|
163 |
?>
|
164 |
<p class="description" id="pmpro-sendwp-description"><?php echo $sendwp_email_forwarding ? $connected : $disconnected; ?></p>
|
@@ -168,25 +156,7 @@
|
|
168 |
<hr />
|
169 |
<h2 class="title"><?php esc_html_e( 'Other Email Settings', 'paid-memberships-pro' ); ?></h2>
|
170 |
<table class="form-table">
|
171 |
-
<tbody>
|
172 |
-
<tr>
|
173 |
-
<th scope="row" valign="top">
|
174 |
-
<label for="email_admin"><?php _e('Send the site admin emails', 'paid-memberships-pro' );?>:</label>
|
175 |
-
</th>
|
176 |
-
<td>
|
177 |
-
<input type="checkbox" id="email_admin_checkout" name="email_admin_checkout" value="1" <?php if(!empty($email_admin_checkout)) { ?>checked="checked"<?php } ?> />
|
178 |
-
<label for="email_admin_checkout"><?php _e('when a member checks out.', 'paid-memberships-pro' );?></label>
|
179 |
-
<br />
|
180 |
-
<input type="checkbox" id="email_admin_changes" name="email_admin_changes" value="1" <?php if(!empty($email_admin_changes)) { ?>checked="checked"<?php } ?> />
|
181 |
-
<label for="email_admin_changes"><?php _e('when an admin changes a user\'s membership level through the dashboard.', 'paid-memberships-pro' );?></label>
|
182 |
-
<br />
|
183 |
-
<input type="checkbox" id="email_admin_cancels" name="email_admin_cancels" value="1" <?php if(!empty($email_admin_cancels)) { ?>checked="checked"<?php } ?> />
|
184 |
-
<label for="email_admin_cancels"><?php _e('when a user cancels his or her account.', 'paid-memberships-pro' );?></label>
|
185 |
-
<br />
|
186 |
-
<input type="checkbox" id="email_admin_billing" name="email_admin_billing" value="1" <?php if(!empty($email_admin_billing)) { ?>checked="checked"<?php } ?> />
|
187 |
-
<label for="email_admin_billing"><?php _e('when a user updates his or her billing information.', 'paid-memberships-pro' );?></label>
|
188 |
-
</td>
|
189 |
-
</tr>
|
190 |
<tr>
|
191 |
<th scope="row" valign="top">
|
192 |
<label for="email_member_notification"><?php _e('Send members emails', 'paid-memberships-pro' );?>:</label>
|
@@ -198,13 +168,11 @@
|
|
198 |
</td>
|
199 |
</tr>
|
200 |
</tbody>
|
201 |
-
</table>
|
202 |
-
|
203 |
<p class="submit">
|
204 |
<input name="savesettings" type="submit" class="button-primary" value="<?php esc_attr_e( 'Save All Settings', 'paid-memberships-pro' ); ?>" />
|
205 |
</p>
|
206 |
</form>
|
207 |
|
208 |
<?php
|
209 |
-
require_once(dirname(__FILE__) . "/admin_footer.php");
|
210 |
-
?>
|
9 |
|
10 |
//get/set settings
|
11 |
global $pmpro_pages;
|
12 |
+
|
13 |
+
global $current_user;
|
14 |
|
15 |
//check nonce for saving settings
|
16 |
if (!empty($_REQUEST['savesettings']) && (empty($_REQUEST['pmpro_emailsettings_nonce']) || !check_admin_referer('savesettings', 'pmpro_emailsettings_nonce'))) {
|
118 |
</table>
|
119 |
<p class="submit"><input name="savesettings" type="submit" class="button-primary" value="<?php esc_attr_e( 'Save All Settings', 'paid-memberships-pro' ); ?>" /></p>
|
120 |
<hr />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
<div class="pmpro_admin_section pmpro_admin_section-email-deliverability">
|
122 |
<h2><?php _e( 'Email Deliverability', 'paid-memberships-pro' ); ?></h2>
|
123 |
|
146 |
$sendwp_email_forwarding = function_exists( 'sendwp_forwarding_enabled' ) && sendwp_forwarding_enabled() ? true : false;
|
147 |
|
148 |
// Messages for connected or not.
|
149 |
+
$connected = __( 'Your site is connected to SendWP.', 'paid-memberships-pro' ) . " <a href='https://app.sendwp.com/dashboard/' target='_blank' rel='nofollow'>" . __( 'View Your SendWP Account', 'paid-memberships-pro' ) . "</a>";
|
150 |
$disconnected = ' ' . sprintf( __( 'Please enable email sending inside %s.', 'paid-memberships-pro' ), '<a href="' . admin_url('/tools.php?page=sendwp') . '">SendWP Settings</a>' );
|
151 |
?>
|
152 |
<p class="description" id="pmpro-sendwp-description"><?php echo $sendwp_email_forwarding ? $connected : $disconnected; ?></p>
|
156 |
<hr />
|
157 |
<h2 class="title"><?php esc_html_e( 'Other Email Settings', 'paid-memberships-pro' ); ?></h2>
|
158 |
<table class="form-table">
|
159 |
+
<tbody>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
<tr>
|
161 |
<th scope="row" valign="top">
|
162 |
<label for="email_member_notification"><?php _e('Send members emails', 'paid-memberships-pro' );?>:</label>
|
168 |
</td>
|
169 |
</tr>
|
170 |
</tbody>
|
171 |
+
</table>
|
|
|
172 |
<p class="submit">
|
173 |
<input name="savesettings" type="submit" class="button-primary" value="<?php esc_attr_e( 'Save All Settings', 'paid-memberships-pro' ); ?>" />
|
174 |
</p>
|
175 |
</form>
|
176 |
|
177 |
<?php
|
178 |
+
require_once(dirname(__FILE__) . "/admin_footer.php");
|
|
adminpages/emailtemplates.php
ADDED
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//only admins can get this
|
3 |
+
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_emailsettings")))
|
4 |
+
{
|
5 |
+
die(__("You do not have permissions to perform this action.", 'paid-memberships-pro' ));
|
6 |
+
}
|
7 |
+
|
8 |
+
global $wpdb, $msg, $msgt;
|
9 |
+
|
10 |
+
//get/set settings
|
11 |
+
global $pmpro_pages;
|
12 |
+
|
13 |
+
global $pmpro_email_templates_defaults, $current_user;
|
14 |
+
|
15 |
+
require_once(dirname(__FILE__) . "/admin_header.php");
|
16 |
+
?>
|
17 |
+
<form action="" method="post" enctype="multipart/form-data">
|
18 |
+
<?php wp_nonce_field('savesettings', 'pmpro_emailsettings_nonce');?>
|
19 |
+
|
20 |
+
<h1 class="wp-heading-inline"><?php esc_html_e( 'Email Templates', 'paid-memberships-pro' ); ?></h1>
|
21 |
+
<hr class="wp-header-end">
|
22 |
+
|
23 |
+
<p><?php esc_html_e( 'Select an email template from the dropdown below to customize the subject and body of emails sent through your membership site. You can also disable a specific email or send a test version through this admin page.', 'paid-memberships-pro' ); ?> <a href="https://www.paidmembershipspro.com/documentation/member-communications/list-of-pmpro-email-templates/" target="_blank"><?php esc_html_e( 'Click here for a description of each email sent to your members and admins at different stages of the member experience.', 'paid-memberships-pro'); ?></a></p>
|
24 |
+
|
25 |
+
<div class="pmpro_admin_section pmpro_admin_section-email-templates-content">
|
26 |
+
|
27 |
+
<table class="form-table">
|
28 |
+
<tr class="status hide-while-loading" style="display:none;">
|
29 |
+
<th scope="row" valign="top"></th>
|
30 |
+
<td>
|
31 |
+
<div id="message" class="status_message_wrapper">
|
32 |
+
<p class="status_message"></p>
|
33 |
+
</div>
|
34 |
+
</td>
|
35 |
+
</tr>
|
36 |
+
<tr>
|
37 |
+
<th scope="row" valign="top">
|
38 |
+
<label for="pmpro_email_template_switcher"><?php esc_html_e( 'Email Template', 'paid-memberships-pro' ); ?></label>
|
39 |
+
</th>
|
40 |
+
<td>
|
41 |
+
<select name="pmpro_email_template_switcher" id="pmpro_email_template_switcher">
|
42 |
+
<option value="" selected="selected"><?php echo '--- ' . esc_html__( 'Select a Template to Edit', 'paid-memberships-pro' ) . ' ---'; ?></option>
|
43 |
+
|
44 |
+
<?php foreach ( $pmpro_email_templates_defaults as $key => $template ): ?>
|
45 |
+
<option value="<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $template['description'] ); ?></option>
|
46 |
+
|
47 |
+
<?php endforeach; ?>
|
48 |
+
</select>
|
49 |
+
<img src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" id="pmproet-spinner" style="display:none;"/>
|
50 |
+
|
51 |
+
<p id="pmpro_email_template_help_text" class="description"></p>
|
52 |
+
</td>
|
53 |
+
</tr>
|
54 |
+
<tr class="hide-while-loading">
|
55 |
+
<th scope="row" valign="top"></th>
|
56 |
+
<td>
|
57 |
+
<label><input id="pmpro_email_template_disable" name="pmpro_email_template_disable" type="checkbox" /><span
|
58 |
+
id="disable_label"><?php esc_html_e( 'Disable this email?', 'paid-memberships-pro' ); ?></span></label>
|
59 |
+
|
60 |
+
|
61 |
+
<p id="disable_description" class="description"><?php esc_html_e( 'Emails with this template will not be sent.', 'paid-memberships-pro' ); ?></p>
|
62 |
+
|
63 |
+
</td>
|
64 |
+
</tr>
|
65 |
+
<tr class="hide-while-loading">
|
66 |
+
<th scope="row" valign="top"><label for="pmpro_email_template_subject"><?php esc_html_e( 'Subject', 'paid-memberships-pro' ); ?></label></th>
|
67 |
+
|
68 |
+
<td>
|
69 |
+
<input id="pmpro_email_template_subject" name="pmpro_email_template_subject" type="text" size="100"/>
|
70 |
+
</td>
|
71 |
+
</tr>
|
72 |
+
<tr class="hide-while-loading">
|
73 |
+
<th scope="row" valign="top"><label for="pmpro_email_template_body"><?php esc_html_e( 'Body', 'paid-memberships-pro' ); ?></label></th>
|
74 |
+
|
75 |
+
<td>
|
76 |
+
<div id="template_editor_container">
|
77 |
+
<textarea rows="10" cols="80" name="pmpro_email_template_body" id="pmpro_email_template_body"></textarea>
|
78 |
+
</div>
|
79 |
+
</td>
|
80 |
+
</tr>
|
81 |
+
<tr class="hide-while-loading">
|
82 |
+
<th scope="row" valign="top"></th>
|
83 |
+
<td>
|
84 |
+
<?php esc_html_e( 'Send a test email to ', 'paid-memberships-pro' ); ?>
|
85 |
+
<input id="test_email_address" name="test_email_address" type="text"
|
86 |
+
value="<?php echo esc_attr( $current_user->user_email ); ?>"/>
|
87 |
+
<input id="send_test_email" class="button" name="send_test_email" value="<?php esc_attr_e( 'Save Template and Send Email', 'paid-memberships-pro' ); ?>"
|
88 |
+
|
89 |
+
type="button"/>
|
90 |
+
|
91 |
+
<p class="description">
|
92 |
+
<?php esc_html_e( 'Your current membership will be used for any membership level data.', 'paid-memberships-pro' ); ?>
|
93 |
+
</p>
|
94 |
+
</td>
|
95 |
+
</tr>
|
96 |
+
<tr class="controls hide-while-loading">
|
97 |
+
<th scope="row" valign="top"></th>
|
98 |
+
<td>
|
99 |
+
<p class="submit">
|
100 |
+
<input id="pmpro_submit_template_data" name="pmpro_save_template" type="button" class="button-primary"
|
101 |
+
value="<?php esc_attr_e( 'Save Template', 'paid-memberships-pro' ); ?>"/>
|
102 |
+
|
103 |
+
<input id="pmpro_reset_template_data" name="pmpro_reset_template" type="button" class="button"
|
104 |
+
value="<?php esc_attr_e( 'Reset Template', 'paid-memberships-pro' ); ?>"/>
|
105 |
+
|
106 |
+
</p>
|
107 |
+
</td>
|
108 |
+
</tr>
|
109 |
+
</table>
|
110 |
+
|
111 |
+
<hr />
|
112 |
+
|
113 |
+
<div class="pmpro-email-templates-variable-reference">
|
114 |
+
<h1><?php esc_html_e( 'Variable Reference', 'paid-memberships-pro' ); ?></h1>
|
115 |
+
|
116 |
+
<p><?php esc_html_e( 'Use the placeholder variables below to customize your member and admin emails with specific user or membership data.', 'paid-memberships-pro' ); ?></p>
|
117 |
+
<table class="form-table">
|
118 |
+
<tbody>
|
119 |
+
<tr>
|
120 |
+
<th scope="row"><?php esc_html_e('General Settings / Membership Info', 'paid-memberships-pro'); ?></th>
|
121 |
+
<td>
|
122 |
+
<table class="widefat striped">
|
123 |
+
<tbody>
|
124 |
+
<?php
|
125 |
+
$email_variables = [
|
126 |
+
'!!name!!' => __( 'Display Name (Profile/Edit User > Display name publicly as)', 'paid-memberships-pro' ),
|
127 |
+
'!!user_login!!' => __( 'Username', 'paid-memberships-pro' ),
|
128 |
+
'!!sitename!!' => __( 'Site Title', 'paid-memberships-pro' ),
|
129 |
+
'!!siteemail!!' => __( 'Site Email Address (General Settings > Email OR Memberships > Settings > Email Settings)', 'paid-memberships-pro' ),
|
130 |
+
'!!membership_id!!' => __( 'Membership Level ID', 'paid-memberships-pro' ),
|
131 |
+
'!!membership_level_name!!' => __( 'Membership Level Name', 'paid-memberships-pro' ),
|
132 |
+
'!!membership_change!!' => __( 'Membership Level Change', 'paid-memberships-pro' ),
|
133 |
+
'!!membership_expiration!!' => __( 'Membership Level Expiration', 'paid-memberships-pro' ),
|
134 |
+
'!!startdate!!' => __( 'Membership Start Date', 'paid-memberships-pro' ),
|
135 |
+
'!!enddate!!' => __( 'Membership End Date', 'paid-memberships-pro' ),
|
136 |
+
'!!display_name!!' => __( 'Display Name (Profile/Edit User > Display name publicly as)', 'paid-memberships-pro' ),
|
137 |
+
'!!user_email!!' => __( 'User Email', 'paid-memberships-pro' ),
|
138 |
+
'!!login_url!!' => __( 'Login URL', 'paid-memberships-pro' ),
|
139 |
+
'!!levels_url!!' => __( 'Membership Levels Page URL', 'paid-memberships-pro' ),
|
140 |
+
];
|
141 |
+
|
142 |
+
foreach ( $email_variables as $email_variable => $description ) {
|
143 |
+
?>
|
144 |
+
<tr>
|
145 |
+
<td><?php echo esc_html( $email_variable ); ?></td>
|
146 |
+
<td><?php echo esc_html( $description ); ?></td>
|
147 |
+
</tr>
|
148 |
+
<?php
|
149 |
+
}
|
150 |
+
?>
|
151 |
+
</tbody>
|
152 |
+
</table>
|
153 |
+
</td>
|
154 |
+
</tr>
|
155 |
+
<tr>
|
156 |
+
<th scope="row"><?php esc_html_e( 'Billing Information', 'paid-memberships-pro' ); ?></th>
|
157 |
+
<td>
|
158 |
+
<table class="widefat striped">
|
159 |
+
<tbody>
|
160 |
+
<?php
|
161 |
+
$email_variables = [
|
162 |
+
'!!billing_address!!' => __( 'Billing Info Complete Address', 'paid-memberships-pro' ),
|
163 |
+
'!!billing_name!!' => __( 'Billing Info Name', 'paid-memberships-pro' ),
|
164 |
+
'!!billing_street!!' => __( 'Billing Info Street Address', 'paid-memberships-pro' ),
|
165 |
+
'!!billing_city!!' => __( 'Billing Info City', 'paid-memberships-pro' ),
|
166 |
+
'!!billing_state!!' => __( 'Billing Info State', 'paid-memberships-pro' ),
|
167 |
+
'!!billing_zip!!' => __( 'Billing Info ZIP Code', 'paid-memberships-pro' ),
|
168 |
+
'!!billing_country!!' => __( 'Billing Info Country', 'paid-memberships-pro' ),
|
169 |
+
'!!billing_phone!!' => __( 'Billing Info Phone #', 'paid-memberships-pro' ),
|
170 |
+
'!!cardtype!!' => __( 'Credit Card Type', 'paid-memberships-pro' ),
|
171 |
+
'!!accountnumber!!' => __( 'Credit Card Number (last 4 digits)', 'paid-memberships-pro' ),
|
172 |
+
'!!expirationmonth!!' => __( 'Credit Card Expiration Month (mm format)', 'paid-memberships-pro' ),
|
173 |
+
'!!expirationyear!!' => __( 'Credit Card Expiration Year (yyyy format)', 'paid-memberships-pro' ),
|
174 |
+
'!!membership_cost!!' => __( 'Membership Level Cost Text', 'paid-memberships-pro' ),
|
175 |
+
'!!instructions!!' => __( 'Payment Instructions (used in Checkout - Email Template)', 'paid-memberships-pro' ),
|
176 |
+
'!!invoice_id!!' => __( 'Invoice ID', 'paid-memberships-pro' ),
|
177 |
+
'!!invoice_total!!' => __( 'Invoice Total', 'paid-memberships-pro' ),
|
178 |
+
'!!invoice_date!!' => __( 'Invoice Date', 'paid-memberships-pro' ),
|
179 |
+
'!!invoice_url!!' => __( 'Invoice Page URL', 'paid-memberships-pro' ),
|
180 |
+
'!!discount_code!!' => __( 'Discount Code Applied', 'paid-memberships-pro' ),
|
181 |
+
'!!membership_level_confirmation_message!!' => __( 'Custom Level Confirmation Message', 'paid-memberships-pro' ),
|
182 |
+
|
183 |
+
];
|
184 |
+
|
185 |
+
foreach ( $email_variables as $email_variable => $description ) {
|
186 |
+
?>
|
187 |
+
<tr>
|
188 |
+
<td><?php echo esc_html( $email_variable ); ?></td>
|
189 |
+
<td><?php echo esc_html( $description ); ?></td>
|
190 |
+
</tr>
|
191 |
+
<?php
|
192 |
+
}
|
193 |
+
?>
|
194 |
+
</tbody>
|
195 |
+
</table>
|
196 |
+
</td>
|
197 |
+
</tr>
|
198 |
+
</tbody>
|
199 |
+
</table>
|
200 |
+
</div> <!-- end pmpro-email-templates-variable-reference -->
|
201 |
+
|
202 |
+
<?php wp_nonce_field( 'pmproet', 'security' ); ?>
|
203 |
+
|
204 |
+
</div> <!-- end pmpro_admin_section-email-templates-content -->
|
205 |
+
</form>
|
206 |
+
<?php
|
207 |
+
require_once(dirname(__FILE__) . "/admin_footer.php");
|
adminpages/functions.php
CHANGED
@@ -51,10 +51,20 @@ function pmpro_checkLevelForStripeCompatibility($level = NULL)
|
|
51 |
if(is_numeric($level))
|
52 |
$level = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = %d LIMIT 1" , $level ) );
|
53 |
|
54 |
-
//
|
55 |
if ( ( $level->billing_limit > 0 ) && ! function_exists( 'pmprosbl_plugin_row_meta' ) ) {
|
56 |
return false;
|
57 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
}
|
59 |
}
|
60 |
|
@@ -231,7 +241,19 @@ function pmpro_check_discount_code_level_for_gateway_compatibility( $discount_co
|
|
231 |
|
232 |
// Check this discount code level for gateway compatibility
|
233 |
if ( $gateway == 'stripe' ) {
|
234 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
global $pmpro_stripe_error;
|
236 |
$pmpro_stripe_error = true;
|
237 |
return false;
|
@@ -249,7 +271,7 @@ function pmpro_check_discount_code_level_for_gateway_compatibility( $discount_co
|
|
249 |
$pmpro_braintree_error = true;
|
250 |
return false;
|
251 |
}
|
252 |
-
}
|
253 |
if ( $discount_code_level->trial_amount > $discount_code_level->billing_amount ) {
|
254 |
global $pmpro_twocheckout_error;
|
255 |
$pmpro_twocheckout_error = true;
|
@@ -367,7 +389,7 @@ function pmpro_add_email_order_modal() {
|
|
367 |
$email = new PMProEmail();
|
368 |
$user = get_user_by( 'email', sanitize_email( $_REQUEST['email'] ) );
|
369 |
$order = new MemberOrder( $_REQUEST['order'] );
|
370 |
-
if ( $email->sendBillableInvoiceEmail( $user, $order ) ) { ?>
|
371 |
<div class="notice notice-success is-dismissible">
|
372 |
<p><?php _e( 'Invoice emailed successfully.', 'paid-memberships-pro' ); ?></p>
|
373 |
</div>
|
@@ -410,4 +432,3 @@ function pmpro_add_email_order_modal() {
|
|
410 |
</div>
|
411 |
<?php
|
412 |
}
|
413 |
-
|
51 |
if(is_numeric($level))
|
52 |
$level = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = %d LIMIT 1" , $level ) );
|
53 |
|
54 |
+
// Check if this level uses billing limits.
|
55 |
if ( ( $level->billing_limit > 0 ) && ! function_exists( 'pmprosbl_plugin_row_meta' ) ) {
|
56 |
return false;
|
57 |
}
|
58 |
+
|
59 |
+
// Check if this level has a billing period longer than 1 year.
|
60 |
+
if (
|
61 |
+
( $level->cycle_period === 'Year' && $level->cycle_number > 1 ) ||
|
62 |
+
( $level->cycle_period === 'Month' && $level->cycle_number > 12 ) ||
|
63 |
+
( $level->cycle_period === 'Week' && $level->cycle_number > 52 ) ||
|
64 |
+
( $level->cycle_period === 'Day' && $level->cycle_number > 365 )
|
65 |
+
) {
|
66 |
+
return false;
|
67 |
+
}
|
68 |
}
|
69 |
}
|
70 |
|
241 |
|
242 |
// Check this discount code level for gateway compatibility
|
243 |
if ( $gateway == 'stripe' ) {
|
244 |
+
// Check if this code level has a billing limit.
|
245 |
+
if ( ( intval( $discount_code_level->billing_limit ) > 0 ) && ! function_exists( 'pmprosbl_plugin_row_meta' ) ) {
|
246 |
+
global $pmpro_stripe_error;
|
247 |
+
$pmpro_stripe_error = true;
|
248 |
+
return false;
|
249 |
+
}
|
250 |
+
// Check if this code level has a billing period longer than 1 year.
|
251 |
+
if (
|
252 |
+
( $discount_code_level->cycle_period === 'Year' && intval( $discount_code_level->cycle_number ) > 1 ) ||
|
253 |
+
( $discount_code_level->cycle_period === 'Month' && intval( $discount_code_level->cycle_number ) > 12 ) ||
|
254 |
+
( $discount_code_level->cycle_period === 'Week' && intval( $discount_code_level->cycle_number ) > 52 ) ||
|
255 |
+
( $discount_code_level->cycle_period === 'Day' && intval( $discount_code_level->cycle_number ) > 365 )
|
256 |
+
) {
|
257 |
global $pmpro_stripe_error;
|
258 |
$pmpro_stripe_error = true;
|
259 |
return false;
|
271 |
$pmpro_braintree_error = true;
|
272 |
return false;
|
273 |
}
|
274 |
+
} elseif ( $gateway == 'twocheckout' ) {
|
275 |
if ( $discount_code_level->trial_amount > $discount_code_level->billing_amount ) {
|
276 |
global $pmpro_twocheckout_error;
|
277 |
$pmpro_twocheckout_error = true;
|
389 |
$email = new PMProEmail();
|
390 |
$user = get_user_by( 'email', sanitize_email( $_REQUEST['email'] ) );
|
391 |
$order = new MemberOrder( $_REQUEST['order'] );
|
392 |
+
if ( ! empty( $user ) && ! empty( $order ) && $email->sendBillableInvoiceEmail( $user, $order ) ) { ?>
|
393 |
<div class="notice notice-success is-dismissible">
|
394 |
<p><?php _e( 'Invoice emailed successfully.', 'paid-memberships-pro' ); ?></p>
|
395 |
</div>
|
432 |
</div>
|
433 |
<?php
|
434 |
}
|
|
adminpages/license.php
CHANGED
@@ -7,35 +7,25 @@ if ( ! function_exists( 'current_user_can' ) || ( ! current_user_can( 'manage_op
|
|
7 |
//updating license?
|
8 |
if ( ! empty( $_REQUEST['pmpro-verify-submit'] ) ) {
|
9 |
$key = preg_replace("/[^a-zA-Z0-9]/", "", $_REQUEST['pmpro-license-key']);
|
10 |
-
|
11 |
-
//erase the old key
|
12 |
-
delete_option('pmpro_license_key');
|
13 |
|
14 |
-
//
|
15 |
-
$
|
|
|
16 |
|
17 |
-
|
18 |
-
<div id="message" class="updated fade">
|
19 |
-
<p><?php _e( 'Your license key has been validated.', 'paid-memberships-pro' ); ?></p>
|
20 |
-
</div>
|
21 |
-
<?php } else {
|
22 |
-
global $pmpro_license_error;
|
23 |
-
if ( ! empty( $pmpro_license_error ) ) { ?>
|
24 |
-
<div id="message" class="error">
|
25 |
-
<p><?php echo $pmpro_license_error; ?></p>
|
26 |
-
</div>
|
27 |
-
<?php }
|
28 |
-
}
|
29 |
-
|
30 |
-
//update key
|
31 |
update_option( 'pmpro_license_key', $key, 'no' );
|
32 |
-
}
|
33 |
|
34 |
-
//
|
35 |
-
|
36 |
-
$
|
|
|
|
|
|
|
|
|
|
|
37 |
|
38 |
-
//
|
39 |
if ( defined( 'PMPRO_DIR' ) ) {
|
40 |
require_once( PMPRO_DIR . '/adminpages/admin_header.php' );
|
41 |
} ?>
|
@@ -43,12 +33,14 @@ if ( defined( 'PMPRO_DIR' ) ) {
|
|
43 |
<h2><?php _e('Paid Memberships Pro Support License', 'paid-memberships-pro' );?></h2>
|
44 |
|
45 |
<div class="about-text">
|
46 |
-
<?php if(
|
|
|
|
|
47 |
<p class="pmpro_message pmpro_error"><strong><?php _e('Enter your support license key.</strong> Your license key can be found in your membership email receipt or in your <a href="https://www.paidmembershipspro.com/login/?redirect_to=%2Fmembership-account%2F%3Futm_source%3Dplugin%26utm_medium%3Dpmpro-license%26utm_campaign%3Dmembership-account%26utm_content%3Dno-key" target="_blank">Membership Account</a>.', 'paid-memberships-pro' );?></p>
|
48 |
-
<?php } elseif(!pmpro_license_isValid()) { ?>
|
49 |
<p class="pmpro_message pmpro_error"><strong><?php _e('Your license is invalid or expired.', 'paid-memberships-pro' );?></strong> <?php _e('Visit the PMPro <a href="https://www.paidmembershipspro.com/login/?redirect_to=%2Fmembership-account%2F%3Futm_source%3Dplugin%26utm_medium%3Dpmpro-license%26utm_campaign%3Dmembership-account%26utm_content%3Dkey-not-valid" target="_blank">Membership Account</a> page to confirm that your account is active and to find your license key.', 'paid-memberships-pro' );?></p>
|
50 |
<?php } else { ?>
|
51 |
-
<p class="pmpro_message pmpro_success"><?php printf(__('<strong>Thank you!</strong> A valid <strong>%s</strong> license key has been used to activate your support license on this site.', 'paid-memberships-pro' ), ucwords($pmpro_license_check['license']));?></p>
|
52 |
<?php } ?>
|
53 |
|
54 |
<form action="" method="post">
|
@@ -56,7 +48,7 @@ if ( defined( 'PMPRO_DIR' ) ) {
|
|
56 |
<tbody>
|
57 |
<tr id="pmpro-settings-key-box">
|
58 |
<td>
|
59 |
-
<input type="
|
60 |
<?php wp_nonce_field( 'pmpro-key-nonce', 'pmpro-key-nonce' ); ?>
|
61 |
<?php submit_button( __( 'Validate Key', 'paid-memberships-pro' ), 'primary', 'pmpro-verify-submit', false ); ?>
|
62 |
</td>
|
@@ -67,8 +59,7 @@ if ( defined( 'PMPRO_DIR' ) ) {
|
|
67 |
|
68 |
<p>
|
69 |
<?php if ( ! pmpro_license_isValid() ) { ?>
|
70 |
-
<a class="button button-primary button-hero" href="https://www.paidmembershipspro.com/
|
71 |
-
<a class="button button-hero" href="https://www.paidmembershipspro.com/pricing/?utm_source=plugin&utm_medium=pmpro-license&utm_campaign=pricing&utm_content=view-license-options" target="_blank"><?php echo esc_html( 'View Support License Options', 'paid-memberships-pro' ); ?></a>
|
72 |
<?php } else { ?>
|
73 |
<a class="button button-primary button-hero" href="https://www.paidmembershipspro.com/login/?redirect_to=%2Fmembership-account%2F%3Futm_source%3Dplugin%26utm_medium%3Dpmpro-license%26utm_campaign%3Dmembership-account%26utm_content%3Dview-account" target="_blank"><?php echo esc_html( 'Manage My Account', 'paid-memberships-pro' ); ?></a>
|
74 |
<a class="button button-hero" href="https://www.paidmembershipspro.com/login/?redirect_to=%2Fnew-topic%2F%3Futm_source%3Dplugin%26utm_medium%3Dpmpro-license%26utm_campaign%3Dsupport%26utm_content%3Dnew-support-ticket" target="_blank"><?php echo esc_html( 'Open Support Ticket', 'paid-memberships-pro' ); ?></a>
|
@@ -96,7 +87,7 @@ if ( defined( 'PMPRO_DIR' ) ) {
|
|
96 |
?>
|
97 |
|
98 |
<?php
|
99 |
-
echo '<p>' . wp_kses( __( '<strong>Paid Memberships Pro offers plans for automatic updates of Add Ons and premium support.</strong> These plans include a
|
100 |
?>
|
101 |
|
102 |
<?php
|
7 |
//updating license?
|
8 |
if ( ! empty( $_REQUEST['pmpro-verify-submit'] ) ) {
|
9 |
$key = preg_replace("/[^a-zA-Z0-9]/", "", $_REQUEST['pmpro-license-key']);
|
|
|
|
|
|
|
10 |
|
11 |
+
// Check key.
|
12 |
+
$pmpro_license_check = pmpro_license_check_key( $key );
|
13 |
+
$r = pmpro_license_isValid( $key );
|
14 |
|
15 |
+
// Update key.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
update_option( 'pmpro_license_key', $key, 'no' );
|
17 |
+
}
|
18 |
|
19 |
+
// Get values from options if not updating.
|
20 |
+
if ( empty( $key ) ) {
|
21 |
+
$key = get_option( 'pmpro_license_key', '' );
|
22 |
+
}
|
23 |
+
|
24 |
+
if ( empty( $pmpro_license_check ) ) {
|
25 |
+
$pmpro_license_check = get_option( 'pmpro_license_check', array( 'license' => false, 'enddate' => 0 ) );
|
26 |
+
}
|
27 |
|
28 |
+
// HTML for license settings page.
|
29 |
if ( defined( 'PMPRO_DIR' ) ) {
|
30 |
require_once( PMPRO_DIR . '/adminpages/admin_header.php' );
|
31 |
} ?>
|
33 |
<h2><?php _e('Paid Memberships Pro Support License', 'paid-memberships-pro' );?></h2>
|
34 |
|
35 |
<div class="about-text">
|
36 |
+
<?php if ( is_wp_error( $pmpro_license_check ) ) { ?>
|
37 |
+
<p class="pmpro_message pmpro_error"><strong><?php echo esc_html( sprintf( __( 'There was an issue validating your license key: %s', 'paid-memberships-pro' ), $pmpro_license_check->get_error_message() ) );?></strong> <?php _e('Visit the PMPro <a href="https://www.paidmembershipspro.com/login/?redirect_to=%2Fmembership-account%2F%3Futm_source%3Dplugin%26utm_medium%3Dpmpro-license%26utm_campaign%3Dmembership-account%26utm_content%3Dkey-not-valid" target="_blank">Membership Account</a> page to confirm that your account is active and to find your license key.', 'paid-memberships-pro' );?></p>
|
38 |
+
<?php } elseif( ! pmpro_license_isValid() && empty( $key ) ) { ?>
|
39 |
<p class="pmpro_message pmpro_error"><strong><?php _e('Enter your support license key.</strong> Your license key can be found in your membership email receipt or in your <a href="https://www.paidmembershipspro.com/login/?redirect_to=%2Fmembership-account%2F%3Futm_source%3Dplugin%26utm_medium%3Dpmpro-license%26utm_campaign%3Dmembership-account%26utm_content%3Dno-key" target="_blank">Membership Account</a>.', 'paid-memberships-pro' );?></p>
|
40 |
+
<?php } elseif( ! pmpro_license_isValid() ) { ?>
|
41 |
<p class="pmpro_message pmpro_error"><strong><?php _e('Your license is invalid or expired.', 'paid-memberships-pro' );?></strong> <?php _e('Visit the PMPro <a href="https://www.paidmembershipspro.com/login/?redirect_to=%2Fmembership-account%2F%3Futm_source%3Dplugin%26utm_medium%3Dpmpro-license%26utm_campaign%3Dmembership-account%26utm_content%3Dkey-not-valid" target="_blank">Membership Account</a> page to confirm that your account is active and to find your license key.', 'paid-memberships-pro' );?></p>
|
42 |
<?php } else { ?>
|
43 |
+
<p class="pmpro_message pmpro_success"><?php printf(__('<strong>Thank you!</strong> A valid <strong>%s</strong> license key has been used to activate your support license on this site.', 'paid-memberships-pro' ), ucwords( $pmpro_license_check['license'] ) );?></p>
|
44 |
<?php } ?>
|
45 |
|
46 |
<form action="" method="post">
|
48 |
<tbody>
|
49 |
<tr id="pmpro-settings-key-box">
|
50 |
<td>
|
51 |
+
<input type="text" name="pmpro-license-key" id="pmpro-license-key" value="<?php echo esc_attr($key);?>" placeholder="<?php _e('Enter license key here...', 'paid-memberships-pro' );?>" size="40" />
|
52 |
<?php wp_nonce_field( 'pmpro-key-nonce', 'pmpro-key-nonce' ); ?>
|
53 |
<?php submit_button( __( 'Validate Key', 'paid-memberships-pro' ), 'primary', 'pmpro-verify-submit', false ); ?>
|
54 |
</td>
|
59 |
|
60 |
<p>
|
61 |
<?php if ( ! pmpro_license_isValid() ) { ?>
|
62 |
+
<a class="button button-primary button-hero" href="https://www.paidmembershipspro.com/pricing/?utm_source=plugin&utm_medium=pmpro-license&utm_campaign=pricing&utm_content=view-plans-pricing" target="_blank"><?php echo esc_html( 'View Plans and Pricing', 'paid-memberships-pro' ); ?></a>
|
|
|
63 |
<?php } else { ?>
|
64 |
<a class="button button-primary button-hero" href="https://www.paidmembershipspro.com/login/?redirect_to=%2Fmembership-account%2F%3Futm_source%3Dplugin%26utm_medium%3Dpmpro-license%26utm_campaign%3Dmembership-account%26utm_content%3Dview-account" target="_blank"><?php echo esc_html( 'Manage My Account', 'paid-memberships-pro' ); ?></a>
|
65 |
<a class="button button-hero" href="https://www.paidmembershipspro.com/login/?redirect_to=%2Fnew-topic%2F%3Futm_source%3Dplugin%26utm_medium%3Dpmpro-license%26utm_campaign%3Dsupport%26utm_content%3Dnew-support-ticket" target="_blank"><?php echo esc_html( 'Open Support Ticket', 'paid-memberships-pro' ); ?></a>
|
87 |
?>
|
88 |
|
89 |
<?php
|
90 |
+
echo '<p>' . wp_kses( __( '<strong>Paid Memberships Pro offers plans for automatic updates of Add Ons and premium support.</strong> These plans include a license key which we recommend for all public websites running Paid Memberships Pro. A license key allows you to automatically install Add Ons included in your plan and update active Add Ons included in your plan when a new security, bug fix, or feature enhancement is released.' ), $allowed_pmpro_license_strings_html ) . '</p>';
|
91 |
?>
|
92 |
|
93 |
<?php
|
adminpages/membershiplevels.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
die(__("You do not have permissions to perform this action.", 'paid-memberships-pro' ));
|
6 |
}
|
7 |
|
8 |
-
global $wpdb, $msg, $msgt, $pmpro_currency_symbol, $allowedposttags;
|
9 |
|
10 |
//some vars
|
11 |
$gateway = pmpro_getOption("gateway");
|
@@ -134,7 +134,7 @@
|
|
134 |
'%d', //allow_signups
|
135 |
)
|
136 |
);
|
137 |
-
|
138 |
if($saveid < 1) {
|
139 |
//added a level
|
140 |
$saveid = $wpdb->insert_id;
|
@@ -164,10 +164,10 @@
|
|
164 |
$msgt = __("Error updating membership level.", 'paid-memberships-pro' );
|
165 |
}
|
166 |
}
|
167 |
-
|
168 |
if( ! empty( $msgt ) && $ml_recurring && $ml_expiration ) {
|
169 |
$msgt .= ' <strong class="red">' . sprintf( __( 'WARNING: A level was set with both a recurring billing amount and an expiration date. You only need to set one of these unless you really want this membership to expire after a specific time period. For more information, <a target="_blank" href="%s">see our post here</a>.', 'paid-memberships-pro' ), 'https://www.paidmembershipspro.com/important-notes-on-recurring-billing-and-expiration-dates-for-membership-levels/?utm_source=plugin&utm_medium=pmpro-membershiplevels&utm_campaign=blog&utm_content=important-notes-on-recurring-billing-and-expiration-dates-for-membership-levels' ) . '</strong>';
|
170 |
-
|
171 |
// turn success to errors
|
172 |
if( $msg > 0 ) {
|
173 |
$msg = 0 - $msg;
|
@@ -178,7 +178,7 @@
|
|
178 |
if ( isset( $ml_confirmation_in_email ) ) {
|
179 |
update_pmpro_membership_level_meta( $saveid, 'confirmation_in_email', $ml_confirmation_in_email );
|
180 |
}
|
181 |
-
|
182 |
do_action("pmpro_save_membership_level", $saveid);
|
183 |
}
|
184 |
elseif($action == "delete_membership_level")
|
@@ -269,7 +269,7 @@
|
|
269 |
?>
|
270 |
</h1>
|
271 |
<hr class="wp-header-end">
|
272 |
-
|
273 |
<div>
|
274 |
<?php
|
275 |
// get the level...
|
@@ -328,7 +328,7 @@
|
|
328 |
) );
|
329 |
if(empty($level->categories))
|
330 |
$level->categories = array();
|
331 |
-
|
332 |
// grab the meta for the given level...
|
333 |
if ( ! empty( $temp_id ) ) {
|
334 |
$confirmation_in_email = get_pmpro_membership_level_meta( $temp_id, 'confirmation_in_email', true );
|
@@ -446,7 +446,9 @@
|
|
446 |
<?php _e('The amount to be billed one cycle after the initial payment.', 'paid-memberships-pro' );?>
|
447 |
<?php if($gateway == "braintree") { ?>
|
448 |
<strong <?php if(!empty($pmpro_braintree_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Braintree integration currently only supports billing periods of "Month" or "Year".', 'paid-memberships-pro' );?></strong>
|
449 |
-
<?php } ?>
|
|
|
|
|
450 |
</p>
|
451 |
<?php if($gateway == "braintree" && $edit < 0) { ?>
|
452 |
<p class="pmpro_message"><strong><?php _e('Note', 'paid-memberships-pro' );?>:</strong> <?php _e('After saving this level, make note of the ID and create a "Plan" in your Braintree dashboard with the same settings and the "Plan ID" set to <em>pmpro_#</em>, where # is the level ID.', 'paid-memberships-pro' );?></p>
|
@@ -531,7 +533,20 @@
|
|
531 |
|
532 |
</tbody>
|
533 |
</table>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
534 |
<hr />
|
|
|
535 |
<h2 class="title"><?php esc_html_e( 'Other Settings', 'paid-memberships-pro' ); ?></h2>
|
536 |
<table class="form-table">
|
537 |
<tbody>
|
@@ -556,22 +571,20 @@
|
|
556 |
echo '<tr><th> </th><td><p class="description">' . sprintf( wp_kses( __( 'Optional: Allow more customizable expiration dates using the <a href="%s" title="Paid Memberships Pro - Set Expiration Date Add On" target="_blank">Set Expiration Date Add On</a>.', 'paid-memberships-pro' ), $allowed_sed_html ), 'https://www.paidmembershipspro.com/add-ons/pmpro-expiration-date/?utm_source=plugin&utm_medium=pmpro-membershiplevels&utm_campaign=add-ons&utm_content=pmpro-expiration-date' ) . '</p></td></tr>';
|
557 |
} ?>
|
558 |
|
559 |
-
<tr class="expiration_info" <?php if(!pmpro_isLevelExpiring($level)) {?>style="display: none;"<?php } ?>>
|
560 |
<th scope="row" valign="top"><label for="billing_amount"><?php _e('Expires In', 'paid-memberships-pro' );?>:</label></th>
|
561 |
<td>
|
562 |
<input id="expiration_number" name="expiration_number" type="text" value="<?php echo esc_attr($level->expiration_number);?>" class="small-text" />
|
563 |
<select id="expiration_period" name="expiration_period">
|
564 |
<?php
|
565 |
-
$cycles = array( __('Day(s)', 'paid-memberships-pro' ) => 'Day', __('Week(s)', 'paid-memberships-pro' ) => 'Week', __('Month(s)', 'paid-memberships-pro' ) => 'Month', __('Year(s)', 'paid-memberships-pro' ) => 'Year' );
|
566 |
foreach ( $cycles as $name => $value ) {
|
567 |
-
echo "<option value='$value'";
|
568 |
-
if ( $level->expiration_period == $value ) echo " selected='selected'";
|
569 |
-
echo ">$name</option>";
|
570 |
}
|
571 |
?>
|
572 |
</select>
|
573 |
<p class="description"><?php _e('Set the duration of membership access. Note that the any future payments (recurring subscription, if any) will be cancelled when the membership expires.', 'paid-memberships-pro' );?></p>
|
574 |
-
|
575 |
<div id="pmpro_expiration_warning" style="display: none;" class="notice error inline">
|
576 |
<p><?php printf( __( 'WARNING: This level is set with both a recurring billing amount and an expiration date. You only need to set one of these unless you really want this membership to expire after a certain number of payments. For more information, <a target="_blank" href="%s">see our post here</a>.', 'paid-memberships-pro' ), 'https://www.paidmembershipspro.com/important-notes-on-recurring-billing-and-expiration-dates-for-membership-levels/?utm_source=plugin&utm_medium=pmpro-membershiplevels&utm_campaign=blog&utm_content=important-notes-on-recurring-billing-and-expiration-dates-for-membership-levels' ); ?></p>
|
577 |
</div>
|
@@ -584,9 +597,9 @@
|
|
584 |
jQuery('#pmpro_expiration_warning').hide();
|
585 |
}
|
586 |
}
|
587 |
-
|
588 |
pmpro_expirationWarningCheck();
|
589 |
-
|
590 |
jQuery('#recurring,#expiration').change(function() { pmpro_expirationWarningCheck(); });
|
591 |
});
|
592 |
</script>
|
@@ -595,7 +608,16 @@
|
|
595 |
</tbody>
|
596 |
</table>
|
597 |
|
598 |
-
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
599 |
|
600 |
<hr />
|
601 |
|
@@ -636,9 +658,21 @@
|
|
636 |
</tr>
|
637 |
</tbody>
|
638 |
</table>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
639 |
<p class="submit topborder">
|
640 |
<input name="save" type="submit" class="button button-primary" value="<?php _e('Save Level', 'paid-memberships-pro' ); ?>" />
|
641 |
-
<input name="cancel" type="button" class="button" value="<?php _e('Cancel', 'paid-memberships-pro' ); ?>" onclick="location.href='<?php echo add_query_arg( 'page', 'pmpro-membershiplevels' ,
|
642 |
</p>
|
643 |
</form>
|
644 |
</div>
|
@@ -756,7 +790,7 @@
|
|
756 |
</p>
|
757 |
</form>
|
758 |
<h1 class="wp-heading-inline"><?php esc_html_e( 'Membership Levels', 'paid-memberships-pro' ); ?></h1>
|
759 |
-
<a href="<?php echo add_query_arg( array( 'page' => 'pmpro-membershiplevels', 'edit' => -1 ),
|
760 |
<hr class="wp-header-end">
|
761 |
|
762 |
<?php if(empty($_REQUEST['s']) && count($reordered_levels) > 1) { ?>
|
@@ -784,7 +818,7 @@
|
|
784 |
<td colspan="5">
|
785 |
<?php echo esc_attr_e( 'No Membership Levels Found', 'paid-memberships-pro' ); ?>
|
786 |
</td>
|
787 |
-
</tr>
|
788 |
<?php } ?>
|
789 |
<?php
|
790 |
$count = 0;
|
@@ -796,9 +830,90 @@
|
|
796 |
<td class="level_name has-row-actions">
|
797 |
<span class="level-name"><a href="<?php echo add_query_arg( array( 'page' => 'pmpro-membershiplevels', 'edit' => $level->id ), admin_url( 'admin.php' ) ); ?>"><?php esc_attr_e( $level->name ); ?></a></span>
|
798 |
<div class="row-actions">
|
799 |
-
|
800 |
-
|
801 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
802 |
</div>
|
803 |
</td>
|
804 |
<td>
|
@@ -815,7 +930,17 @@
|
|
815 |
<?php _e('After', 'paid-memberships-pro' );?> <?php echo $level->expiration_number?> <?php echo sornot($level->expiration_period,$level->expiration_number)?>
|
816 |
<?php } ?>
|
817 |
</td>
|
818 |
-
<td><?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
819 |
<?php do_action( 'pmpro_membership_levels_table_extra_cols_body', $level ); ?>
|
820 |
</tr>
|
821 |
<?php
|
5 |
die(__("You do not have permissions to perform this action.", 'paid-memberships-pro' ));
|
6 |
}
|
7 |
|
8 |
+
global $wpdb, $msg, $msgt, $pmpro_currency_symbol, $allowedposttags, $pmpro_pages;
|
9 |
|
10 |
//some vars
|
11 |
$gateway = pmpro_getOption("gateway");
|
134 |
'%d', //allow_signups
|
135 |
)
|
136 |
);
|
137 |
+
|
138 |
if($saveid < 1) {
|
139 |
//added a level
|
140 |
$saveid = $wpdb->insert_id;
|
164 |
$msgt = __("Error updating membership level.", 'paid-memberships-pro' );
|
165 |
}
|
166 |
}
|
167 |
+
|
168 |
if( ! empty( $msgt ) && $ml_recurring && $ml_expiration ) {
|
169 |
$msgt .= ' <strong class="red">' . sprintf( __( 'WARNING: A level was set with both a recurring billing amount and an expiration date. You only need to set one of these unless you really want this membership to expire after a specific time period. For more information, <a target="_blank" href="%s">see our post here</a>.', 'paid-memberships-pro' ), 'https://www.paidmembershipspro.com/important-notes-on-recurring-billing-and-expiration-dates-for-membership-levels/?utm_source=plugin&utm_medium=pmpro-membershiplevels&utm_campaign=blog&utm_content=important-notes-on-recurring-billing-and-expiration-dates-for-membership-levels' ) . '</strong>';
|
170 |
+
|
171 |
// turn success to errors
|
172 |
if( $msg > 0 ) {
|
173 |
$msg = 0 - $msg;
|
178 |
if ( isset( $ml_confirmation_in_email ) ) {
|
179 |
update_pmpro_membership_level_meta( $saveid, 'confirmation_in_email', $ml_confirmation_in_email );
|
180 |
}
|
181 |
+
|
182 |
do_action("pmpro_save_membership_level", $saveid);
|
183 |
}
|
184 |
elseif($action == "delete_membership_level")
|
269 |
?>
|
270 |
</h1>
|
271 |
<hr class="wp-header-end">
|
272 |
+
|
273 |
<div>
|
274 |
<?php
|
275 |
// get the level...
|
328 |
) );
|
329 |
if(empty($level->categories))
|
330 |
$level->categories = array();
|
331 |
+
|
332 |
// grab the meta for the given level...
|
333 |
if ( ! empty( $temp_id ) ) {
|
334 |
$confirmation_in_email = get_pmpro_membership_level_meta( $temp_id, 'confirmation_in_email', true );
|
446 |
<?php _e('The amount to be billed one cycle after the initial payment.', 'paid-memberships-pro' );?>
|
447 |
<?php if($gateway == "braintree") { ?>
|
448 |
<strong <?php if(!empty($pmpro_braintree_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Braintree integration currently only supports billing periods of "Month" or "Year".', 'paid-memberships-pro' );?></strong>
|
449 |
+
<?php } elseif($gateway == "stripe") { ?>
|
450 |
+
<p class="description"><strong <?php if(!empty($pmpro_stripe_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Stripe integration does not allow billing periods longer than 1 year.', 'paid-memberships-pro' );?></strong></p>
|
451 |
+
<?php }?>
|
452 |
</p>
|
453 |
<?php if($gateway == "braintree" && $edit < 0) { ?>
|
454 |
<p class="pmpro_message"><strong><?php _e('Note', 'paid-memberships-pro' );?>:</strong> <?php _e('After saving this level, make note of the ID and create a "Plan" in your Braintree dashboard with the same settings and the "Plan ID" set to <em>pmpro_#</em>, where # is the level ID.', 'paid-memberships-pro' );?></p>
|
533 |
|
534 |
</tbody>
|
535 |
</table>
|
536 |
+
|
537 |
+
<?php
|
538 |
+
/**
|
539 |
+
* Allow adding form fields after the Billing Details Settings section.
|
540 |
+
*
|
541 |
+
* @since 2.5.10
|
542 |
+
*
|
543 |
+
* @param object $level The Membership Level object.
|
544 |
+
*/
|
545 |
+
do_action( 'pmpro_membership_level_after_billing_details_settings', $level );
|
546 |
+
?>
|
547 |
+
|
548 |
<hr />
|
549 |
+
|
550 |
<h2 class="title"><?php esc_html_e( 'Other Settings', 'paid-memberships-pro' ); ?></h2>
|
551 |
<table class="form-table">
|
552 |
<tbody>
|
571 |
echo '<tr><th> </th><td><p class="description">' . sprintf( wp_kses( __( 'Optional: Allow more customizable expiration dates using the <a href="%s" title="Paid Memberships Pro - Set Expiration Date Add On" target="_blank">Set Expiration Date Add On</a>.', 'paid-memberships-pro' ), $allowed_sed_html ), 'https://www.paidmembershipspro.com/add-ons/pmpro-expiration-date/?utm_source=plugin&utm_medium=pmpro-membershiplevels&utm_campaign=add-ons&utm_content=pmpro-expiration-date' ) . '</p></td></tr>';
|
572 |
} ?>
|
573 |
|
574 |
+
<tr class="expiration_info" <?php if(!pmpro_isLevelExpiring($level)) {?>style="display: none;"<?php } ?>>
|
575 |
<th scope="row" valign="top"><label for="billing_amount"><?php _e('Expires In', 'paid-memberships-pro' );?>:</label></th>
|
576 |
<td>
|
577 |
<input id="expiration_number" name="expiration_number" type="text" value="<?php echo esc_attr($level->expiration_number);?>" class="small-text" />
|
578 |
<select id="expiration_period" name="expiration_period">
|
579 |
<?php
|
580 |
+
$cycles = array( __('Hour(s)', 'paid-memberships-pro' ) => 'Hour', __('Day(s)', 'paid-memberships-pro' ) => 'Day', __('Week(s)', 'paid-memberships-pro' ) => 'Week', __('Month(s)', 'paid-memberships-pro' ) => 'Month', __('Year(s)', 'paid-memberships-pro' ) => 'Year' );
|
581 |
foreach ( $cycles as $name => $value ) {
|
582 |
+
echo "<option value='$value' ".selected( $level->expiration_period, $value, true ).">$name</option>";
|
|
|
|
|
583 |
}
|
584 |
?>
|
585 |
</select>
|
586 |
<p class="description"><?php _e('Set the duration of membership access. Note that the any future payments (recurring subscription, if any) will be cancelled when the membership expires.', 'paid-memberships-pro' );?></p>
|
587 |
+
|
588 |
<div id="pmpro_expiration_warning" style="display: none;" class="notice error inline">
|
589 |
<p><?php printf( __( 'WARNING: This level is set with both a recurring billing amount and an expiration date. You only need to set one of these unless you really want this membership to expire after a certain number of payments. For more information, <a target="_blank" href="%s">see our post here</a>.', 'paid-memberships-pro' ), 'https://www.paidmembershipspro.com/important-notes-on-recurring-billing-and-expiration-dates-for-membership-levels/?utm_source=plugin&utm_medium=pmpro-membershiplevels&utm_campaign=blog&utm_content=important-notes-on-recurring-billing-and-expiration-dates-for-membership-levels' ); ?></p>
|
590 |
</div>
|
597 |
jQuery('#pmpro_expiration_warning').hide();
|
598 |
}
|
599 |
}
|
600 |
+
|
601 |
pmpro_expirationWarningCheck();
|
602 |
+
|
603 |
jQuery('#recurring,#expiration').change(function() { pmpro_expirationWarningCheck(); });
|
604 |
});
|
605 |
</script>
|
608 |
</tbody>
|
609 |
</table>
|
610 |
|
611 |
+
<?php
|
612 |
+
/**
|
613 |
+
* Allow adding form fields after the Other Settings section.
|
614 |
+
*
|
615 |
+
* @since 2.5.10
|
616 |
+
*
|
617 |
+
* @param object $level The Membership Level object.
|
618 |
+
*/
|
619 |
+
do_action( 'pmpro_membership_level_after_other_settings', $level );
|
620 |
+
?>
|
621 |
|
622 |
<hr />
|
623 |
|
658 |
</tr>
|
659 |
</tbody>
|
660 |
</table>
|
661 |
+
|
662 |
+
<?php
|
663 |
+
/**
|
664 |
+
* Allow adding form fields after the Content Settings section.
|
665 |
+
*
|
666 |
+
* @since 2.5.10
|
667 |
+
*
|
668 |
+
* @param object $level The Membership Level object.
|
669 |
+
*/
|
670 |
+
do_action( 'pmpro_membership_level_after_content_settings', $level );
|
671 |
+
?>
|
672 |
+
|
673 |
<p class="submit topborder">
|
674 |
<input name="save" type="submit" class="button button-primary" value="<?php _e('Save Level', 'paid-memberships-pro' ); ?>" />
|
675 |
+
<input name="cancel" type="button" class="button" value="<?php _e('Cancel', 'paid-memberships-pro' ); ?>" onclick="location.href='<?php echo add_query_arg( 'page', 'pmpro-membershiplevels' , admin_url( '/admin.php') ); ?>';" />
|
676 |
</p>
|
677 |
</form>
|
678 |
</div>
|
790 |
</p>
|
791 |
</form>
|
792 |
<h1 class="wp-heading-inline"><?php esc_html_e( 'Membership Levels', 'paid-memberships-pro' ); ?></h1>
|
793 |
+
<a href="<?php echo add_query_arg( array( 'page' => 'pmpro-membershiplevels', 'edit' => -1 ), admin_url( 'admin.php' ) ); ?>" class="page-title-action"><?php esc_html_e( 'Add New Level', 'paid-memberships-pro' ); ?></a>
|
794 |
<hr class="wp-header-end">
|
795 |
|
796 |
<?php if(empty($_REQUEST['s']) && count($reordered_levels) > 1) { ?>
|
818 |
<td colspan="5">
|
819 |
<?php echo esc_attr_e( 'No Membership Levels Found', 'paid-memberships-pro' ); ?>
|
820 |
</td>
|
821 |
+
</tr>
|
822 |
<?php } ?>
|
823 |
<?php
|
824 |
$count = 0;
|
830 |
<td class="level_name has-row-actions">
|
831 |
<span class="level-name"><a href="<?php echo add_query_arg( array( 'page' => 'pmpro-membershiplevels', 'edit' => $level->id ), admin_url( 'admin.php' ) ); ?>"><?php esc_attr_e( $level->name ); ?></a></span>
|
832 |
<div class="row-actions">
|
833 |
+
<?php
|
834 |
+
$delete_text = esc_html(
|
835 |
+
sprintf(
|
836 |
+
// translators: %s is the Level Name.
|
837 |
+
__( 'Are you sure you want to delete membership level %s? All subscriptions will be cancelled.', 'paid-memberships-pro' ),
|
838 |
+
$level->name
|
839 |
+
)
|
840 |
+
);
|
841 |
+
|
842 |
+
$delete_nonce_url = wp_nonce_url(
|
843 |
+
add_query_arg(
|
844 |
+
[
|
845 |
+
'page' => 'pmpro-membershiplevels',
|
846 |
+
'action' => 'delete_membership_level',
|
847 |
+
'deleteid' => $level->id,
|
848 |
+
],
|
849 |
+
admin_url( 'admin.php' )
|
850 |
+
),
|
851 |
+
'delete_membership_level',
|
852 |
+
'pmpro_membershiplevels_nonce'
|
853 |
+
);
|
854 |
+
|
855 |
+
$actions = [
|
856 |
+
'edit' => sprintf(
|
857 |
+
'<a title="%1$s" href="%2$s">%3$s</a>',
|
858 |
+
esc_attr__( 'Edit', 'paid-memberships-pro' ),
|
859 |
+
esc_url(
|
860 |
+
add_query_arg(
|
861 |
+
[
|
862 |
+
'page' => 'pmpro-membershiplevels',
|
863 |
+
'edit' => $level->id,
|
864 |
+
],
|
865 |
+
admin_url( 'admin.php' )
|
866 |
+
)
|
867 |
+
),
|
868 |
+
esc_html__( 'Edit', 'paid-memberships-pro' )
|
869 |
+
),
|
870 |
+
'copy' => sprintf(
|
871 |
+
'<a title="%1$s" href="%2$s">%3$s</a>',
|
872 |
+
esc_attr__( 'Copy', 'paid-memberships-pro' ),
|
873 |
+
esc_url(
|
874 |
+
add_query_arg(
|
875 |
+
[
|
876 |
+
'page' => 'pmpro-membershiplevels',
|
877 |
+
'edit' => - 1,
|
878 |
+
'copy' => $level->id,
|
879 |
+
],
|
880 |
+
admin_url( 'admin.php' )
|
881 |
+
)
|
882 |
+
),
|
883 |
+
esc_html__( 'Copy', 'paid-memberships-pro' )
|
884 |
+
),
|
885 |
+
'delete' => sprintf(
|
886 |
+
'<a title="%1$s" href="%2$s">%3$s</a>',
|
887 |
+
esc_attr__( 'Delete', 'paid-memberships-pro' ),
|
888 |
+
'javascript:pmpro_askfirst(\'' . esc_js( $delete_text ) . '\', \'' . esc_js( $delete_nonce_url ) . '\'); void(0);',
|
889 |
+
esc_html__( 'Delete', 'paid-memberships-pro' )
|
890 |
+
),
|
891 |
+
];
|
892 |
+
|
893 |
+
/**
|
894 |
+
* Filter the extra actions for this level.
|
895 |
+
*
|
896 |
+
* @since 2.6.2
|
897 |
+
*
|
898 |
+
* @param array $actions The list of actions.
|
899 |
+
* @param object $level The membership level data.
|
900 |
+
*/
|
901 |
+
$actions = apply_filters( 'pmpro_membershiplevels_row_actions', $actions, $level );
|
902 |
+
|
903 |
+
$actions_html = [];
|
904 |
+
|
905 |
+
foreach ( $actions as $action => $link ) {
|
906 |
+
$actions_html[] = sprintf(
|
907 |
+
'<span class="%1$s">%2$s</span>',
|
908 |
+
esc_attr( $action ),
|
909 |
+
$link
|
910 |
+
);
|
911 |
+
}
|
912 |
+
|
913 |
+
if ( ! empty( $actions_html ) ) {
|
914 |
+
echo implode( ' | ', $actions_html );
|
915 |
+
}
|
916 |
+
?>
|
917 |
</div>
|
918 |
</td>
|
919 |
<td>
|
930 |
<?php _e('After', 'paid-memberships-pro' );?> <?php echo $level->expiration_number?> <?php echo sornot($level->expiration_period,$level->expiration_number)?>
|
931 |
<?php } ?>
|
932 |
</td>
|
933 |
+
<td><?php
|
934 |
+
if($level->allow_signups) {
|
935 |
+
if ( ! empty( $pmpro_pages['checkout'] ) ) {
|
936 |
+
?><a target="_blank" href="<?php echo add_query_arg( 'level', $level->id, pmpro_url("checkout") );?>"><?php _e('Yes', 'paid-memberships-pro' );?></a><?php
|
937 |
+
} else {
|
938 |
+
_e('Yes', 'paid-memberships-pro' );
|
939 |
+
}
|
940 |
+
} else {
|
941 |
+
_e('No', 'paid-memberships-pro' );
|
942 |
+
}
|
943 |
+
?></td>
|
944 |
<?php do_action( 'pmpro_membership_levels_table_extra_cols_body', $level ); ?>
|
945 |
</tr>
|
946 |
<?php
|
adminpages/memberslist.php
CHANGED
@@ -23,7 +23,7 @@ if ( isset( $_REQUEST['l'] ) ) {
|
|
23 |
|
24 |
<?php do_action( 'pmpro_memberslist_before_table' ); ?>
|
25 |
<form id="member-list-form" method="get">
|
26 |
-
<input type="hidden" name="page" value="
|
27 |
<?php
|
28 |
$user_list_table->search_box( __( 'Search Members', 'paid-memberships-pro' ), 'paid-memberships-pro' );
|
29 |
$user_list_table->display();
|
23 |
|
24 |
<?php do_action( 'pmpro_memberslist_before_table' ); ?>
|
25 |
<form id="member-list-form" method="get">
|
26 |
+
<input type="hidden" name="page" value="pmpro-memberslist" />
|
27 |
<?php
|
28 |
$user_list_table->search_box( __( 'Search Members', 'paid-memberships-pro' ), 'paid-memberships-pro' );
|
29 |
$user_list_table->display();
|
adminpages/orders-csv.php
CHANGED
@@ -330,6 +330,14 @@ $default_columns = array(
|
|
330 |
array( "discount_code", "code" )
|
331 |
);
|
332 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
333 |
$default_columns = apply_filters( "pmpro_order_list_csv_default_columns", $default_columns );
|
334 |
|
335 |
$csv_file_header_array = apply_filters( "pmpro_order_list_csv_export_header_array", $csv_file_header_array );
|
330 |
array( "discount_code", "code" )
|
331 |
);
|
332 |
|
333 |
+
// Hiding couponamount by default.
|
334 |
+
$coupons = apply_filters( 'pmpro_orders_show_coupon_amounts', false );
|
335 |
+
if ( empty( $coupons ) ) {
|
336 |
+
$csv_file_header_array = array_diff( $csv_file_header_array, array( 'couponamount' ) );
|
337 |
+
$couponamount_array_key = array_keys( $default_columns, array( 'order', 'couponamount' ) );
|
338 |
+
unset( $default_columns[ $couponamount_array_key[0] ] );
|
339 |
+
}
|
340 |
+
|
341 |
$default_columns = apply_filters( "pmpro_order_list_csv_default_columns", $default_columns );
|
342 |
|
343 |
$csv_file_header_array = apply_filters( "pmpro_order_list_csv_export_header_array", $csv_file_header_array );
|
adminpages/orders.php
CHANGED
@@ -21,8 +21,8 @@ if ( isset( $_REQUEST['l'] ) ) {
|
|
21 |
$l = false;
|
22 |
}
|
23 |
|
24 |
-
if ( isset( $_REQUEST['
|
25 |
-
$discount_code = intval( $_REQUEST['
|
26 |
} else {
|
27 |
$discount_code = false;
|
28 |
}
|
@@ -156,8 +156,14 @@ $condition = apply_filters( 'pmpro_admin_orders_query_condition', $condition, $f
|
|
156 |
|
157 |
// deleting?
|
158 |
if ( ! empty( $_REQUEST['delete'] ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
$dorder = new MemberOrder( intval( $_REQUEST['delete'] ) );
|
160 |
-
if ( $dorder->deleteMe() ) {
|
161 |
$pmpro_msg = __( 'Order deleted successfully.', 'paid-memberships-pro' );
|
162 |
$pmpro_msgt = 'success';
|
163 |
} else {
|
@@ -230,9 +236,15 @@ if ( ! empty( $_REQUEST['save'] ) ) {
|
|
230 |
if ( ! in_array( 'tax', $read_only_fields ) && isset( $_POST['tax'] ) ) {
|
231 |
$order->tax = sanitize_text_field( $_POST['tax'] );
|
232 |
}
|
233 |
-
|
234 |
-
|
|
|
|
|
|
|
|
|
|
|
235 |
}
|
|
|
236 |
if ( ! in_array( 'total', $read_only_fields ) && isset( $_POST['total'] ) ) {
|
237 |
$order->total = sanitize_text_field( $_POST['total'] );
|
238 |
}
|
@@ -271,6 +283,14 @@ if ( ! empty( $_REQUEST['save'] ) ) {
|
|
271 |
global $allowedposttags;
|
272 |
$order->notes = wp_kses( wp_unslash( $_REQUEST['notes'] ), $allowedposttags );
|
273 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
|
275 |
// affiliate stuff
|
276 |
$affiliates = apply_filters( 'pmpro_orders_show_affiliate_ids', false );
|
@@ -290,22 +310,15 @@ if ( ! empty( $_REQUEST['save'] ) ) {
|
|
290 |
}
|
291 |
|
292 |
// save
|
293 |
-
if ( $
|
294 |
$order_id = $order->id;
|
295 |
-
|
296 |
-
|
297 |
-
if ( $order->updateTimestamp( intval( $_POST['ts_year'] ), intval( $_POST['ts_month'] ), intval( $_POST['ts_day'] ), intval( $_POST['ts_hour'] ) . ':' . intval( $_POST['ts_minute'] ) . ':00' ) !== false ) {
|
298 |
-
$pmpro_msg = __( 'Order saved successfully.', 'paid-memberships-pro' );
|
299 |
-
$pmpro_msgt = 'success';
|
300 |
-
} else {
|
301 |
-
$pmpro_msg = __( 'Error updating order timestamp.', 'paid-memberships-pro' );
|
302 |
-
$pmpro_msgt = 'error';
|
303 |
-
}
|
304 |
} else {
|
305 |
$pmpro_msg = __( 'Error saving order.', 'paid-memberships-pro' );
|
306 |
$pmpro_msgt = 'error';
|
307 |
}
|
308 |
-
|
309 |
// also update the discount code if needed
|
310 |
if( isset( $_REQUEST['discount_code_id'] ) ) {
|
311 |
$order->updateDiscountCode( intval( $_REQUEST['discount_code_id'] ) );
|
@@ -419,7 +432,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
419 |
echo esc_html( $order->code );
|
420 |
} else { ?>
|
421 |
<input id="code" name="code" type="text" value="<?php echo esc_attr( $order->code ); ?>" class="regular-text" />
|
422 |
-
<?php
|
423 |
}
|
424 |
?>
|
425 |
<?php if ( $order_id < 0 ) { ?>
|
@@ -435,7 +448,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
435 |
echo esc_html( $order->user_id );
|
436 |
} else { ?>
|
437 |
<input id="user_id" name="user_id" type="text" value="<?php echo esc_attr( $order->user_id ); ?>" class="regular-text" />
|
438 |
-
<?php
|
439 |
}
|
440 |
?>
|
441 |
</td>
|
@@ -448,7 +461,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
448 |
echo esc_html( $order->membership_id );
|
449 |
} else { ?>
|
450 |
<input id="membership_id" name="membership_id" type="text" value="<?php echo esc_attr( $order->membership_id ); ?>" class="regular-text" />
|
451 |
-
<?php
|
452 |
}
|
453 |
?>
|
454 |
</td>
|
@@ -468,8 +481,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
468 |
</td>
|
469 |
</tr>
|
470 |
<tr>
|
471 |
-
<th scope="row" valign="top"><label for="billing_street"><?php esc_html_e( 'Billing Street', 'paid-memberships-pro' );
|
472 |
-
:</label></th>
|
473 |
<td>
|
474 |
<?php
|
475 |
if ( in_array( 'billing_street', $read_only_fields ) && $order_id > 0 ) {
|
@@ -494,8 +506,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
494 |
<?php } ?>
|
495 |
</tr>
|
496 |
<tr>
|
497 |
-
<th scope="row" valign="top"><label for="billing_state"><?php esc_html_e( 'Billing State', 'paid-memberships-pro' );
|
498 |
-
:</label></th>
|
499 |
<td>
|
500 |
<?php
|
501 |
if ( in_array( 'billing_state', $read_only_fields ) && $order_id > 0 ) {
|
@@ -507,8 +518,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
507 |
<?php } ?>
|
508 |
</tr>
|
509 |
<tr>
|
510 |
-
<th scope="row" valign="top"><label for="billing_zip"><?php esc_html_e( 'Billing Postal Code', 'paid-memberships-pro' );
|
511 |
-
:</label></th>
|
512 |
<td>
|
513 |
<?php
|
514 |
if ( in_array( 'billing_zip', $read_only_fields ) && $order_id > 0 ) {
|
@@ -520,8 +530,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
520 |
<?php } ?>
|
521 |
</tr>
|
522 |
<tr>
|
523 |
-
<th scope="row" valign="top"><label for="billing_country"><?php esc_html_e( 'Billing Country', 'paid-memberships-pro' );
|
524 |
-
:</label></th>
|
525 |
<td>
|
526 |
<?php
|
527 |
if ( in_array( 'billing_country', $read_only_fields ) && $order_id > 0 ) {
|
@@ -534,8 +543,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
534 |
</td>
|
535 |
</tr>
|
536 |
<tr>
|
537 |
-
<th scope="row" valign="top"><label for="billing_phone"><?php esc_html_e( 'Billing Phone', 'paid-memberships-pro' );
|
538 |
-
:</label></th>
|
539 |
<td>
|
540 |
<?php
|
541 |
if ( in_array( 'billing_phone', $read_only_fields ) && $order_id > 0 ) {
|
@@ -611,19 +619,28 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
611 |
<?php } ?>
|
612 |
</td>
|
613 |
</tr>
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
|
|
|
|
|
|
|
|
618 |
<?php
|
619 |
-
|
620 |
-
|
621 |
-
|
|
|
|
|
|
|
|
|
622 |
?>
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
|
|
627 |
<tr>
|
628 |
<th scope="row" valign="top"><label for="total"><?php esc_html_e( 'Total', 'paid-memberships-pro' ); ?>:</label></th>
|
629 |
<td>
|
@@ -635,7 +652,6 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
635 |
<input id="total" name="total" type="text" size="10"
|
636 |
value="<?php echo esc_attr( $order->total ); ?>"/>
|
637 |
<?php } ?>
|
638 |
-
<p class="description"><?php esc_html_e( 'Should be subtotal + tax - couponamount.', 'paid-memberships-pro' ); ?></p>
|
639 |
</td>
|
640 |
</tr>
|
641 |
|
@@ -655,7 +671,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
655 |
</td>
|
656 |
</tr>
|
657 |
<tr>
|
658 |
-
<th scope="row" valign="top"><label for="cardtype"><?php esc_html_e( 'Card Type', 'paid-memberships-pro' );
|
659 |
<td>
|
660 |
<?php
|
661 |
if ( in_array( 'cardtype', $read_only_fields ) && $order_id > 0 ) {
|
@@ -669,8 +685,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
669 |
</td>
|
670 |
</tr>
|
671 |
<tr>
|
672 |
-
<th scope="row" valign="top"><label for="accountnumber"><?php esc_html_e( 'Account Number', 'paid-memberships-pro' );
|
673 |
-
:</label></th>
|
674 |
<td>
|
675 |
<?php
|
676 |
if ( in_array( 'accountnumber', $read_only_fields ) && $order_id > 0 ) {
|
@@ -708,8 +723,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
708 |
</td>
|
709 |
</tr>
|
710 |
<tr>
|
711 |
-
<th scope="row" valign="top"><label for="expirationyear"><?php esc_html_e( 'Expiration Year', 'paid-memberships-pro' );
|
712 |
-
:</label></th>
|
713 |
<td>
|
714 |
<input id="expirationyear" name="expirationyear" type="text" size="10"
|
715 |
value="<?php echo esc_attr( $order->expirationyear ); ?>"/>
|
@@ -733,8 +747,8 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
733 |
value="<?php echo esc_attr( $status ); ?>" <?php selected( $order->status, $status ); ?>><?php echo esc_html( $status ); ?></option>
|
734 |
<?php } ?>
|
735 |
</select>
|
736 |
-
<?php
|
737 |
-
}
|
738 |
?>
|
739 |
</td>
|
740 |
</tr>
|
@@ -795,8 +809,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
795 |
</tr>
|
796 |
<tr>
|
797 |
<th scope="row" valign="top"><label
|
798 |
-
for="subscription_transaction_id"><?php esc_html_e( 'Subscription Transaction ID', 'paid-memberships-pro' );
|
799 |
-
:</label></th>
|
800 |
<td>
|
801 |
<?php
|
802 |
if ( in_array( 'subscription_transaction_id', $read_only_fields ) && $order_id > 0 ) {
|
@@ -823,7 +836,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
823 |
} else {
|
824 |
$timestamp = current_time( 'timestamp' );
|
825 |
}
|
826 |
-
|
827 |
$year = date( 'Y', $timestamp );
|
828 |
$month = date( 'n', $timestamp );
|
829 |
$day = date( 'j', $timestamp );
|
@@ -908,7 +921,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
908 |
<th scope="row" valign="top"><label for="notes"><?php esc_html_e( 'Notes', 'paid-memberships-pro' ); ?>:</label></th>
|
909 |
<td>
|
910 |
<?php
|
911 |
-
if ( in_array( 'notes', $read_only_fields ) && $order_id > 0 ) {
|
912 |
echo wp_kses_post( $order->notes );
|
913 |
} else {
|
914 |
?>
|
@@ -922,6 +935,17 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
922 |
</tbody>
|
923 |
</table>
|
924 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
925 |
<p class="submit topborder">
|
926 |
<input name="order" type="hidden" value="
|
927 |
<?php
|
@@ -934,7 +958,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
934 |
"/>
|
935 |
<input name="save" type="submit" class="button-primary" value="<?php esc_attr_e( 'Save Order', 'paid-memberships-pro' ); ?>"/>
|
936 |
<input name="cancel" type="button" class="cancel button-secondary" value="<?php esc_attr_e( 'Cancel', 'paid-memberships-pro' ); ?>"
|
937 |
-
onclick="location.href='<?php echo esc_url(
|
938 |
</p>
|
939 |
|
940 |
</form>
|
@@ -944,7 +968,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
944 |
<form id="posts-filter" method="get" action="">
|
945 |
|
946 |
<h1 class="wp-heading-inline"><?php esc_html_e( 'Orders', 'paid-memberships-pro' ); ?></h1>
|
947 |
-
<a href="<?php echo esc_url( add_query_arg( array( 'page' => 'pmpro-orders', 'order' => -1 ),
|
948 |
|
949 |
<?php
|
950 |
// build the export URL
|
@@ -966,7 +990,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
966 |
$export_url = add_query_arg( $url_params, $export_url );
|
967 |
?>
|
968 |
<a target="_blank" href="<?php echo esc_url( $export_url ); ?>" class="page-title-action"><?php esc_html_e( 'Export to CSV', 'paid-memberships-pro' ); ?></a>
|
969 |
-
|
970 |
<hr class="wp-header-end">
|
971 |
|
972 |
|
@@ -998,9 +1022,9 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
998 |
value="with-discount-code" <?php selected( $filter, 'with-discount-code' ); ?>><?php esc_html_e( 'With a Discount Code', 'paid-memberships-pro' ); ?></option>
|
999 |
<option
|
1000 |
value="within-a-status" <?php selected( $filter, 'within-a-status' ); ?>><?php esc_html_e( 'Within a Status', 'paid-memberships-pro' ); ?></option>
|
1001 |
-
<option
|
1002 |
value="only-paid" <?php selected( $filter, 'only-paid' ); ?>><?php esc_html_e( 'Only Paid Orders', 'paid-memberships-pro' ); ?></option>
|
1003 |
-
<option
|
1004 |
value="only-free" <?php selected( $filter, 'only-free' ); ?>><?php esc_html_e( 'Only Free Orders', 'paid-memberships-pro' ); ?></option>
|
1005 |
|
1006 |
<?php $custom_filters = apply_filters( 'pmpro_admin_orders_filters', array() ); ?>
|
@@ -1054,7 +1078,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1054 |
|
1055 |
<?php
|
1056 |
// Note: only orders belonging to current levels can be filtered. There is no option for orders belonging to deleted levels
|
1057 |
-
$levels = pmpro_getAllLevels( true, true );
|
1058 |
?>
|
1059 |
<select id="l" name="l">
|
1060 |
<?php foreach ( $levels as $level ) { ?>
|
@@ -1063,13 +1087,13 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1063 |
<?php } ?>
|
1064 |
|
1065 |
</select>
|
1066 |
-
|
1067 |
<?php
|
1068 |
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS * FROM $wpdb->pmpro_discount_codes ";
|
1069 |
$sqlQuery .= "ORDER BY id DESC ";
|
1070 |
$codes = $wpdb->get_results($sqlQuery, OBJECT);
|
1071 |
if ( ! empty( $codes ) ) { ?>
|
1072 |
-
<select id="
|
1073 |
<?php foreach ( $codes as $code ) { ?>
|
1074 |
<option
|
1075 |
value="<?php echo esc_attr( $code->id ); ?>" <?php selected( $discount_code, $code->id ); ?>><?php echo esc_html( $code->code ); ?></option>
|
@@ -1111,7 +1135,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1111 |
jQuery('#predefined-date').hide();
|
1112 |
jQuery('#status').hide();
|
1113 |
jQuery('#l').hide();
|
1114 |
-
jQuery('#
|
1115 |
jQuery('#from').hide();
|
1116 |
jQuery('#to').hide();
|
1117 |
jQuery('#submit').show();
|
@@ -1127,7 +1151,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1127 |
jQuery('#predefined-date').hide();
|
1128 |
jQuery('#status').hide();
|
1129 |
jQuery('#l').hide();
|
1130 |
-
jQuery('#
|
1131 |
jQuery('#submit').show();
|
1132 |
jQuery('#from').show();
|
1133 |
jQuery('#to').show();
|
@@ -1143,7 +1167,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1143 |
jQuery('#predefined-date').show();
|
1144 |
jQuery('#status').hide();
|
1145 |
jQuery('#l').hide();
|
1146 |
-
jQuery('#
|
1147 |
jQuery('#submit').show();
|
1148 |
jQuery('#from').hide();
|
1149 |
jQuery('#to').hide();
|
@@ -1159,7 +1183,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1159 |
jQuery('#predefined-date').hide();
|
1160 |
jQuery('#status').hide();
|
1161 |
jQuery('#l').show();
|
1162 |
-
jQuery('#
|
1163 |
jQuery('#submit').show();
|
1164 |
jQuery('#from').hide();
|
1165 |
jQuery('#to').hide();
|
@@ -1175,7 +1199,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1175 |
jQuery('#predefined-date').hide();
|
1176 |
jQuery('#status').hide();
|
1177 |
jQuery('#l').hide();
|
1178 |
-
jQuery('#
|
1179 |
jQuery('#submit').show();
|
1180 |
jQuery('#from').hide();
|
1181 |
jQuery('#to').hide();
|
@@ -1191,7 +1215,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1191 |
jQuery('#predefined-date').hide();
|
1192 |
jQuery('#status').show();
|
1193 |
jQuery('#l').hide();
|
1194 |
-
jQuery('#
|
1195 |
jQuery('#submit').show();
|
1196 |
jQuery('#from').hide();
|
1197 |
jQuery('#to').hide();
|
@@ -1207,7 +1231,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1207 |
jQuery('#predefined-date').hide();
|
1208 |
jQuery('#status').hide();
|
1209 |
jQuery('#l').hide();
|
1210 |
-
jQuery('#
|
1211 |
jQuery('#submit').show();
|
1212 |
jQuery('#from').hide();
|
1213 |
jQuery('#to').hide();
|
@@ -1223,7 +1247,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1223 |
<p class="search-box">
|
1224 |
<label class="hidden" for="post-search-input"><?php esc_html_e( 'Search Orders', 'paid-memberships-pro' ); ?>:</label>
|
1225 |
<input type="hidden" name="page" value="pmpro-orders"/>
|
1226 |
-
<input id="post-search-input" type="text" value="<?php echo esc_attr( $s ); ?>" name="s"/>
|
1227 |
<input class="button" type="submit" value="<?php esc_attr_e( 'Search Orders', 'paid-memberships-pro' ); ?>"/>
|
1228 |
</p>
|
1229 |
|
@@ -1235,7 +1259,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1235 |
if ( $join_with_usermeta ) {
|
1236 |
$sqlQuery .= "LEFT JOIN $wpdb->usermeta um ON o.user_id = um.user_id ";
|
1237 |
}
|
1238 |
-
|
1239 |
if ( $filter === 'with-discount-code' ) {
|
1240 |
$sqlQuery .= "LEFT JOIN $wpdb->pmpro_discount_codes_uses dc ON o.id = dc.order_id ";
|
1241 |
}
|
@@ -1281,18 +1305,18 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1281 |
$sqlQuery .= 'GROUP BY o.id ORDER BY o.id DESC, o.timestamp DESC ';
|
1282 |
} else {
|
1283 |
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS o.id FROM $wpdb->pmpro_membership_orders o ";
|
1284 |
-
|
1285 |
if ( $filter === 'with-discount-code' ) {
|
1286 |
$sqlQuery .= "LEFT JOIN $wpdb->pmpro_discount_codes_uses dc ON o.id = dc.order_id ";
|
1287 |
}
|
1288 |
-
|
1289 |
$sqlQuery .= "WHERE " . $condition . ' ORDER BY o.id DESC, o.timestamp DESC ';
|
1290 |
}
|
1291 |
|
1292 |
$sqlQuery .= "LIMIT $start, $limit";
|
1293 |
|
1294 |
$order_ids = $wpdb->get_col( $sqlQuery );
|
1295 |
-
|
1296 |
$totalrows = $wpdb->get_var( 'SELECT FOUND_ROWS() as found_rows' );
|
1297 |
|
1298 |
if ( $order_ids ) {
|
@@ -1306,7 +1330,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1306 |
<tr class="thead">
|
1307 |
<th><?php esc_html_e( 'ID', 'paid-memberships-pro' ); ?></th>
|
1308 |
<th><?php esc_html_e( 'Code', 'paid-memberships-pro' ); ?></th>
|
1309 |
-
<th><?php esc_html_e( '
|
1310 |
<?php do_action( 'pmpro_orders_extra_cols_header', $order_ids ); ?>
|
1311 |
<th><?php esc_html_e( 'Level', 'paid-memberships-pro' ); ?></th>
|
1312 |
<th><?php esc_html_e( 'Total', 'paid-memberships-pro' ); ?></th>
|
@@ -1336,36 +1360,108 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1336 |
<a href="admin.php?page=pmpro-orders&order=<?php echo esc_attr( $order->id ); ?>"><?php echo esc_html( $order->code ); ?></a>
|
1337 |
<br />
|
1338 |
<div class="row-actions">
|
1339 |
-
<span class="edit">
|
1340 |
-
<a title="<?php esc_attr_e( 'Edit', 'paid-memberships-pro' ); ?>" href="<?php echo esc_url( add_query_arg( array( 'page' => 'pmpro-orders', 'order' => $order->id ), admin_url('admin.php' ) ) ); ?>"><?php esc_html_e( 'Edit', 'paid-memberships-pro' ); ?></a>
|
1341 |
-
</span> |
|
1342 |
-
<span class="copy">
|
1343 |
-
<a title="<?php esc_attr_e( 'Copy', 'paid-memberships-pro' ); ?>" href="<?php echo esc_url( add_query_arg( array( 'page' => 'pmpro-orders', 'order' => '-1', 'copy' => $order->id ), admin_url('admin.php' ) ) ); ?>"><?php esc_html_e( 'Copy', 'paid-memberships-pro' ); ?></a>
|
1344 |
-
</span> |
|
1345 |
-
<span class="delete">
|
1346 |
-
<a href="javascript:pmpro_askfirst('<?php echo esc_attr
|
1347 |
-
( sprintf( __( 'Deleting orders is permanent and can affect active users. Are you sure you want to delete order %s?', 'paid-memberships-pro' ), str_replace( "'", '', $order->code ) ) ); ?>', 'admin.php?page=pmpro-orders&delete=<?php echo $order->id; ?>'); void(0);"><?php esc_html_e( 'Delete', 'paid-memberships-pro' ); ?></a>
|
1348 |
-
</span> |
|
1349 |
-
<span class="print">
|
1350 |
-
<a target="_blank" title="<?php esc_attr_e( 'Print', 'paid-memberships-pro' ); ?>" href="<?php echo esc_url( add_query_arg( array( 'action' => 'pmpro_orders_print_view', 'order' => $order->id ), admin_url('admin-ajax.php' ) ) ); ?>"><?php esc_html_e( 'Print', 'paid-memberships-pro' ); ?></a>
|
1351 |
-
</span> |
|
1352 |
-
<span class="email">
|
1353 |
-
<a href="#TB_inline?width=600&height=200&inlineId=email_invoice" class="thickbox email_link"
|
1354 |
-
data-order="<?php echo esc_attr( $order->id ); ?>"><?php esc_html_e( 'Email', 'paid-memberships-pro' ); ?></a>
|
1355 |
-
</span>
|
1356 |
<?php
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
1361 |
-
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1369 |
}
|
1370 |
?>
|
1371 |
</div>
|
@@ -1373,12 +1469,13 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1373 |
<td class="username column-username">
|
1374 |
<?php $order->getUser(); ?>
|
1375 |
<?php if ( ! empty( $order->user ) ) { ?>
|
1376 |
-
<a href="user-edit.php?user_id=<?php echo esc_attr( $order->user->ID ); ?>"><?php echo esc_html( $order->user->user_login ); ?></a
|
|
|
1377 |
<?php } elseif ( $order->user_id > 0 ) { ?>
|
1378 |
[<?php esc_html_e( 'deleted', 'paid-memberships-pro' ); ?>]
|
1379 |
<?php } else { ?>
|
1380 |
[<?php esc_html_e( 'none', 'paid-memberships-pro' ); ?>]
|
1381 |
-
<?php } ?>
|
1382 |
</td>
|
1383 |
<?php do_action( 'pmpro_orders_extra_cols_body', $order ); ?>
|
1384 |
<td>
|
@@ -1393,7 +1490,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1393 |
<?php }
|
1394 |
?>
|
1395 |
</td>
|
1396 |
-
<td><?php echo
|
1397 |
<td>
|
1398 |
<?php
|
1399 |
if ( ! empty( $order->payment_type ) ) {
|
@@ -1409,7 +1506,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1409 |
<?php if ( ! empty( $order->billing->street ) ) { ?>
|
1410 |
<?php echo esc_html( $order->billing->street ); ?><br/>
|
1411 |
<?php if ( $order->billing->city && $order->billing->state ) { ?>
|
1412 |
-
<?php echo esc_html( $order->billing->city ); ?>, <?php echo esc_html( $order->billing->state );
|
1413 |
<?php
|
1414 |
if ( ! empty( $order->billing->country ) ) {
|
1415 |
echo esc_html( $order->billing->country ); }
|
@@ -1431,7 +1528,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1431 |
?>
|
1432 |
</td>
|
1433 |
<td>
|
1434 |
-
<?php esc_html_e( 'Payment', 'paid-memberships-pro' ); ?>:
|
1435 |
<?php
|
1436 |
if ( ! empty( $order->payment_transaction_id ) ) {
|
1437 |
echo esc_html( $order->payment_transaction_id );
|
@@ -1440,8 +1537,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1440 |
}
|
1441 |
?>
|
1442 |
<br/>
|
1443 |
-
<?php esc_html_e( 'Subscription', 'paid-memberships-pro' );
|
1444 |
-
:
|
1445 |
<?php
|
1446 |
if ( ! empty( $order->subscription_transaction_id ) ) {
|
1447 |
echo esc_html( $order->subscription_transaction_id );
|
@@ -1460,7 +1556,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1460 |
<a title="<?php esc_attr_e('edit', 'paid-memberships-pro' ); ?>" href="<?php echo esc_url( add_query_arg( array( 'page' => 'pmpro-discountcodes', 'edit' => $order->discount_code->id ), admin_url('admin.php' ) ) ); ?>">
|
1461 |
<?php echo esc_html( $order->discount_code->code ); ?>
|
1462 |
</a>
|
1463 |
-
<?php } ?>
|
1464 |
</td>
|
1465 |
</tr>
|
1466 |
<?php
|
@@ -1479,7 +1575,7 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1479 |
</form>
|
1480 |
<?php
|
1481 |
// add normal args
|
1482 |
-
$pagination_url = esc_url( add_query_arg( $url_params,
|
1483 |
echo pmpro_getPaginationString( $pn, $totalrows, $limit, 1, $pagination_url, "&limit=$limit&pn=" );
|
1484 |
?>
|
1485 |
|
21 |
$l = false;
|
22 |
}
|
23 |
|
24 |
+
if ( isset( $_REQUEST['discount-code'] ) ) {
|
25 |
+
$discount_code = intval( $_REQUEST['discount-code'] );
|
26 |
} else {
|
27 |
$discount_code = false;
|
28 |
}
|
156 |
|
157 |
// deleting?
|
158 |
if ( ! empty( $_REQUEST['delete'] ) ) {
|
159 |
+
// Check nonce for deleting.
|
160 |
+
$nonceokay = true;
|
161 |
+
if ( empty( $_REQUEST['pmpro_orders_nonce'] ) || ! check_admin_referer( 'delete_order', 'pmpro_orders_nonce' ) ) {
|
162 |
+
$nonceokay = false;
|
163 |
+
}
|
164 |
+
|
165 |
$dorder = new MemberOrder( intval( $_REQUEST['delete'] ) );
|
166 |
+
if ( $nonceokay && $dorder->deleteMe() ) {
|
167 |
$pmpro_msg = __( 'Order deleted successfully.', 'paid-memberships-pro' );
|
168 |
$pmpro_msgt = 'success';
|
169 |
} else {
|
236 |
if ( ! in_array( 'tax', $read_only_fields ) && isset( $_POST['tax'] ) ) {
|
237 |
$order->tax = sanitize_text_field( $_POST['tax'] );
|
238 |
}
|
239 |
+
|
240 |
+
// Hiding couponamount by default.
|
241 |
+
$coupons = apply_filters( 'pmpro_orders_show_coupon_amounts', false );
|
242 |
+
if ( ! empty( $coupons ) ) {
|
243 |
+
if ( ! in_array( 'couponamount', $read_only_fields ) && isset( $_POST['couponamount'] ) ) {
|
244 |
+
$order->couponamount = sanitize_text_field( $_POST['couponamount'] );
|
245 |
+
}
|
246 |
}
|
247 |
+
|
248 |
if ( ! in_array( 'total', $read_only_fields ) && isset( $_POST['total'] ) ) {
|
249 |
$order->total = sanitize_text_field( $_POST['total'] );
|
250 |
}
|
283 |
global $allowedposttags;
|
284 |
$order->notes = wp_kses( wp_unslash( $_REQUEST['notes'] ), $allowedposttags );
|
285 |
}
|
286 |
+
if ( ! in_array( 'timestamp', $read_only_fields ) && isset( $_POST['ts_year'] ) && isset( $_POST['ts_month'] ) && isset( $_POST['ts_day'] ) && isset( $_POST['ts_hour'] ) && isset( $_POST['ts_minute'] ) ) {
|
287 |
+
$year = intval( $_POST['ts_year'] );
|
288 |
+
$month = intval( $_POST['ts_month'] );
|
289 |
+
$day = intval( $_POST['ts_day'] );
|
290 |
+
$hour = intval( $_POST['ts_hour'] );
|
291 |
+
$minute = intval( $_POST['ts_minute'] );
|
292 |
+
$order->timestamp = $date = get_gmt_from_date( $year . '-' . $month . '-' . $day . ' ' . $hour . ':' . $minute . ':00' , 'U' );;
|
293 |
+
}
|
294 |
|
295 |
// affiliate stuff
|
296 |
$affiliates = apply_filters( 'pmpro_orders_show_affiliate_ids', false );
|
310 |
}
|
311 |
|
312 |
// save
|
313 |
+
if ( $nonceokay && false !== $order->saveOrder() ) {
|
314 |
$order_id = $order->id;
|
315 |
+
$pmpro_msg = __( 'Order saved successfully.', 'paid-memberships-pro' );
|
316 |
+
$pmpro_msgt = 'success';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
317 |
} else {
|
318 |
$pmpro_msg = __( 'Error saving order.', 'paid-memberships-pro' );
|
319 |
$pmpro_msgt = 'error';
|
320 |
}
|
321 |
+
|
322 |
// also update the discount code if needed
|
323 |
if( isset( $_REQUEST['discount_code_id'] ) ) {
|
324 |
$order->updateDiscountCode( intval( $_REQUEST['discount_code_id'] ) );
|
432 |
echo esc_html( $order->code );
|
433 |
} else { ?>
|
434 |
<input id="code" name="code" type="text" value="<?php echo esc_attr( $order->code ); ?>" class="regular-text" />
|
435 |
+
<?php
|
436 |
}
|
437 |
?>
|
438 |
<?php if ( $order_id < 0 ) { ?>
|
448 |
echo esc_html( $order->user_id );
|
449 |
} else { ?>
|
450 |
<input id="user_id" name="user_id" type="text" value="<?php echo esc_attr( $order->user_id ); ?>" class="regular-text" />
|
451 |
+
<?php
|
452 |
}
|
453 |
?>
|
454 |
</td>
|
461 |
echo esc_html( $order->membership_id );
|
462 |
} else { ?>
|
463 |
<input id="membership_id" name="membership_id" type="text" value="<?php echo esc_attr( $order->membership_id ); ?>" class="regular-text" />
|
464 |
+
<?php
|
465 |
}
|
466 |
?>
|
467 |
</td>
|
481 |
</td>
|
482 |
</tr>
|
483 |
<tr>
|
484 |
+
<th scope="row" valign="top"><label for="billing_street"><?php esc_html_e( 'Billing Street', 'paid-memberships-pro' ); ?>:</label></th>
|
|
|
485 |
<td>
|
486 |
<?php
|
487 |
if ( in_array( 'billing_street', $read_only_fields ) && $order_id > 0 ) {
|
506 |
<?php } ?>
|
507 |
</tr>
|
508 |
<tr>
|
509 |
+
<th scope="row" valign="top"><label for="billing_state"><?php esc_html_e( 'Billing State', 'paid-memberships-pro' ); ?>:</label></th>
|
|
|
510 |
<td>
|
511 |
<?php
|
512 |
if ( in_array( 'billing_state', $read_only_fields ) && $order_id > 0 ) {
|
518 |
<?php } ?>
|
519 |
</tr>
|
520 |
<tr>
|
521 |
+
<th scope="row" valign="top"><label for="billing_zip"><?php esc_html_e( 'Billing Postal Code', 'paid-memberships-pro' ); ?>:</label></th>
|
|
|
522 |
<td>
|
523 |
<?php
|
524 |
if ( in_array( 'billing_zip', $read_only_fields ) && $order_id > 0 ) {
|
530 |
<?php } ?>
|
531 |
</tr>
|
532 |
<tr>
|
533 |
+
<th scope="row" valign="top"><label for="billing_country"><?php esc_html_e( 'Billing Country', 'paid-memberships-pro' ); ?>:</label></th>
|
|
|
534 |
<td>
|
535 |
<?php
|
536 |
if ( in_array( 'billing_country', $read_only_fields ) && $order_id > 0 ) {
|
543 |
</td>
|
544 |
</tr>
|
545 |
<tr>
|
546 |
+
<th scope="row" valign="top"><label for="billing_phone"><?php esc_html_e( 'Billing Phone', 'paid-memberships-pro' ); ?>:</label></th>
|
|
|
547 |
<td>
|
548 |
<?php
|
549 |
if ( in_array( 'billing_phone', $read_only_fields ) && $order_id > 0 ) {
|
619 |
<?php } ?>
|
620 |
</td>
|
621 |
</tr>
|
622 |
+
<?php
|
623 |
+
// Hiding couponamount by default.
|
624 |
+
$coupons = apply_filters( 'pmpro_orders_show_coupon_amounts', false );
|
625 |
+
if ( ! empty( $coupons ) ) { ?>
|
626 |
+
<tr>
|
627 |
+
<th scope="row" valign="top"><label for="couponamount"><?php esc_html_e( 'Coupon Amount', 'paid-memberships-pro' ); ?>:</label>
|
628 |
+
</th>
|
629 |
+
<td>
|
630 |
<?php
|
631 |
+
if ( in_array( 'couponamount', $read_only_fields ) && $order_id > 0 ) {
|
632 |
+
echo $order->couponamount;
|
633 |
+
} else {
|
634 |
+
?>
|
635 |
+
<input id="couponamount" name="couponamount" type="text" size="10" value="<?php echo esc_attr( $order->couponamount ); ?>"/>
|
636 |
+
<?php
|
637 |
+
}
|
638 |
?>
|
639 |
+
</td>
|
640 |
+
</tr>
|
641 |
+
<?php
|
642 |
+
}
|
643 |
+
?>
|
644 |
<tr>
|
645 |
<th scope="row" valign="top"><label for="total"><?php esc_html_e( 'Total', 'paid-memberships-pro' ); ?>:</label></th>
|
646 |
<td>
|
652 |
<input id="total" name="total" type="text" size="10"
|
653 |
value="<?php echo esc_attr( $order->total ); ?>"/>
|
654 |
<?php } ?>
|
|
|
655 |
</td>
|
656 |
</tr>
|
657 |
|
671 |
</td>
|
672 |
</tr>
|
673 |
<tr>
|
674 |
+
<th scope="row" valign="top"><label for="cardtype"><?php esc_html_e( 'Card Type', 'paid-memberships-pro' ); ?>:</label></th>
|
675 |
<td>
|
676 |
<?php
|
677 |
if ( in_array( 'cardtype', $read_only_fields ) && $order_id > 0 ) {
|
685 |
</td>
|
686 |
</tr>
|
687 |
<tr>
|
688 |
+
<th scope="row" valign="top"><label for="accountnumber"><?php esc_html_e( 'Account Number', 'paid-memberships-pro' ); ?>:</label></th>
|
|
|
689 |
<td>
|
690 |
<?php
|
691 |
if ( in_array( 'accountnumber', $read_only_fields ) && $order_id > 0 ) {
|
723 |
</td>
|
724 |
</tr>
|
725 |
<tr>
|
726 |
+
<th scope="row" valign="top"><label for="expirationyear"><?php esc_html_e( 'Expiration Year', 'paid-memberships-pro' ); ?>:</label></th>
|
|
|
727 |
<td>
|
728 |
<input id="expirationyear" name="expirationyear" type="text" size="10"
|
729 |
value="<?php echo esc_attr( $order->expirationyear ); ?>"/>
|
747 |
value="<?php echo esc_attr( $status ); ?>" <?php selected( $order->status, $status ); ?>><?php echo esc_html( $status ); ?></option>
|
748 |
<?php } ?>
|
749 |
</select>
|
750 |
+
<?php
|
751 |
+
}
|
752 |
?>
|
753 |
</td>
|
754 |
</tr>
|
809 |
</tr>
|
810 |
<tr>
|
811 |
<th scope="row" valign="top"><label
|
812 |
+
for="subscription_transaction_id"><?php esc_html_e( 'Subscription Transaction ID', 'paid-memberships-pro' ); ?>:</label></th>
|
|
|
813 |
<td>
|
814 |
<?php
|
815 |
if ( in_array( 'subscription_transaction_id', $read_only_fields ) && $order_id > 0 ) {
|
836 |
} else {
|
837 |
$timestamp = current_time( 'timestamp' );
|
838 |
}
|
839 |
+
|
840 |
$year = date( 'Y', $timestamp );
|
841 |
$month = date( 'n', $timestamp );
|
842 |
$day = date( 'j', $timestamp );
|
921 |
<th scope="row" valign="top"><label for="notes"><?php esc_html_e( 'Notes', 'paid-memberships-pro' ); ?>:</label></th>
|
922 |
<td>
|
923 |
<?php
|
924 |
+
if ( in_array( 'notes', $read_only_fields ) && $order_id > 0 ) {
|
925 |
echo wp_kses_post( $order->notes );
|
926 |
} else {
|
927 |
?>
|
935 |
</tbody>
|
936 |
</table>
|
937 |
|
938 |
+
<?php
|
939 |
+
/**
|
940 |
+
* Allow adding other content after the Order Settings table.
|
941 |
+
*
|
942 |
+
* @since 2.5.10
|
943 |
+
*
|
944 |
+
* @param MemberOrder $order Member order object.
|
945 |
+
*/
|
946 |
+
do_action( 'pmpro_after_order_settings_table', $order );
|
947 |
+
?>
|
948 |
+
|
949 |
<p class="submit topborder">
|
950 |
<input name="order" type="hidden" value="
|
951 |
<?php
|
958 |
"/>
|
959 |
<input name="save" type="submit" class="button-primary" value="<?php esc_attr_e( 'Save Order', 'paid-memberships-pro' ); ?>"/>
|
960 |
<input name="cancel" type="button" class="cancel button-secondary" value="<?php esc_attr_e( 'Cancel', 'paid-memberships-pro' ); ?>"
|
961 |
+
onclick="location.href='<?php echo esc_url( admin_url( '/admin.php?page=pmpro-orders' ) ); ?>';"/>
|
962 |
</p>
|
963 |
|
964 |
</form>
|
968 |
<form id="posts-filter" method="get" action="">
|
969 |
|
970 |
<h1 class="wp-heading-inline"><?php esc_html_e( 'Orders', 'paid-memberships-pro' ); ?></h1>
|
971 |
+
<a href="<?php echo esc_url( add_query_arg( array( 'page' => 'pmpro-orders', 'order' => -1 ), admin_url( 'admin.php' ) ) ); ?>" class="page-title-action"><?php esc_html_e( 'Add New Order', 'paid-memberships-pro' ); ?></a>
|
972 |
|
973 |
<?php
|
974 |
// build the export URL
|
990 |
$export_url = add_query_arg( $url_params, $export_url );
|
991 |
?>
|
992 |
<a target="_blank" href="<?php echo esc_url( $export_url ); ?>" class="page-title-action"><?php esc_html_e( 'Export to CSV', 'paid-memberships-pro' ); ?></a>
|
993 |
+
|
994 |
<hr class="wp-header-end">
|
995 |
|
996 |
|
1022 |
value="with-discount-code" <?php selected( $filter, 'with-discount-code' ); ?>><?php esc_html_e( 'With a Discount Code', 'paid-memberships-pro' ); ?></option>
|
1023 |
<option
|
1024 |
value="within-a-status" <?php selected( $filter, 'within-a-status' ); ?>><?php esc_html_e( 'Within a Status', 'paid-memberships-pro' ); ?></option>
|
1025 |
+
<option
|
1026 |
value="only-paid" <?php selected( $filter, 'only-paid' ); ?>><?php esc_html_e( 'Only Paid Orders', 'paid-memberships-pro' ); ?></option>
|
1027 |
+
<option
|
1028 |
value="only-free" <?php selected( $filter, 'only-free' ); ?>><?php esc_html_e( 'Only Free Orders', 'paid-memberships-pro' ); ?></option>
|
1029 |
|
1030 |
<?php $custom_filters = apply_filters( 'pmpro_admin_orders_filters', array() ); ?>
|
1078 |
|
1079 |
<?php
|
1080 |
// Note: only orders belonging to current levels can be filtered. There is no option for orders belonging to deleted levels
|
1081 |
+
$levels = pmpro_sort_levels_by_order( pmpro_getAllLevels( true, true ) );
|
1082 |
?>
|
1083 |
<select id="l" name="l">
|
1084 |
<?php foreach ( $levels as $level ) { ?>
|
1087 |
<?php } ?>
|
1088 |
|
1089 |
</select>
|
1090 |
+
|
1091 |
<?php
|
1092 |
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS * FROM $wpdb->pmpro_discount_codes ";
|
1093 |
$sqlQuery .= "ORDER BY id DESC ";
|
1094 |
$codes = $wpdb->get_results($sqlQuery, OBJECT);
|
1095 |
if ( ! empty( $codes ) ) { ?>
|
1096 |
+
<select id="discount-code" name="discount-code">
|
1097 |
<?php foreach ( $codes as $code ) { ?>
|
1098 |
<option
|
1099 |
value="<?php echo esc_attr( $code->id ); ?>" <?php selected( $discount_code, $code->id ); ?>><?php echo esc_html( $code->code ); ?></option>
|
1135 |
jQuery('#predefined-date').hide();
|
1136 |
jQuery('#status').hide();
|
1137 |
jQuery('#l').hide();
|
1138 |
+
jQuery('#discount-code').hide();
|
1139 |
jQuery('#from').hide();
|
1140 |
jQuery('#to').hide();
|
1141 |
jQuery('#submit').show();
|
1151 |
jQuery('#predefined-date').hide();
|
1152 |
jQuery('#status').hide();
|
1153 |
jQuery('#l').hide();
|
1154 |
+
jQuery('#discount-code').hide();
|
1155 |
jQuery('#submit').show();
|
1156 |
jQuery('#from').show();
|
1157 |
jQuery('#to').show();
|
1167 |
jQuery('#predefined-date').show();
|
1168 |
jQuery('#status').hide();
|
1169 |
jQuery('#l').hide();
|
1170 |
+
jQuery('#discount-code').hide();
|
1171 |
jQuery('#submit').show();
|
1172 |
jQuery('#from').hide();
|
1173 |
jQuery('#to').hide();
|
1183 |
jQuery('#predefined-date').hide();
|
1184 |
jQuery('#status').hide();
|
1185 |
jQuery('#l').show();
|
1186 |
+
jQuery('#discount-code').hide();
|
1187 |
jQuery('#submit').show();
|
1188 |
jQuery('#from').hide();
|
1189 |
jQuery('#to').hide();
|
1199 |
jQuery('#predefined-date').hide();
|
1200 |
jQuery('#status').hide();
|
1201 |
jQuery('#l').hide();
|
1202 |
+
jQuery('#discount-code').show();
|
1203 |
jQuery('#submit').show();
|
1204 |
jQuery('#from').hide();
|
1205 |
jQuery('#to').hide();
|
1215 |
jQuery('#predefined-date').hide();
|
1216 |
jQuery('#status').show();
|
1217 |
jQuery('#l').hide();
|
1218 |
+
jQuery('#discount-code').hide();
|
1219 |
jQuery('#submit').show();
|
1220 |
jQuery('#from').hide();
|
1221 |
jQuery('#to').hide();
|
1231 |
jQuery('#predefined-date').hide();
|
1232 |
jQuery('#status').hide();
|
1233 |
jQuery('#l').hide();
|
1234 |
+
jQuery('#discount-code').hide();
|
1235 |
jQuery('#submit').show();
|
1236 |
jQuery('#from').hide();
|
1237 |
jQuery('#to').hide();
|
1247 |
<p class="search-box">
|
1248 |
<label class="hidden" for="post-search-input"><?php esc_html_e( 'Search Orders', 'paid-memberships-pro' ); ?>:</label>
|
1249 |
<input type="hidden" name="page" value="pmpro-orders"/>
|
1250 |
+
<input id="post-search-input" type="text" value="<?php echo esc_attr( wp_unslash( $s ) ); ?>" name="s"/>
|
1251 |
<input class="button" type="submit" value="<?php esc_attr_e( 'Search Orders', 'paid-memberships-pro' ); ?>"/>
|
1252 |
</p>
|
1253 |
|
1259 |
if ( $join_with_usermeta ) {
|
1260 |
$sqlQuery .= "LEFT JOIN $wpdb->usermeta um ON o.user_id = um.user_id ";
|
1261 |
}
|
1262 |
+
|
1263 |
if ( $filter === 'with-discount-code' ) {
|
1264 |
$sqlQuery .= "LEFT JOIN $wpdb->pmpro_discount_codes_uses dc ON o.id = dc.order_id ";
|
1265 |
}
|
1305 |
$sqlQuery .= 'GROUP BY o.id ORDER BY o.id DESC, o.timestamp DESC ';
|
1306 |
} else {
|
1307 |
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS o.id FROM $wpdb->pmpro_membership_orders o ";
|
1308 |
+
|
1309 |
if ( $filter === 'with-discount-code' ) {
|
1310 |
$sqlQuery .= "LEFT JOIN $wpdb->pmpro_discount_codes_uses dc ON o.id = dc.order_id ";
|
1311 |
}
|
1312 |
+
|
1313 |
$sqlQuery .= "WHERE " . $condition . ' ORDER BY o.id DESC, o.timestamp DESC ';
|
1314 |
}
|
1315 |
|
1316 |
$sqlQuery .= "LIMIT $start, $limit";
|
1317 |
|
1318 |
$order_ids = $wpdb->get_col( $sqlQuery );
|
1319 |
+
|
1320 |
$totalrows = $wpdb->get_var( 'SELECT FOUND_ROWS() as found_rows' );
|
1321 |
|
1322 |
if ( $order_ids ) {
|
1330 |
<tr class="thead">
|
1331 |
<th><?php esc_html_e( 'ID', 'paid-memberships-pro' ); ?></th>
|
1332 |
<th><?php esc_html_e( 'Code', 'paid-memberships-pro' ); ?></th>
|
1333 |
+
<th><?php esc_html_e( 'User', 'paid-memberships-pro' ); ?></th>
|
1334 |
<?php do_action( 'pmpro_orders_extra_cols_header', $order_ids ); ?>
|
1335 |
<th><?php esc_html_e( 'Level', 'paid-memberships-pro' ); ?></th>
|
1336 |
<th><?php esc_html_e( 'Total', 'paid-memberships-pro' ); ?></th>
|
1360 |
<a href="admin.php?page=pmpro-orders&order=<?php echo esc_attr( $order->id ); ?>"><?php echo esc_html( $order->code ); ?></a>
|
1361 |
<br />
|
1362 |
<div class="row-actions">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1363 |
<?php
|
1364 |
+
$delete_text = esc_html(
|
1365 |
+
sprintf(
|
1366 |
+
// translators: %s is the Order Code.
|
1367 |
+
__( 'Deleting orders is permanent and can affect active users. Are you sure you want to delete order %s?', 'paid-memberships-pro' ),
|
1368 |
+
str_replace( "'", '', $order->code )
|
1369 |
+
)
|
1370 |
+
);
|
1371 |
+
|
1372 |
+
$delete_nonce_url = wp_nonce_url(
|
1373 |
+
add_query_arg(
|
1374 |
+
[
|
1375 |
+
'page' => 'pmpro-orders',
|
1376 |
+
'action' => 'delete_order',
|
1377 |
+
'delete' => $order->id,
|
1378 |
+
],
|
1379 |
+
admin_url( 'admin.php' )
|
1380 |
+
),
|
1381 |
+
'delete_order',
|
1382 |
+
'pmpro_orders_nonce'
|
1383 |
+
);
|
1384 |
+
|
1385 |
+
$actions = [
|
1386 |
+
'edit' => sprintf(
|
1387 |
+
'<a title="%1$s" href="%2$s">%3$s</a>',
|
1388 |
+
esc_attr__( 'Edit', 'paid-memberships-pro' ),
|
1389 |
+
esc_url(
|
1390 |
+
add_query_arg(
|
1391 |
+
[
|
1392 |
+
'page' => 'pmpro-orders',
|
1393 |
+
'order' => $order->id,
|
1394 |
+
],
|
1395 |
+
admin_url( 'admin.php' )
|
1396 |
+
)
|
1397 |
+
),
|
1398 |
+
esc_html__( 'Edit', 'paid-memberships-pro' )
|
1399 |
+
),
|
1400 |
+
'copy' => sprintf(
|
1401 |
+
'<a title="%1$s" href="%2$s">%3$s</a>',
|
1402 |
+
esc_attr__( 'Copy', 'paid-memberships-pro' ),
|
1403 |
+
esc_url(
|
1404 |
+
add_query_arg(
|
1405 |
+
[
|
1406 |
+
'page' => 'pmpro-orders',
|
1407 |
+
'order' => - 1,
|
1408 |
+
'copy' => $order->id,
|
1409 |
+
],
|
1410 |
+
admin_url( 'admin.php' )
|
1411 |
+
)
|
1412 |
+
),
|
1413 |
+
esc_html__( 'Copy', 'paid-memberships-pro' )
|
1414 |
+
),
|
1415 |
+
'delete' => sprintf(
|
1416 |
+
'<a title="%1$s" href="%2$s">%3$s</a>',
|
1417 |
+
esc_attr__( 'Delete', 'paid-memberships-pro' ),
|
1418 |
+
'javascript:pmpro_askfirst(\'' . esc_js( $delete_text ) . '\', \'' . esc_js( $delete_nonce_url ) . '\'); void(0);',
|
1419 |
+
esc_html__( 'Delete', 'paid-memberships-pro' )
|
1420 |
+
),
|
1421 |
+
'print' => sprintf(
|
1422 |
+
'<a title="%1$s" href="%2$s" target="_blank" rel="noopener noreferrer">%3$s</a>',
|
1423 |
+
esc_attr__( 'Print', 'paid-memberships-pro' ),
|
1424 |
+
esc_url(
|
1425 |
+
add_query_arg(
|
1426 |
+
[
|
1427 |
+
'action' => 'pmpro_orders_print_view',
|
1428 |
+
'order' => $order->id,
|
1429 |
+
],
|
1430 |
+
admin_url( 'admin-ajax.php' )
|
1431 |
+
)
|
1432 |
+
),
|
1433 |
+
esc_html__( 'Print', 'paid-memberships-pro' )
|
1434 |
+
),
|
1435 |
+
'email' => sprintf(
|
1436 |
+
'<a title="%1$s" href="%2$s" data-order="%3$s" class="thickbox email_link">%4$s</a>',
|
1437 |
+
esc_attr__( 'Email', 'paid-memberships-pro' ),
|
1438 |
+
'#TB_inline?width=600&height=200&inlineId=email_invoice',
|
1439 |
+
esc_attr( $order->id ),
|
1440 |
+
esc_html__( 'Email', 'paid-memberships-pro' )
|
1441 |
+
),
|
1442 |
+
];
|
1443 |
+
|
1444 |
+
/**
|
1445 |
+
* Filter the extra actions for this user on this order.
|
1446 |
+
*
|
1447 |
+
* @param array $actions The list of actions.
|
1448 |
+
* @param object $user The user data.
|
1449 |
+
* @param MemberOrder $order The current order.
|
1450 |
+
*/
|
1451 |
+
$actions = apply_filters( 'pmpro_orders_user_row_actions', $actions, $order->user, $order );
|
1452 |
+
|
1453 |
+
$actions_html = [];
|
1454 |
+
|
1455 |
+
foreach ( $actions as $action => $link ) {
|
1456 |
+
$actions_html[] = sprintf(
|
1457 |
+
'<span class="%1$s">%2$s</span>',
|
1458 |
+
esc_attr( $action ),
|
1459 |
+
$link
|
1460 |
+
);
|
1461 |
+
}
|
1462 |
+
|
1463 |
+
if ( ! empty( $actions_html ) ) {
|
1464 |
+
echo implode( ' | ', $actions_html );
|
1465 |
}
|
1466 |
?>
|
1467 |
</div>
|
1469 |
<td class="username column-username">
|
1470 |
<?php $order->getUser(); ?>
|
1471 |
<?php if ( ! empty( $order->user ) ) { ?>
|
1472 |
+
<a href="user-edit.php?user_id=<?php echo esc_attr( $order->user->ID ); ?>"><?php echo esc_html( $order->user->user_login ); ?></a><br />
|
1473 |
+
<?php echo esc_html( $order->user->user_email ); ?>
|
1474 |
<?php } elseif ( $order->user_id > 0 ) { ?>
|
1475 |
[<?php esc_html_e( 'deleted', 'paid-memberships-pro' ); ?>]
|
1476 |
<?php } else { ?>
|
1477 |
[<?php esc_html_e( 'none', 'paid-memberships-pro' ); ?>]
|
1478 |
+
<?php } ?>
|
1479 |
</td>
|
1480 |
<?php do_action( 'pmpro_orders_extra_cols_body', $order ); ?>
|
1481 |
<td>
|
1490 |
<?php }
|
1491 |
?>
|
1492 |
</td>
|
1493 |
+
<td><?php echo pmpro_escape_price( pmpro_formatPrice( $order->total ) ); ?></td>
|
1494 |
<td>
|
1495 |
<?php
|
1496 |
if ( ! empty( $order->payment_type ) ) {
|
1506 |
<?php if ( ! empty( $order->billing->street ) ) { ?>
|
1507 |
<?php echo esc_html( $order->billing->street ); ?><br/>
|
1508 |
<?php if ( $order->billing->city && $order->billing->state ) { ?>
|
1509 |
+
<?php echo esc_html( $order->billing->city ); ?>, <?php echo esc_html( $order->billing->state ); ?> <?php echo esc_html( $order->billing->zip ); ?>
|
1510 |
<?php
|
1511 |
if ( ! empty( $order->billing->country ) ) {
|
1512 |
echo esc_html( $order->billing->country ); }
|
1528 |
?>
|
1529 |
</td>
|
1530 |
<td>
|
1531 |
+
<?php esc_html_e( 'Payment', 'paid-memberships-pro' ); ?>:
|
1532 |
<?php
|
1533 |
if ( ! empty( $order->payment_transaction_id ) ) {
|
1534 |
echo esc_html( $order->payment_transaction_id );
|
1537 |
}
|
1538 |
?>
|
1539 |
<br/>
|
1540 |
+
<?php esc_html_e( 'Subscription', 'paid-memberships-pro' ); ?>:
|
|
|
1541 |
<?php
|
1542 |
if ( ! empty( $order->subscription_transaction_id ) ) {
|
1543 |
echo esc_html( $order->subscription_transaction_id );
|
1556 |
<a title="<?php esc_attr_e('edit', 'paid-memberships-pro' ); ?>" href="<?php echo esc_url( add_query_arg( array( 'page' => 'pmpro-discountcodes', 'edit' => $order->discount_code->id ), admin_url('admin.php' ) ) ); ?>">
|
1557 |
<?php echo esc_html( $order->discount_code->code ); ?>
|
1558 |
</a>
|
1559 |
+
<?php } ?>
|
1560 |
</td>
|
1561 |
</tr>
|
1562 |
<?php
|
1575 |
</form>
|
1576 |
<?php
|
1577 |
// add normal args
|
1578 |
+
$pagination_url = esc_url( add_query_arg( $url_params, admin_url( '/admin.php?page=pmpro-orders' ) ) );
|
1579 |
echo pmpro_getPaginationString( $pn, $totalrows, $limit, 1, $pagination_url, "&limit=$limit&pn=" );
|
1580 |
?>
|
1581 |
|
adminpages/pagesettings.php
CHANGED
@@ -21,7 +21,22 @@ global $pmpro_pages;
|
|
21 |
* @since 1.8.5
|
22 |
*/
|
23 |
$extra_pages = apply_filters('pmpro_extra_page_settings', array());
|
24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
|
26 |
//check nonce for saving settings
|
27 |
if (!empty($_REQUEST['savesettings']) && (empty($_REQUEST['pmpro_pagesettings_nonce']) || !check_admin_referer('savesettings', 'pmpro_pagesettings_nonce'))) {
|
@@ -187,7 +202,14 @@ require_once(dirname(__FILE__) . "/admin_header.php");
|
|
187 |
</th>
|
188 |
<td>
|
189 |
<?php
|
190 |
-
wp_dropdown_pages(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
?>
|
192 |
<?php if (!empty($pmpro_pages['account'])) { ?>
|
193 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['account']; ?>&action=edit"
|
@@ -204,7 +226,14 @@ require_once(dirname(__FILE__) . "/admin_header.php");
|
|
204 |
</th>
|
205 |
<td>
|
206 |
<?php
|
207 |
-
wp_dropdown_pages(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
?>
|
209 |
<?php if (!empty($pmpro_pages['billing'])) { ?>
|
210 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['billing'] ?>&action=edit"
|
@@ -221,7 +250,14 @@ require_once(dirname(__FILE__) . "/admin_header.php");
|
|
221 |
</th>
|
222 |
<td>
|
223 |
<?php
|
224 |
-
wp_dropdown_pages(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
?>
|
226 |
<?php if (!empty($pmpro_pages['cancel'])) { ?>
|
227 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['cancel'] ?>&action=edit"
|
@@ -239,7 +275,14 @@ require_once(dirname(__FILE__) . "/admin_header.php");
|
|
239 |
</th>
|
240 |
<td>
|
241 |
<?php
|
242 |
-
wp_dropdown_pages(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
243 |
?>
|
244 |
<?php if (!empty($pmpro_pages['checkout'])) { ?>
|
245 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['checkout'] ?>&action=edit"
|
@@ -257,7 +300,14 @@ require_once(dirname(__FILE__) . "/admin_header.php");
|
|
257 |
</th>
|
258 |
<td>
|
259 |
<?php
|
260 |
-
wp_dropdown_pages(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
261 |
?>
|
262 |
<?php if (!empty($pmpro_pages['confirmation'])) { ?>
|
263 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['confirmation'] ?>&action=edit"
|
@@ -275,7 +325,14 @@ require_once(dirname(__FILE__) . "/admin_header.php");
|
|
275 |
</th>
|
276 |
<td>
|
277 |
<?php
|
278 |
-
wp_dropdown_pages(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
?>
|
280 |
<?php if (!empty($pmpro_pages['invoice'])) { ?>
|
281 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['invoice'] ?>&action=edit"
|
@@ -293,7 +350,14 @@ require_once(dirname(__FILE__) . "/admin_header.php");
|
|
293 |
</th>
|
294 |
<td>
|
295 |
<?php
|
296 |
-
wp_dropdown_pages(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
297 |
?>
|
298 |
<?php if (!empty($pmpro_pages['levels'])) { ?>
|
299 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['levels'] ?>&action=edit"
|
@@ -326,7 +390,8 @@ require_once(dirname(__FILE__) . "/admin_header.php");
|
|
326 |
array(
|
327 |
'name' => 'login_page_id',
|
328 |
'show_option_none' => '-- ' . __('Use WordPress Default', 'paid-memberships-pro') . ' --',
|
329 |
-
'selected' => $pmpro_pages['login'],
|
|
|
330 |
)
|
331 |
);
|
332 |
?>
|
@@ -354,7 +419,8 @@ require_once(dirname(__FILE__) . "/admin_header.php");
|
|
354 |
array(
|
355 |
'name' => 'member_profile_edit_page_id',
|
356 |
'show_option_none' => '-- ' . __('Use WordPress Default', 'paid-memberships-pro') . ' --',
|
357 |
-
'selected' => $pmpro_pages['member_profile_edit'],
|
|
|
358 |
)
|
359 |
);
|
360 |
?>
|
@@ -409,11 +475,14 @@ require_once(dirname(__FILE__) . "/admin_header.php");
|
|
409 |
<label for="<?php echo $name; ?>_page_id"><?php echo $label; ?></label>
|
410 |
</th>
|
411 |
<td>
|
412 |
-
<?php wp_dropdown_pages(
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
|
|
|
|
|
|
417 |
if(!empty($pmpro_pages[$name])) {
|
418 |
?>
|
419 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages[$name] ?>&action=edit"
|
21 |
* @since 1.8.5
|
22 |
*/
|
23 |
$extra_pages = apply_filters('pmpro_extra_page_settings', array());
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @deprecated replaced with pmpro_admin_pagesetting_post_type since 2.7.0
|
27 |
+
*/
|
28 |
+
$post_types = apply_filters( 'pmpro_admin_pagesetting_post_type_array', array( 'page' ) );
|
29 |
+
|
30 |
+
// For backward compatibility we extract the first element from the array
|
31 |
+
$post_type = is_array( $post_types ) ? $post_types[ array_key_first( $post_types ) ] : $post_types;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Set post type to use for PMPro pages in the page settings dropdown.
|
35 |
+
*
|
36 |
+
* @since 2.7.0
|
37 |
+
* @param string $post_type Accepts existing hierarchical post type
|
38 |
+
*/
|
39 |
+
$post_type = apply_filters( 'pmpro_admin_pagesetting_post_type', $post_type );
|
40 |
|
41 |
//check nonce for saving settings
|
42 |
if (!empty($_REQUEST['savesettings']) && (empty($_REQUEST['pmpro_pagesettings_nonce']) || !check_admin_referer('savesettings', 'pmpro_pagesettings_nonce'))) {
|
202 |
</th>
|
203 |
<td>
|
204 |
<?php
|
205 |
+
wp_dropdown_pages(
|
206 |
+
array(
|
207 |
+
'name' => 'account_page_id',
|
208 |
+
'show_option_none' => '-- ' . __( 'Choose One', 'paid-memberships-pro' ) . ' --',
|
209 |
+
'selected' => $pmpro_pages['account'],
|
210 |
+
'post_type' => $post_type,
|
211 |
+
)
|
212 |
+
);
|
213 |
?>
|
214 |
<?php if (!empty($pmpro_pages['account'])) { ?>
|
215 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['account']; ?>&action=edit"
|
226 |
</th>
|
227 |
<td>
|
228 |
<?php
|
229 |
+
wp_dropdown_pages(
|
230 |
+
array(
|
231 |
+
'name' => 'billing_page_id',
|
232 |
+
'show_option_none' => '-- ' . __( 'Choose One', 'paid-memberships-pro' ) . ' --',
|
233 |
+
'selected' => $pmpro_pages['billing'],
|
234 |
+
'post_type' => $post_type,
|
235 |
+
)
|
236 |
+
);
|
237 |
?>
|
238 |
<?php if (!empty($pmpro_pages['billing'])) { ?>
|
239 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['billing'] ?>&action=edit"
|
250 |
</th>
|
251 |
<td>
|
252 |
<?php
|
253 |
+
wp_dropdown_pages(
|
254 |
+
array(
|
255 |
+
'name' => 'cancel_page_id',
|
256 |
+
'show_option_none' => '-- ' . __( 'Choose One', 'paid-memberships-pro' ) . ' --',
|
257 |
+
'selected' => $pmpro_pages['cancel'],
|
258 |
+
'post_type' => $post_type,
|
259 |
+
)
|
260 |
+
);
|
261 |
?>
|
262 |
<?php if (!empty($pmpro_pages['cancel'])) { ?>
|
263 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['cancel'] ?>&action=edit"
|
275 |
</th>
|
276 |
<td>
|
277 |
<?php
|
278 |
+
wp_dropdown_pages(
|
279 |
+
array(
|
280 |
+
'name' => 'checkout_page_id',
|
281 |
+
'show_option_none' => '-- ' . __( 'Choose One', 'paid-memberships-pro' ) . ' --',
|
282 |
+
'selected' => $pmpro_pages['checkout'],
|
283 |
+
'post_type' => $post_type,
|
284 |
+
)
|
285 |
+
);
|
286 |
?>
|
287 |
<?php if (!empty($pmpro_pages['checkout'])) { ?>
|
288 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['checkout'] ?>&action=edit"
|
300 |
</th>
|
301 |
<td>
|
302 |
<?php
|
303 |
+
wp_dropdown_pages(
|
304 |
+
array(
|
305 |
+
'name' => 'confirmation_page_id',
|
306 |
+
'show_option_none' => '-- ' . __( 'Choose One', 'paid-memberships-pro' ) . ' --',
|
307 |
+
'selected' => $pmpro_pages['confirmation'],
|
308 |
+
'post_type' => $post_type,
|
309 |
+
)
|
310 |
+
);
|
311 |
?>
|
312 |
<?php if (!empty($pmpro_pages['confirmation'])) { ?>
|
313 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['confirmation'] ?>&action=edit"
|
325 |
</th>
|
326 |
<td>
|
327 |
<?php
|
328 |
+
wp_dropdown_pages(
|
329 |
+
array(
|
330 |
+
'name' => 'invoice_page_id',
|
331 |
+
'show_option_none' => '-- ' . __( 'Choose One', 'paid-memberships-pro' ) . ' --',
|
332 |
+
'selected' => $pmpro_pages['invoice'],
|
333 |
+
'post_type' => $post_type,
|
334 |
+
)
|
335 |
+
);
|
336 |
?>
|
337 |
<?php if (!empty($pmpro_pages['invoice'])) { ?>
|
338 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['invoice'] ?>&action=edit"
|
350 |
</th>
|
351 |
<td>
|
352 |
<?php
|
353 |
+
wp_dropdown_pages(
|
354 |
+
array(
|
355 |
+
'name' => 'levels_page_id',
|
356 |
+
'show_option_none' => '-- ' . __( 'Choose One', 'paid-memberships-pro' ) . ' --',
|
357 |
+
'selected' => $pmpro_pages['levels'],
|
358 |
+
'post_type' => $post_type,
|
359 |
+
)
|
360 |
+
);
|
361 |
?>
|
362 |
<?php if (!empty($pmpro_pages['levels'])) { ?>
|
363 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['levels'] ?>&action=edit"
|
390 |
array(
|
391 |
'name' => 'login_page_id',
|
392 |
'show_option_none' => '-- ' . __('Use WordPress Default', 'paid-memberships-pro') . ' --',
|
393 |
+
'selected' => $pmpro_pages['login'],
|
394 |
+
'post_type' => $post_type,
|
395 |
)
|
396 |
);
|
397 |
?>
|
419 |
array(
|
420 |
'name' => 'member_profile_edit_page_id',
|
421 |
'show_option_none' => '-- ' . __('Use WordPress Default', 'paid-memberships-pro') . ' --',
|
422 |
+
'selected' => $pmpro_pages['member_profile_edit'],
|
423 |
+
'post_type' => $post_type,
|
424 |
)
|
425 |
);
|
426 |
?>
|
475 |
<label for="<?php echo $name; ?>_page_id"><?php echo $label; ?></label>
|
476 |
</th>
|
477 |
<td>
|
478 |
+
<?php wp_dropdown_pages(
|
479 |
+
array(
|
480 |
+
'name' => $name . '_page_id',
|
481 |
+
'show_option_none' => '-- ' . __( 'Choose One', 'paid-memberships-pro' ) . ' --',
|
482 |
+
'selected' => $pmpro_pages[ $name ],
|
483 |
+
'post_type' => $post_type,
|
484 |
+
)
|
485 |
+
);
|
486 |
if(!empty($pmpro_pages[$name])) {
|
487 |
?>
|
488 |
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages[$name] ?>&action=edit"
|
adminpages/paymentsettings.php
CHANGED
@@ -112,7 +112,7 @@
|
|
112 |
<h1 class="wp-heading-inline"><?php esc_html_e( 'Payment Gateway', 'paid-memberships-pro' );?> & <?php esc_html_e( 'SSL Settings', 'paid-memberships-pro' ); ?></h1>
|
113 |
<hr class="wp-header-end">
|
114 |
|
115 |
-
<p><?php _e('Learn more about <a title="Paid Memberships Pro -
|
116 |
|
117 |
<table class="form-table">
|
118 |
<tbody>
|
@@ -127,7 +127,7 @@
|
|
127 |
<label for="gateway"><?php _e('Payment Gateway', 'paid-memberships-pro' );?>:</label>
|
128 |
</th>
|
129 |
<td>
|
130 |
-
<select id="gateway" name="gateway"
|
131 |
<?php
|
132 |
$pmpro_gateways = pmpro_gateways();
|
133 |
foreach($pmpro_gateways as $pmpro_gateway_name => $pmpro_gateway_label)
|
@@ -148,16 +148,20 @@
|
|
148 |
<label for="gateway_environment"><?php _e('Gateway Environment', 'paid-memberships-pro' );?>:</label>
|
149 |
</th>
|
150 |
<td>
|
151 |
-
<select name="gateway_environment">
|
152 |
<option value="sandbox" <?php selected( $gateway_environment, "sandbox" ); ?>><?php _e('Sandbox/Testing', 'paid-memberships-pro' );?></option>
|
153 |
<option value="live" <?php selected( $gateway_environment, "live" ); ?>><?php _e('Live/Production', 'paid-memberships-pro' );?></option>
|
154 |
</select>
|
155 |
<script>
|
156 |
-
function pmpro_changeGateway(
|
157 |
{
|
|
|
|
|
|
|
158 |
//hide all gateway options
|
159 |
jQuery('tr.gateway').hide();
|
160 |
jQuery('tr.gateway_'+gateway).show();
|
|
|
161 |
|
162 |
//hide sub settings and toggle them on based on triggers
|
163 |
jQuery('tr.pmpro_toggle_target').hide();
|
@@ -173,7 +177,10 @@
|
|
173 |
jQuery('#pmpro-default-gateway-message').hide();
|
174 |
}
|
175 |
}
|
176 |
-
pmpro_changeGateway(
|
|
|
|
|
|
|
177 |
</script>
|
178 |
</td>
|
179 |
</tr>
|
112 |
<h1 class="wp-heading-inline"><?php esc_html_e( 'Payment Gateway', 'paid-memberships-pro' );?> & <?php esc_html_e( 'SSL Settings', 'paid-memberships-pro' ); ?></h1>
|
113 |
<hr class="wp-header-end">
|
114 |
|
115 |
+
<p><?php _e('Learn more about <a title="Paid Memberships Pro - Payment Gateway Settings" target="_blank" href="https://www.paidmembershipspro.com/documentation/admin/payment-ssl-settings/?utm_source=plugin&utm_medium=pmpro-paymentsettings&utm_campaign=documentation&utm_content=payment-gateway-settings">Payment Gateway Settings</a> and <a title="Paid Memberships Pro - SSL Settings" target="_blank" href="https://www.paidmembershipspro.com/documentation/initial-plugin-setup/ssl/?utm_source=plugin&utm_medium=pmpro-paymentsettings&utm_campaign=documentation&utm_content=ssl&utm_term=link1">SSL</a>.', 'paid-memberships-pro' ); ?></p>
|
116 |
|
117 |
<table class="form-table">
|
118 |
<tbody>
|
127 |
<label for="gateway"><?php _e('Payment Gateway', 'paid-memberships-pro' );?>:</label>
|
128 |
</th>
|
129 |
<td>
|
130 |
+
<select id="gateway" name="gateway">
|
131 |
<?php
|
132 |
$pmpro_gateways = pmpro_gateways();
|
133 |
foreach($pmpro_gateways as $pmpro_gateway_name => $pmpro_gateway_label)
|
148 |
<label for="gateway_environment"><?php _e('Gateway Environment', 'paid-memberships-pro' );?>:</label>
|
149 |
</th>
|
150 |
<td>
|
151 |
+
<select id="gateway_environment" name="gateway_environment">
|
152 |
<option value="sandbox" <?php selected( $gateway_environment, "sandbox" ); ?>><?php _e('Sandbox/Testing', 'paid-memberships-pro' );?></option>
|
153 |
<option value="live" <?php selected( $gateway_environment, "live" ); ?>><?php _e('Live/Production', 'paid-memberships-pro' );?></option>
|
154 |
</select>
|
155 |
<script>
|
156 |
+
function pmpro_changeGateway()
|
157 |
{
|
158 |
+
const gateway = jQuery('#gateway').val();
|
159 |
+
const gateway_environment = jQuery('#gateway_environment').val();
|
160 |
+
|
161 |
//hide all gateway options
|
162 |
jQuery('tr.gateway').hide();
|
163 |
jQuery('tr.gateway_'+gateway).show();
|
164 |
+
jQuery('tr.gateway_'+gateway+'_'+gateway_environment).show();
|
165 |
|
166 |
//hide sub settings and toggle them on based on triggers
|
167 |
jQuery('tr.pmpro_toggle_target').hide();
|
177 |
jQuery('#pmpro-default-gateway-message').hide();
|
178 |
}
|
179 |
}
|
180 |
+
pmpro_changeGateway();
|
181 |
+
|
182 |
+
// Handle change events.
|
183 |
+
jQuery('#gateway, #gateway_environment').on('change', pmpro_changeGateway);
|
184 |
</script>
|
185 |
</td>
|
186 |
</tr>
|
adminpages/reports/login.php
CHANGED
@@ -105,6 +105,7 @@ function pmpro_report_login_page()
|
|
105 |
<option value="all" <?php if($l == "all") { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'paid-memberships-pro')?></option>
|
106 |
<?php
|
107 |
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
|
|
108 |
foreach($levels as $level)
|
109 |
{
|
110 |
?>
|
@@ -227,7 +228,8 @@ function pmpro_report_login_page()
|
|
227 |
<?php echo $theuser->display_name;?>
|
228 |
</td>
|
229 |
<td><?php echo $auser->membership?></td>
|
230 |
-
<td><?php echo date_i18n(
|
|
|
231 |
<td>
|
232 |
<?php
|
233 |
if($auser->enddate)
|
@@ -268,7 +270,7 @@ function pmpro_report_login_page()
|
|
268 |
</form>
|
269 |
|
270 |
<?php
|
271 |
-
echo pmpro_getPaginationString($pn, $totalrows, $limit, 1,
|
272 |
?>
|
273 |
<?php
|
274 |
}
|
@@ -410,12 +412,15 @@ function pmpro_report_track_values($type, $user_id = NULL) {
|
|
410 |
return false;
|
411 |
|
412 |
//check for cookie for visits
|
413 |
-
if($type
|
414 |
return false;
|
|
|
415 |
|
416 |
//set cookie for visits
|
417 |
-
if($type
|
418 |
-
|
|
|
|
|
419 |
|
420 |
//some vars for below
|
421 |
$now = current_time('timestamp');
|
105 |
<option value="all" <?php if($l == "all") { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'paid-memberships-pro')?></option>
|
106 |
<?php
|
107 |
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
108 |
+
$levels = pmpro_sort_levels_by_order( $levels );
|
109 |
foreach($levels as $level)
|
110 |
{
|
111 |
?>
|
228 |
<?php echo $theuser->display_name;?>
|
229 |
</td>
|
230 |
<td><?php echo $auser->membership?></td>
|
231 |
+
<td><?php echo date_i18n( 'm/d/Y', strtotime( get_date_from_gmt( $theuser->user_registered ), current_time( 'timestamp' ) ) ); ?></td>
|
232 |
+
|
233 |
<td>
|
234 |
<?php
|
235 |
if($auser->enddate)
|
270 |
</form>
|
271 |
|
272 |
<?php
|
273 |
+
echo pmpro_getPaginationString($pn, $totalrows, $limit, 1, admin_url( "/admin.php?page=pmpro-reports&report=login&s=" . urlencode($s)), "&l=$l&limit=$limit&pn=");
|
274 |
?>
|
275 |
<?php
|
276 |
}
|
412 |
return false;
|
413 |
|
414 |
//check for cookie for visits
|
415 |
+
if( $type === 'visits' && !empty( $_COOKIE['pmpro_visit'] ) ) {
|
416 |
return false;
|
417 |
+
}
|
418 |
|
419 |
//set cookie for visits
|
420 |
+
if( $type === 'visits' && empty( $_COOKIE['pmpro_visit'] ) ) {
|
421 |
+
// The secure parameter is set to is_ssl(), true if HTTPS.
|
422 |
+
setcookie( 'pmpro_visit', '1', null, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true );
|
423 |
+
}
|
424 |
|
425 |
//some vars for below
|
426 |
$now = current_time('timestamp');
|
adminpages/reports/memberships.php
CHANGED
@@ -31,25 +31,7 @@ function pmpro_report_memberships_widget() {
|
|
31 |
global $wpdb;
|
32 |
|
33 |
//get levels to show stats on first 3
|
34 |
-
$pmpro_levels = pmpro_getAllLevels(true, true);
|
35 |
-
|
36 |
-
$pmpro_level_order = pmpro_getOption('level_order');
|
37 |
-
|
38 |
-
if(!empty($pmpro_level_order))
|
39 |
-
{
|
40 |
-
$order = explode(',',$pmpro_level_order);
|
41 |
-
|
42 |
-
//reorder array
|
43 |
-
$reordered_levels = array();
|
44 |
-
foreach($order as $level_id) {
|
45 |
-
foreach($pmpro_levels as $key=>$level) {
|
46 |
-
if($level_id == $level->id)
|
47 |
-
$reordered_levels[$key] = $pmpro_levels[$key];
|
48 |
-
}
|
49 |
-
}
|
50 |
-
|
51 |
-
$pmpro_levels = $reordered_levels;
|
52 |
-
}
|
53 |
|
54 |
$pmpro_levels = apply_filters( 'pmpro_report_levels', $pmpro_levels );
|
55 |
?>
|
@@ -375,6 +357,7 @@ function pmpro_report_memberships_page()
|
|
375 |
<option value="free-levels" <?php if(isset($_REQUEST['level']) && $_REQUEST['level'] == "free-levels"){?> selected="selected" <?php }?>><?php _e( 'All Free Levels', 'paid-memberships-pro' ); ?></option>
|
376 |
<?php
|
377 |
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
|
|
378 |
foreach($levels as $level)
|
379 |
{
|
380 |
?>
|
31 |
global $wpdb;
|
32 |
|
33 |
//get levels to show stats on first 3
|
34 |
+
$pmpro_levels = pmpro_sort_levels_by_order( pmpro_getAllLevels(true, true) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
$pmpro_levels = apply_filters( 'pmpro_report_levels', $pmpro_levels );
|
37 |
?>
|
357 |
<option value="free-levels" <?php if(isset($_REQUEST['level']) && $_REQUEST['level'] == "free-levels"){?> selected="selected" <?php }?>><?php _e( 'All Free Levels', 'paid-memberships-pro' ); ?></option>
|
358 |
<?php
|
359 |
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
360 |
+
$levels = pmpro_sort_levels_by_order( $levels );
|
361 |
foreach($levels as $level)
|
362 |
{
|
363 |
?>
|
adminpages/reports/sales.php
CHANGED
@@ -69,7 +69,7 @@ function pmpro_report_sales_widget() {
|
|
69 |
<?php } ?>
|
70 |
</th>
|
71 |
<td><?php echo esc_html( number_format_i18n( pmpro_getSales( $report_type ) ) ); ?></td>
|
72 |
-
<td><?php echo
|
73 |
</tr>
|
74 |
<?php
|
75 |
//sale prices stats
|
@@ -82,9 +82,9 @@ function pmpro_report_sales_widget() {
|
|
82 |
}
|
83 |
?>
|
84 |
<tr class="pmpro_report_tr_sub" style="display: none;">
|
85 |
-
<th scope="row">- <?php echo
|
86 |
<td><?php echo esc_html( number_format_i18n( $quantity ) ); ?></td>
|
87 |
-
<td><?php echo
|
88 |
</tr>
|
89 |
<?php
|
90 |
}
|
@@ -152,7 +152,7 @@ function pmpro_report_sales_page()
|
|
152 |
if($period == "daily")
|
153 |
{
|
154 |
$startdate = $year . '-' . substr("0" . $month, strlen($month) - 1, 2) . '-01';
|
155 |
-
$enddate = $year . '-' . substr("0" . $month, strlen($month) - 1, 2) . '-
|
156 |
$date_function = 'DAY';
|
157 |
$currently_in_period = ( intval( date( 'Y' ) ) == $year && intval( date( 'n' ) ) == $month );
|
158 |
}
|
@@ -173,17 +173,22 @@ function pmpro_report_sales_page()
|
|
173 |
//testing or live data
|
174 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
175 |
|
|
|
|
|
|
|
|
|
|
|
176 |
//get data
|
177 |
-
$sqlQuery = "SELECT $date_function(o.timestamp) as date, $type_function(o.total) as value FROM $wpdb->pmpro_membership_orders o ";
|
178 |
|
179 |
if ( ! empty( $discount_code ) ) {
|
180 |
$sqlQuery .= "LEFT JOIN $wpdb->pmpro_discount_codes_uses dc ON o.id = dc.order_id ";
|
181 |
}
|
182 |
|
183 |
-
$sqlQuery .= "WHERE o.total > 0 AND o.timestamp >= '
|
184 |
|
185 |
if(!empty($enddate))
|
186 |
-
$sqlQuery .= "AND o.timestamp <=
|
187 |
|
188 |
if(!empty($l))
|
189 |
$sqlQuery .= "AND o.membership_id IN(" . esc_sql( $l ) . ") ";
|
@@ -311,6 +316,7 @@ function pmpro_report_sales_page()
|
|
311 |
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'paid-memberships-pro' );?></option>
|
312 |
<?php
|
313 |
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
|
|
314 |
foreach($levels as $level)
|
315 |
{
|
316 |
?>
|
@@ -473,10 +479,13 @@ function pmpro_getSales($period, $levels = NULL)
|
|
473 |
elseif($period == "this year")
|
474 |
$startdate = date_i18n("Y", current_time('timestamp')) . "-01-01";
|
475 |
else
|
476 |
-
$startdate = "";
|
477 |
|
478 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
479 |
|
|
|
|
|
|
|
480 |
//build query
|
481 |
global $wpdb;
|
482 |
$sqlQuery = "SELECT COUNT(*) FROM $wpdb->pmpro_membership_orders WHERE total > 0 AND status NOT IN('refunded', 'review', 'token', 'error') AND timestamp >= '" . esc_sql( $startdate ) . "' AND gateway_environment = '" . esc_sql( $gateway_environment ) . "' ";
|
@@ -523,6 +532,9 @@ function pmpro_get_prices_paid( $period, $count = NULL ) {
|
|
523 |
$startdate = '1970-01-01';
|
524 |
}
|
525 |
|
|
|
|
|
|
|
526 |
$gateway_environment = pmpro_getOption( 'gateway_environment' );
|
527 |
|
528 |
// Build query.
|
@@ -581,7 +593,10 @@ function pmpro_getRevenue($period, $levels = NULL)
|
|
581 |
elseif($period == "this year")
|
582 |
$startdate = date_i18n("Y", current_time('timestamp')) . "-01-01";
|
583 |
else
|
584 |
-
$startdate = "";
|
|
|
|
|
|
|
585 |
|
586 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
587 |
|
69 |
<?php } ?>
|
70 |
</th>
|
71 |
<td><?php echo esc_html( number_format_i18n( pmpro_getSales( $report_type ) ) ); ?></td>
|
72 |
+
<td><?php echo pmpro_escape_price( pmpro_formatPrice( pmpro_getRevenue( $report_type ) ) ); ?></td>
|
73 |
</tr>
|
74 |
<?php
|
75 |
//sale prices stats
|
82 |
}
|
83 |
?>
|
84 |
<tr class="pmpro_report_tr_sub" style="display: none;">
|
85 |
+
<th scope="row">- <?php echo pmpro_escape_price( pmpro_formatPrice( $price ) );?></th>
|
86 |
<td><?php echo esc_html( number_format_i18n( $quantity ) ); ?></td>
|
87 |
+
<td><?php echo pmpro_escape_price( pmpro_formatPrice( $price * $quantity ) ); ?></td>
|
88 |
</tr>
|
89 |
<?php
|
90 |
}
|
152 |
if($period == "daily")
|
153 |
{
|
154 |
$startdate = $year . '-' . substr("0" . $month, strlen($month) - 1, 2) . '-01';
|
155 |
+
$enddate = $year . '-' . substr("0" . $month, strlen($month) - 1, 2) . '-' . date_i18n('t', strtotime( $startdate ) );
|
156 |
$date_function = 'DAY';
|
157 |
$currently_in_period = ( intval( date( 'Y' ) ) == $year && intval( date( 'n' ) ) == $month );
|
158 |
}
|
173 |
//testing or live data
|
174 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
175 |
|
176 |
+
// Get the estimated second offset to convert from GMT time to local.This is not perfect as daylight
|
177 |
+
// savings time can come and go in the middle of a month, but it's a tradeoff that we are making
|
178 |
+
// for performance so that we don't need to go through each order manually to calculate the local time.
|
179 |
+
$tz_offset = strtotime( $startdate ) - strtotime( get_gmt_from_date( $startdate . " 00:00:00" ) );
|
180 |
+
|
181 |
//get data
|
182 |
+
$sqlQuery = "SELECT $date_function( DATE_ADD( o.timestamp, INTERVAL $tz_offset SECOND ) ) as date, $type_function(o.total) as value FROM $wpdb->pmpro_membership_orders o ";
|
183 |
|
184 |
if ( ! empty( $discount_code ) ) {
|
185 |
$sqlQuery .= "LEFT JOIN $wpdb->pmpro_discount_codes_uses dc ON o.id = dc.order_id ";
|
186 |
}
|
187 |
|
188 |
+
$sqlQuery .= "WHERE o.total > 0 AND o.timestamp >= DATE_ADD( '$startdate' , INTERVAL - $tz_offset SECOND ) AND o.status NOT IN('refunded', 'review', 'token', 'error') AND o.gateway_environment = '" . esc_sql( $gateway_environment ) . "' ";
|
189 |
|
190 |
if(!empty($enddate))
|
191 |
+
$sqlQuery .= "AND o.timestamp <= DATE_ADD( '$enddate 23:59:59' , INTERVAL - $tz_offset SECOND )";
|
192 |
|
193 |
if(!empty($l))
|
194 |
$sqlQuery .= "AND o.membership_id IN(" . esc_sql( $l ) . ") ";
|
316 |
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'paid-memberships-pro' );?></option>
|
317 |
<?php
|
318 |
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
319 |
+
$levels = pmpro_sort_levels_by_order( $levels );
|
320 |
foreach($levels as $level)
|
321 |
{
|
322 |
?>
|
479 |
elseif($period == "this year")
|
480 |
$startdate = date_i18n("Y", current_time('timestamp')) . "-01-01";
|
481 |
else
|
482 |
+
$startdate = date_i18n("Y-m-d", 0);
|
483 |
|
484 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
485 |
|
486 |
+
// Convert from local to UTC.
|
487 |
+
$startdate = get_gmt_from_date( $startdate );
|
488 |
+
|
489 |
//build query
|
490 |
global $wpdb;
|
491 |
$sqlQuery = "SELECT COUNT(*) FROM $wpdb->pmpro_membership_orders WHERE total > 0 AND status NOT IN('refunded', 'review', 'token', 'error') AND timestamp >= '" . esc_sql( $startdate ) . "' AND gateway_environment = '" . esc_sql( $gateway_environment ) . "' ";
|
532 |
$startdate = '1970-01-01';
|
533 |
}
|
534 |
|
535 |
+
// Convert from local to UTC.
|
536 |
+
$startdate = get_gmt_from_date( $startdate );
|
537 |
+
|
538 |
$gateway_environment = pmpro_getOption( 'gateway_environment' );
|
539 |
|
540 |
// Build query.
|
593 |
elseif($period == "this year")
|
594 |
$startdate = date_i18n("Y", current_time('timestamp')) . "-01-01";
|
595 |
else
|
596 |
+
$startdate = date_i18n("Y-m-d", 0);
|
597 |
+
|
598 |
+
// Convert from local to UTC.
|
599 |
+
$startdate = get_gmt_from_date( $startdate );
|
600 |
|
601 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
602 |
|
adminpages/templates/orders-email.php
CHANGED
@@ -15,12 +15,12 @@
|
|
15 |
</tr>
|
16 |
<tr>
|
17 |
<td>
|
18 |
-
<?php echo __( 'Date:', 'paid-memberships-pro' ) . ' ' . date_i18n( '
|
19 |
</td>
|
20 |
</tr>
|
21 |
<?php if(!empty($order->billing->name)): ?>
|
22 |
<tr>
|
23 |
-
<td>
|
24 |
<strong><?php _e( 'Bill to:', 'paid-memberships-pro' ); ?></strong><br>
|
25 |
<?php
|
26 |
echo pmpro_formatAddress(
|
@@ -41,29 +41,33 @@
|
|
41 |
<tbody>
|
42 |
<tr>
|
43 |
<td colspan="2">
|
44 |
-
<table style="width:100%;border-width:
|
45 |
<tr style="border-width:1px;border-style:solid;border-collapse:collapse;">
|
46 |
-
<th style="text-align:center;border-width:1px;border-style:solid;border-collapse:collapse;"><?php _e('ID', 'paid-memberships-pro' ); ?></th>
|
47 |
-
<th style="border-width:1px;border-style:solid;border-collapse:collapse;"><?php _e('Item', 'paid-memberships-pro' ); ?></th>
|
48 |
-
<th style="border-width:1px;border-style:solid;border-collapse:collapse;"><?php _e('Price', 'paid-memberships-pro' ); ?></th>
|
49 |
</tr>
|
50 |
<tr style="border-width:1px;border-style:solid;border-collapse:collapse;">
|
51 |
-
<td style="text-align:center;border-width:1px;border-style:solid;border-collapse:collapse;"><?php echo $level->id; ?></td>
|
52 |
-
<td style="border-width:1px;border-style:solid;border-collapse:collapse;"><?php echo $level->name; ?></td>
|
53 |
-
<td style="text-align:right;"><?php echo $order->subtotal; ?></td>
|
54 |
-
</tr>
|
55 |
-
<tr style="border-width:1px;border-style:solid;border-collapse:collapse;">
|
56 |
-
<th colspan="2" style="text-align:right;border-width:1px;border-style:solid;border-collapse:collapse;"><?php _e('Subtotal', 'paid-memberships-pro' ); ?></th>
|
57 |
-
<td style="text-align:right;border-width:1px;border-style:solid;border-collapse:collapse;"><?php echo $order->subtotal; ?></td>
|
58 |
-
</tr>
|
59 |
-
<tr style="border-width:1px;border-style:solid;border-collapse:collapse;">
|
60 |
-
<th colspan="2" style="text-align:right;border-width:1px;border-style:solid;border-collapse:collapse;"><?php _e('Tax', 'paid-memberships-pro' ); ?></th>
|
61 |
-
<td style="text-align:right;border-width:1px;border-style:solid;border-collapse:collapse;"><?php echo $order->tax; ?></td>
|
62 |
-
</tr>
|
63 |
-
<tr style="border-width:1px;border-style:solid;border-collapse:collapse;">
|
64 |
-
<th colspan="2" style="text-align:right;border-width:1px;border-style:solid;border-collapse:collapse;"><?php _e('Total', 'paid-memberships-pro' ); ?></th>
|
65 |
-
<th style="text-align:right;border-width:1px;border-style:solid;border-collapse:collapse;"><?php echo pmpro_formatPrice($order->total); ?></th>
|
66 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
</table>
|
68 |
</td>
|
69 |
</tr>
|
15 |
</tr>
|
16 |
<tr>
|
17 |
<td>
|
18 |
+
<?php echo __( 'Date:', 'paid-memberships-pro' ) . ' ' . date_i18n( get_option( 'date_format' ), $order->getTimestamp() ); ?>
|
19 |
</td>
|
20 |
</tr>
|
21 |
<?php if(!empty($order->billing->name)): ?>
|
22 |
<tr>
|
23 |
+
<td style="padding-bottom:10px;">
|
24 |
<strong><?php _e( 'Bill to:', 'paid-memberships-pro' ); ?></strong><br>
|
25 |
<?php
|
26 |
echo pmpro_formatAddress(
|
41 |
<tbody>
|
42 |
<tr>
|
43 |
<td colspan="2">
|
44 |
+
<table style="width:100%;border-width:0px;border-collapse:collapse;">
|
45 |
<tr style="border-width:1px;border-style:solid;border-collapse:collapse;">
|
46 |
+
<th style="text-align:center;border-width:1px;border-style:solid;border-collapse:collapse;padding:4px;"><?php _e('ID', 'paid-memberships-pro' ); ?></th>
|
47 |
+
<th style="border-width:1px;border-style:solid;border-collapse:collapse;padding:4px;"><?php _e('Item', 'paid-memberships-pro' ); ?></th>
|
48 |
+
<th style="border-width:1px;border-style:solid;border-collapse:collapse;padding:4px;"><?php _e('Price', 'paid-memberships-pro' ); ?></th>
|
49 |
</tr>
|
50 |
<tr style="border-width:1px;border-style:solid;border-collapse:collapse;">
|
51 |
+
<td style="text-align:center;border-width:1px;border-style:solid;border-collapse:collapse;padding:4px;"><?php echo $level->id; ?></td>
|
52 |
+
<td style="border-width:1px;border-style:solid;border-collapse:collapse;padding:4px;"><?php echo $level->name; ?></td>
|
53 |
+
<td style="border-width:1px;border-style:solid;border-collapse:collapse;text-align:right;padding:4px;"><?php echo pmpro_escape_price( pmpro_formatPrice( $order->subtotal ) ); ?></td>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
</tr>
|
55 |
+
<?php
|
56 |
+
if ( (float)$order->total > 0 ) {
|
57 |
+
$pmpro_price_parts = pmpro_get_price_parts( $order, 'array' );
|
58 |
+
foreach ( $pmpro_price_parts as $pmpro_price_part ) { ?>
|
59 |
+
<tr style="border-width:1px;border-style:solid;border-collapse:collapse;padding:4px;">
|
60 |
+
<th colspan="2" style="text-align:right;border-width:1px;border-style:solid;border-collapse:collapse;padding:4px;">
|
61 |
+
<?php esc_html_e( $pmpro_price_part['label'] ); ?>
|
62 |
+
</th>
|
63 |
+
<td style="text-align:right;border-width:1px;border-style:solid;border-collapse:collapse;padding:4px;">
|
64 |
+
<?php esc_html_e( $pmpro_price_part['value'] ); ?>
|
65 |
+
</td>
|
66 |
+
</tr>
|
67 |
+
<?php
|
68 |
+
}
|
69 |
+
}
|
70 |
+
?>
|
71 |
</table>
|
72 |
</td>
|
73 |
</tr>
|
adminpages/templates/orders-print.php
CHANGED
@@ -70,7 +70,7 @@
|
|
70 |
$order->billing->phone
|
71 |
); ?>
|
72 |
</p>
|
73 |
-
<table class="invoice">
|
74 |
<tr>
|
75 |
<th><?php _e('ID', 'paid-memberships-pro' ); ?></th>
|
76 |
<th><?php _e('Item', 'paid-memberships-pro' ); ?></th>
|
@@ -79,20 +79,24 @@
|
|
79 |
<tr>
|
80 |
<td class="aligncenter"><?php echo $level->id; ?></td>
|
81 |
<td><?php echo $level->name; ?></td>
|
82 |
-
<td class="alignright"><?php echo $order->subtotal; ?></td>
|
83 |
-
</tr>
|
84 |
-
<tr>
|
85 |
-
<th colspan="2" class="alignright"><?php _e('Subtotal', 'paid-memberships-pro' ); ?></th>
|
86 |
-
<td class="alignright"><?php echo $order->subtotal; ?></td>
|
87 |
-
</tr>
|
88 |
-
<tr>
|
89 |
-
<th colspan="2" class="alignright"><?php _e('Tax', 'paid-memberships-pro' ); ?></th>
|
90 |
-
<td class="alignright"><?php echo $order->tax; ?></td>
|
91 |
-
</tr>
|
92 |
-
<tr>
|
93 |
-
<th colspan="2" class="alignright"><?php _e('Total', 'paid-memberships-pro' ); ?></th>
|
94 |
-
<th class="alignright"><?php echo pmpro_formatPrice( $order->total ); ?></th>
|
95 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
</table>
|
97 |
</main>
|
98 |
</body>
|
70 |
$order->billing->phone
|
71 |
); ?>
|
72 |
</p>
|
73 |
+
<table class="invoice" style="border-width:0px;border-collapse:collapse;">
|
74 |
<tr>
|
75 |
<th><?php _e('ID', 'paid-memberships-pro' ); ?></th>
|
76 |
<th><?php _e('Item', 'paid-memberships-pro' ); ?></th>
|
79 |
<tr>
|
80 |
<td class="aligncenter"><?php echo $level->id; ?></td>
|
81 |
<td><?php echo $level->name; ?></td>
|
82 |
+
<td class="alignright"><?php echo pmpro_escape_price( pmpro_formatPrice( $order->subtotal ) ); ?></td>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
</tr>
|
84 |
+
<?php
|
85 |
+
if ( (float)$order->total > 0 ) {
|
86 |
+
$pmpro_price_parts = pmpro_get_price_parts( $order, 'array' );
|
87 |
+
foreach ( $pmpro_price_parts as $pmpro_price_part ) { ?>
|
88 |
+
<tr style="border-width:1px;border-style:solid;border-collapse:collapse;">
|
89 |
+
<th colspan="2" style="text-align:right;border-width:1px;border-style:solid;border-collapse:collapse;">
|
90 |
+
<?php esc_html_e( $pmpro_price_part['label'] ); ?>
|
91 |
+
</th>
|
92 |
+
<td style="text-align:right;border-width:1px;border-style:solid;border-collapse:collapse;">
|
93 |
+
<?php esc_html_e( $pmpro_price_part['value'] ); ?>
|
94 |
+
</td>
|
95 |
+
</tr>
|
96 |
+
<?php
|
97 |
+
}
|
98 |
+
}
|
99 |
+
?>
|
100 |
</table>
|
101 |
</main>
|
102 |
</body>
|
blocks/blocks.php
CHANGED
@@ -27,8 +27,12 @@ require_once( 'login/block.php' );
|
|
27 |
|
28 |
/**
|
29 |
* Add PMPro block category
|
|
|
|
|
|
|
|
|
30 |
*/
|
31 |
-
function pmpro_place_blocks_in_panel( $categories, $
|
32 |
return array_merge(
|
33 |
$categories,
|
34 |
array(
|
@@ -39,7 +43,15 @@ function pmpro_place_blocks_in_panel( $categories, $post ) {
|
|
39 |
)
|
40 |
);
|
41 |
}
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
|
44 |
/**
|
45 |
* Enqueue block editor only JavaScript and CSS
|
@@ -49,7 +61,15 @@ function pmpro_block_editor_scripts() {
|
|
49 |
wp_enqueue_script(
|
50 |
'pmpro-blocks-editor-js',
|
51 |
plugins_url( 'js/blocks.build.js', PMPRO_BASE_FILE ),
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
PMPRO_VERSION
|
54 |
);
|
55 |
|
27 |
|
28 |
/**
|
29 |
* Add PMPro block category
|
30 |
+
* This callback is used with the block_categories (pre 5.8)
|
31 |
+
* and block_categories_all (5.8+) filters. In the first filter,
|
32 |
+
* the second parameter is a $post, in the latter it's a $context.
|
33 |
+
* We don't use the second parameter yet though.
|
34 |
*/
|
35 |
+
function pmpro_place_blocks_in_panel( $categories, $post_or_context ) {
|
36 |
return array_merge(
|
37 |
$categories,
|
38 |
array(
|
43 |
)
|
44 |
);
|
45 |
}
|
46 |
+
|
47 |
+
// Use the correct filter based on WP version.
|
48 |
+
if ( function_exists( 'get_default_block_categories' ) ) {
|
49 |
+
// 5.8+, context is 2nd parameter.
|
50 |
+
add_filter( 'block_categories_all', 'pmpro_place_blocks_in_panel', 10, 2 );
|
51 |
+
} else {
|
52 |
+
// Pre-5.8, post is 2nd parameter.
|
53 |
+
add_filter( 'block_categories', 'pmpro_place_blocks_in_panel', 10, 2 );
|
54 |
+
}
|
55 |
|
56 |
/**
|
57 |
* Enqueue block editor only JavaScript and CSS
|
61 |
wp_enqueue_script(
|
62 |
'pmpro-blocks-editor-js',
|
63 |
plugins_url( 'js/blocks.build.js', PMPRO_BASE_FILE ),
|
64 |
+
[
|
65 |
+
'wp-i18n',
|
66 |
+
'wp-element',
|
67 |
+
'wp-blocks',
|
68 |
+
'wp-components',
|
69 |
+
'wp-api',
|
70 |
+
'wp-block-editor',
|
71 |
+
'pmpro_admin',
|
72 |
+
],
|
73 |
PMPRO_VERSION
|
74 |
);
|
75 |
|
blocks/membership/block.js
CHANGED
@@ -13,9 +13,8 @@
|
|
13 |
} = wp.blocks;
|
14 |
const {
|
15 |
PanelBody,
|
16 |
-
|
17 |
} = wp.components;
|
18 |
-
|
19 |
const {
|
20 |
InspectorControls,
|
21 |
InnerBlocks,
|
@@ -49,33 +48,47 @@ const all_levels = [{ value: 0, label: "Non-Members" }].concat( pmpro.all_level_
|
|
49 |
},
|
50 |
},
|
51 |
edit: props => {
|
52 |
-
const { attributes: {levels, uid}, setAttributes, isSelected } = props;
|
53 |
if( uid=='' ) {
|
54 |
var rand = Math.random()+"";
|
55 |
setAttributes( { uid:rand } );
|
56 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
return [
|
58 |
isSelected && <InspectorControls>
|
59 |
-
<PanelBody>
|
60 |
-
<
|
61 |
-
|
62 |
-
|
63 |
-
value={ levels }
|
64 |
-
onChange={ levels => { setAttributes( { levels } ) } }
|
65 |
-
options={ all_levels }
|
66 |
-
/>
|
67 |
</PanelBody>
|
68 |
</InspectorControls>,
|
69 |
isSelected && <div className="pmpro-block-require-membership-element" >
|
70 |
<span className="pmpro-block-title">{ __( 'Require Membership', 'paid-memberships-pro' ) }</span>
|
71 |
-
<PanelBody>
|
72 |
-
|
73 |
-
multiple
|
74 |
-
label={ __( 'Select levels to show content to:', 'paid-memberships-pro' ) }
|
75 |
-
value={ levels }
|
76 |
-
onChange={ levels => { setAttributes( { levels } ) } }
|
77 |
-
options={ all_levels }
|
78 |
-
/>
|
79 |
</PanelBody>
|
80 |
<InnerBlocks
|
81 |
renderAppender={ () => (
|
13 |
} = wp.blocks;
|
14 |
const {
|
15 |
PanelBody,
|
16 |
+
CheckboxControl,
|
17 |
} = wp.components;
|
|
|
18 |
const {
|
19 |
InspectorControls,
|
20 |
InnerBlocks,
|
48 |
},
|
49 |
},
|
50 |
edit: props => {
|
51 |
+
const { attributes: {levels, uid}, setAttributes, isSelected } = props;
|
52 |
if( uid=='' ) {
|
53 |
var rand = Math.random()+"";
|
54 |
setAttributes( { uid:rand } );
|
55 |
}
|
56 |
+
|
57 |
+
// Build an array of checkboxes for each level.
|
58 |
+
var checkboxes = all_levels.map( function(level) {
|
59 |
+
function setLevelsAttribute( nowChecked ) {
|
60 |
+
if ( nowChecked && ! ( levels.some( levelID => levelID == level.value ) ) ) {
|
61 |
+
// Add the level.
|
62 |
+
const newLevels = levels.slice();
|
63 |
+
newLevels.push( level.value + '' );
|
64 |
+
setAttributes( { levels:newLevels } );
|
65 |
+
} else if ( ! nowChecked && levels.some( levelID => levelID == level.value ) ) {
|
66 |
+
// Remove the level.
|
67 |
+
const newLevels = levels.filter(( levelID ) => levelID != level.value);
|
68 |
+
setAttributes( { levels:newLevels } );
|
69 |
+
}
|
70 |
+
}
|
71 |
+
return [
|
72 |
+
<CheckboxControl
|
73 |
+
label = { level.label }
|
74 |
+
checked = { levels.some( levelID => levelID == level.value ) }
|
75 |
+
onChange = { setLevelsAttribute }
|
76 |
+
/>
|
77 |
+
]
|
78 |
+
});
|
79 |
+
|
80 |
return [
|
81 |
isSelected && <InspectorControls>
|
82 |
+
<PanelBody>
|
83 |
+
<div class="pmpro-block-inspector-scrollable">
|
84 |
+
{checkboxes}
|
85 |
+
</div>
|
|
|
|
|
|
|
|
|
86 |
</PanelBody>
|
87 |
</InspectorControls>,
|
88 |
isSelected && <div className="pmpro-block-require-membership-element" >
|
89 |
<span className="pmpro-block-title">{ __( 'Require Membership', 'paid-memberships-pro' ) }</span>
|
90 |
+
<PanelBody>
|
91 |
+
{checkboxes}
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
</PanelBody>
|
93 |
<InnerBlocks
|
94 |
renderAppender={ () => (
|
classes/class-deny-network-activation.php
CHANGED
@@ -12,15 +12,27 @@ class PMPro_Deny_Network_Activation {
|
|
12 |
|
13 |
public function wp_admin_style() {
|
14 |
global $current_screen;
|
15 |
-
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
<style type="text/css">
|
18 |
.notice.notice-info {
|
19 |
background-color: #ffd;
|
20 |
}
|
21 |
</style>
|
22 |
-
|
23 |
-
}
|
24 |
}
|
25 |
|
26 |
public function display_message_after_network_activation_attempt() {
|
12 |
|
13 |
public function wp_admin_style() {
|
14 |
global $current_screen;
|
15 |
+
// Bail if not in the dashboard.
|
16 |
+
if ( ! is_admin() ) {
|
17 |
+
return;
|
18 |
+
}
|
19 |
+
|
20 |
+
// Bail if there is no current screen.
|
21 |
+
if ( empty( $current_screen ) ) {
|
22 |
+
return;
|
23 |
+
}
|
24 |
+
|
25 |
+
// Bail if not on the screens we want.
|
26 |
+
if ( 'sites-network' !== $current_screen->id && 'plugins-network' !== $current_screen->id ) {
|
27 |
+
return;
|
28 |
+
}
|
29 |
+
?>
|
30 |
<style type="text/css">
|
31 |
.notice.notice-info {
|
32 |
background-color: #ffd;
|
33 |
}
|
34 |
</style>
|
35 |
+
<?php
|
|
|
36 |
}
|
37 |
|
38 |
public function display_message_after_network_activation_attempt() {
|
classes/class-pmpro-admin-activity-email.php
CHANGED
@@ -79,8 +79,10 @@ class PMPro_Admin_Activity_Email extends PMProEmail {
|
|
79 |
?>
|
80 |
<tr>
|
81 |
<td valign="top" style="background:#FFFFFF;font-family:Helvetica,Arial,sans-serif;font-size:16px;line-height:25px;color:#222222;padding:30px;text-align:center;">
|
82 |
-
<
|
83 |
-
|
|
|
|
|
84 |
</td>
|
85 |
</tr>
|
86 |
<tr>
|
@@ -99,7 +101,7 @@ class PMPro_Admin_Activity_Email extends PMProEmail {
|
|
99 |
if ( $revenue > 0 ) {
|
100 |
?>
|
101 |
<h3 style="color:#2997c8;font-size:20px;line-height:30px;margin:0px 0px 15px 0px;padding:0px;"><?php esc_html_e( 'Sales and Revenue', 'paid-memberships-pro' ); ?></h3>
|
102 |
-
<p style="margin:0px 0px 15px 0px;padding:0px;"><?php printf( __( 'Your membership site made <strong>%1$s</strong> in revenue %2$s.', 'paid-memberships-pro' ),
|
103 |
<?php } else { ?>
|
104 |
<h3 style="color:#2997c8;font-size:20px;line-height:30px;margin:0px 0px 15px 0px;padding:0px;"><?php esc_html_e( 'Signups and Cancellations', 'paid-memberships-pro' ); ?></h3>
|
105 |
<?php } ?>
|
@@ -240,7 +242,7 @@ class PMPro_Admin_Activity_Email extends PMProEmail {
|
|
240 |
<table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="border:0;background-color:#F1F1F1;text-align:center;font-family:Helvetica,Arial,sans-serif;font-size:16px;line-height:25px;color:#222222;">
|
241 |
<tr>
|
242 |
<?php
|
243 |
-
// Get
|
244 |
$free_addons = 0;
|
245 |
$plus_addons = 0;
|
246 |
$update_addons = 0;
|
@@ -354,7 +356,7 @@ class PMPro_Admin_Activity_Email extends PMProEmail {
|
|
354 |
<p style="margin:0px 0px 15px 0px;padding:0px;"><a style="color:#2997c8;" href="https://www.paidmembershipspro.com/support/" target="_blank"><?php esc_html_e( 'Get Support', 'paid-memberships-pro' ); ?></a></p>
|
355 |
<p style="margin:0px 0px 15px 0px;padding:0px;"><a style="color:#2997c8;" href="https://twitter.com/pmproplugin" target="_blank"><?php esc_html_e( 'Follow @pmproplugin on Twitter', 'paid-memberships-pro' ); ?></a></p>
|
356 |
<p style="margin:0px 0px 15px 0px;padding:0px;"><a style="color:#2997c8;" href="https://www.facebook.com/PaidMembershipsPro/" target="_blank"><?php esc_html_e( 'Like us on Facebook', 'paid-memberships-pro' ); ?></p></p>
|
357 |
-
<p style="margin:0px;padding:0px;"><a style="color:#2997c8;" href="https://www.youtube.com/user/strangerstudiostv" target="_blank"><?php esc_html_e( 'Subscribe to our YouTube Channel', 'paid-memberships-pro' ); ?></a></p>
|
358 |
</td>
|
359 |
</tr>
|
360 |
</table>
|
79 |
?>
|
80 |
<tr>
|
81 |
<td valign="top" style="background:#FFFFFF;font-family:Helvetica,Arial,sans-serif;font-size:16px;line-height:25px;color:#222222;padding:30px;text-align:center;">
|
82 |
+
<p style="font-size:20px;line-height:30px;margin:0px;padding:0px;">
|
83 |
+
<a href="<?php echo site_url(); ?>" target="_blank" style="color:#2997c8;font-weight:bold;">[<?php echo get_bloginfo( 'name' ); ?>]</a><br />
|
84 |
+
<?php printf( __( "Here's a summary of what happened in your Paid Memberships Pro site %s.", 'paid-memberships-pro' ), esc_html( $term ) ); ?>
|
85 |
+
</p>
|
86 |
</td>
|
87 |
</tr>
|
88 |
<tr>
|
101 |
if ( $revenue > 0 ) {
|
102 |
?>
|
103 |
<h3 style="color:#2997c8;font-size:20px;line-height:30px;margin:0px 0px 15px 0px;padding:0px;"><?php esc_html_e( 'Sales and Revenue', 'paid-memberships-pro' ); ?></h3>
|
104 |
+
<p style="margin:0px 0px 15px 0px;padding:0px;"><?php printf( __( 'Your membership site made <strong>%1$s</strong> in revenue %2$s.', 'paid-memberships-pro' ), pmpro_escape_price( pmpro_formatPrice( $revenue ) ), esc_html( $term ) ); ?></p>
|
105 |
<?php } else { ?>
|
106 |
<h3 style="color:#2997c8;font-size:20px;line-height:30px;margin:0px 0px 15px 0px;padding:0px;"><?php esc_html_e( 'Signups and Cancellations', 'paid-memberships-pro' ); ?></h3>
|
107 |
<?php } ?>
|
242 |
<table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="border:0;background-color:#F1F1F1;text-align:center;font-family:Helvetica,Arial,sans-serif;font-size:16px;line-height:25px;color:#222222;">
|
243 |
<tr>
|
244 |
<?php
|
245 |
+
// Get Add On statistics.
|
246 |
$free_addons = 0;
|
247 |
$plus_addons = 0;
|
248 |
$update_addons = 0;
|
356 |
<p style="margin:0px 0px 15px 0px;padding:0px;"><a style="color:#2997c8;" href="https://www.paidmembershipspro.com/support/" target="_blank"><?php esc_html_e( 'Get Support', 'paid-memberships-pro' ); ?></a></p>
|
357 |
<p style="margin:0px 0px 15px 0px;padding:0px;"><a style="color:#2997c8;" href="https://twitter.com/pmproplugin" target="_blank"><?php esc_html_e( 'Follow @pmproplugin on Twitter', 'paid-memberships-pro' ); ?></a></p>
|
358 |
<p style="margin:0px 0px 15px 0px;padding:0px;"><a style="color:#2997c8;" href="https://www.facebook.com/PaidMembershipsPro/" target="_blank"><?php esc_html_e( 'Like us on Facebook', 'paid-memberships-pro' ); ?></p></p>
|
359 |
+
<p style="margin:0px;padding:0px;"><a style="color:#2997c8;" href="https://www.youtube.com/user/strangerstudiostv?sub_confirmation=1" target="_blank"><?php esc_html_e( 'Subscribe to our YouTube Channel', 'paid-memberships-pro' ); ?></a></p>
|
360 |
</td>
|
361 |
</tr>
|
362 |
</table>
|
classes/class-pmpro-members-list-table.php
CHANGED
@@ -72,9 +72,8 @@ class PMPro_Members_List_Table extends WP_List_Table {
|
|
72 |
*/
|
73 |
public function get_columns() {
|
74 |
$columns = array(
|
75 |
-
// 'cb' => '<input type="checkbox" />',
|
76 |
-
'ID' => 'ID',
|
77 |
'username' => 'Username',
|
|
|
78 |
'first_name' => 'First Name',
|
79 |
'last_name' => 'Last Name',
|
80 |
'display_name' => 'Display Name',
|
@@ -119,7 +118,7 @@ class PMPro_Members_List_Table extends WP_List_Table {
|
|
119 |
|
120 |
// Shortcut for editing columns in default memberslist location.
|
121 |
$current_screen = get_current_screen();
|
122 |
-
if ( ! empty( $current_screen ) &&
|
123 |
$columns = apply_filters( 'pmpro_manage_memberslist_columns', $columns );
|
124 |
}
|
125 |
|
@@ -242,7 +241,7 @@ class PMPro_Members_List_Table extends WP_List_Table {
|
|
242 |
/**
|
243 |
* Get the table data
|
244 |
*
|
245 |
-
* @return Array
|
246 |
*/
|
247 |
private function sql_table_data( $count = false ) {
|
248 |
global $wpdb;
|
@@ -543,7 +542,7 @@ class PMPro_Members_List_Table extends WP_List_Table {
|
|
543 |
} else {
|
544 |
// Display the member's initial payment.
|
545 |
if ( (float)$item['initial_payment'] > 0 ) {
|
546 |
-
$fee .= pmpro_formatPrice( $item['initial_payment'] );
|
547 |
}
|
548 |
// If there is a recurring payment, show a plus sign.
|
549 |
if ( (float)$item['initial_payment'] > 0 && (float)$item['billing_amount'] > 0 ) {
|
@@ -551,7 +550,7 @@ class PMPro_Members_List_Table extends WP_List_Table {
|
|
551 |
}
|
552 |
// If there is a recurring payment, show the recurring payment amount and cycle.
|
553 |
if ( (float)$item['billing_amount'] > 0 ) {
|
554 |
-
$fee .= pmpro_formatPrice( $item['billing_amount'] );
|
555 |
$fee .= esc_html( ' per ', 'paid-memberships-pro' );
|
556 |
if ( $item['cycle_number'] > 1 ) {
|
557 |
$fee .= $item['cycle_number'] . " " . $item['cycle_period'] . "s";
|
@@ -574,7 +573,7 @@ class PMPro_Members_List_Table extends WP_List_Table {
|
|
574 |
if ( empty( $joindate ) ) {
|
575 |
return;
|
576 |
}
|
577 |
-
return date_i18n( get_option('date_format'), $joindate );
|
578 |
}
|
579 |
|
580 |
/**
|
@@ -621,7 +620,7 @@ class PMPro_Members_List_Table extends WP_List_Table {
|
|
621 |
$l = false;
|
622 |
}
|
623 |
_e('Show', 'paid-memberships-pro' );?>
|
624 |
-
<select name="l" onchange="jQuery('#member-list-form').submit();">
|
625 |
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'paid-memberships-pro' );?></option>
|
626 |
<?php
|
627 |
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
72 |
*/
|
73 |
public function get_columns() {
|
74 |
$columns = array(
|
|
|
|
|
75 |
'username' => 'Username',
|
76 |
+
'ID' => 'ID',
|
77 |
'first_name' => 'First Name',
|
78 |
'last_name' => 'Last Name',
|
79 |
'display_name' => 'Display Name',
|
118 |
|
119 |
// Shortcut for editing columns in default memberslist location.
|
120 |
$current_screen = get_current_screen();
|
121 |
+
if ( ! empty( $current_screen ) && strpos( $current_screen->id, "pmpro-memberslist" ) !== false ) {
|
122 |
$columns = apply_filters( 'pmpro_manage_memberslist_columns', $columns );
|
123 |
}
|
124 |
|
241 |
/**
|
242 |
* Get the table data
|
243 |
*
|
244 |
+
* @return Array|integer if $count parameter = true
|
245 |
*/
|
246 |
private function sql_table_data( $count = false ) {
|
247 |
global $wpdb;
|
542 |
} else {
|
543 |
// Display the member's initial payment.
|
544 |
if ( (float)$item['initial_payment'] > 0 ) {
|
545 |
+
$fee .= pmpro_escape_price( pmpro_formatPrice( $item['initial_payment'] ) );
|
546 |
}
|
547 |
// If there is a recurring payment, show a plus sign.
|
548 |
if ( (float)$item['initial_payment'] > 0 && (float)$item['billing_amount'] > 0 ) {
|
550 |
}
|
551 |
// If there is a recurring payment, show the recurring payment amount and cycle.
|
552 |
if ( (float)$item['billing_amount'] > 0 ) {
|
553 |
+
$fee .= pmpro_escape_price( pmpro_formatPrice( $item['billing_amount'] ) );
|
554 |
$fee .= esc_html( ' per ', 'paid-memberships-pro' );
|
555 |
if ( $item['cycle_number'] > 1 ) {
|
556 |
$fee .= $item['cycle_number'] . " " . $item['cycle_period'] . "s";
|
573 |
if ( empty( $joindate ) ) {
|
574 |
return;
|
575 |
}
|
576 |
+
return date_i18n( get_option( 'date_format' ), strtotime( get_date_from_gmt( date( 'Y-m-d H:i:s', $joindate ) ) ) );
|
577 |
}
|
578 |
|
579 |
/**
|
620 |
$l = false;
|
621 |
}
|
622 |
_e('Show', 'paid-memberships-pro' );?>
|
623 |
+
<select name="l" onchange="jQuery('#current-page-selector').val('1'); jQuery('#member-list-form').submit();">
|
624 |
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'paid-memberships-pro' );?></option>
|
625 |
<?php
|
626 |
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
classes/class-pmpro-site-health.php
ADDED
@@ -0,0 +1,548 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* The functionality that includes PMPro data within Site Health information.
|
5 |
+
*
|
6 |
+
* @since 2.6.2
|
7 |
+
*/
|
8 |
+
class PMPro_Site_Health {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* The current object instance.
|
12 |
+
*
|
13 |
+
* @var self
|
14 |
+
*/
|
15 |
+
private static $instance;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Initialize class object and use it for future init calls.
|
19 |
+
*
|
20 |
+
* @since 2.6.2
|
21 |
+
*
|
22 |
+
* @return self The class object.
|
23 |
+
*/
|
24 |
+
public static function init() {
|
25 |
+
if ( ! is_object( self::$instance ) ) {
|
26 |
+
self::$instance = new self();
|
27 |
+
}
|
28 |
+
|
29 |
+
return self::$instance;
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Add hooks needed for functionality.
|
34 |
+
*
|
35 |
+
* @since 2.6.2
|
36 |
+
*/
|
37 |
+
public function hook() {
|
38 |
+
add_filter( 'debug_information', [ $this, 'debug_information' ] );
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Remove hooks needed for functionality.
|
43 |
+
*
|
44 |
+
* @since 2.6.2
|
45 |
+
*/
|
46 |
+
public function unhook() {
|
47 |
+
remove_filter( 'debug_information', [ $this, 'debug_information' ] );
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Add our data to Site Health information.
|
52 |
+
*
|
53 |
+
* @since 2.6.2
|
54 |
+
*
|
55 |
+
* @param array $info The Site Health information.
|
56 |
+
*
|
57 |
+
* @return array The updated Site Health information.
|
58 |
+
*/
|
59 |
+
public function debug_information( $info ) {
|
60 |
+
$info['pmpro'] = [
|
61 |
+
'label' => 'Paid Memberships Pro',
|
62 |
+
'description' => __( 'This debug information for your Paid Memberships Pro installation can assist you in getting support.', 'paid-memberships-pro' ),
|
63 |
+
'fields' => [
|
64 |
+
'pmpro-cron-jobs' => [
|
65 |
+
'label' => __( 'Cron Job Status', 'paid-memberships-pro' ),
|
66 |
+
'value' => self::get_cron_jobs(),
|
67 |
+
],
|
68 |
+
'pmpro-gateway' => [
|
69 |
+
'label' => __( 'Payment Gateway', 'paid-memberships-pro' ),
|
70 |
+
'value' => self::get_gateway(),
|
71 |
+
],
|
72 |
+
'pmpro-gateway-env' => [
|
73 |
+
'label' => __( 'Payment Gateway Environment', 'paid-memberships-pro' ),
|
74 |
+
'value' => self::get_gateway_env(),
|
75 |
+
],
|
76 |
+
'pmpro-orders' => [
|
77 |
+
'label' => __( 'Orders', 'paid-memberships-pro' ),
|
78 |
+
'value' => self::get_orders(),
|
79 |
+
],
|
80 |
+
'pmpro-discount-codes' => [
|
81 |
+
'label' => __( 'Discount Codes', 'paid-memberships-pro' ),
|
82 |
+
'value' => self::get_discount_codes(),
|
83 |
+
],
|
84 |
+
'pmpro-membership-levels' => [
|
85 |
+
'label' => __( 'Membership Levels', 'paid-memberships-pro' ),
|
86 |
+
'value' => self::get_levels(),
|
87 |
+
],
|
88 |
+
'pmpro-custom-templates' => [
|
89 |
+
'label' => __( 'Custom Templates', 'paid-memberships-pro' ),
|
90 |
+
'value' => self::get_custom_templates(),
|
91 |
+
],
|
92 |
+
'pmpro-getfile-usage' => [
|
93 |
+
'label' => __( 'getfile.php Usage', 'paid-memberships-pro' ),
|
94 |
+
'value' => self::get_getfile_usage(),
|
95 |
+
],
|
96 |
+
'pmpro-htaccess-cache-usage' => [
|
97 |
+
'label' => __( '.htaccess Cache Usage', 'paid-memberships-pro' ),
|
98 |
+
'value' => self::get_htaccess_cache_usage(),
|
99 |
+
],
|
100 |
+
'pmpro-pages' => [
|
101 |
+
'label' => __( 'Membership Pages', 'paid-memberships-pro' ),
|
102 |
+
'value' => self::get_pmpro_pages(),
|
103 |
+
]
|
104 |
+
],
|
105 |
+
];
|
106 |
+
|
107 |
+
// Automatically add information about constants set.
|
108 |
+
$info['pmpro']['fields'] = array_merge( $info['pmpro']['fields'], self::get_constants() );
|
109 |
+
|
110 |
+
return $info;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Gets the level information.
|
115 |
+
*
|
116 |
+
* @since 2.6.2
|
117 |
+
*
|
118 |
+
* @return string The level information.
|
119 |
+
*/
|
120 |
+
public function get_levels() {
|
121 |
+
$membership_levels = pmpro_getAllLevels( true, true );
|
122 |
+
|
123 |
+
if ( ! $membership_levels ) {
|
124 |
+
return __( 'No Levels Found', 'paid-memberships-pro' );
|
125 |
+
}
|
126 |
+
|
127 |
+
return wp_json_encode( $membership_levels, JSON_PRETTY_PRINT );
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Get the discount code information.
|
132 |
+
*
|
133 |
+
* @since 2.6.2
|
134 |
+
*
|
135 |
+
* @return string The discount code information.
|
136 |
+
*/
|
137 |
+
public function get_discount_codes() {
|
138 |
+
global $wpdb;
|
139 |
+
|
140 |
+
$count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM `$wpdb->pmpro_discount_codes`" );
|
141 |
+
|
142 |
+
// translators: %d: The total count of discount codes.
|
143 |
+
return sprintf( _n( '%d discount code', '%d discount codes', $count, 'paid-memberships-pro' ), $count );
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Get the order information.
|
148 |
+
*
|
149 |
+
* @since 2.6.2
|
150 |
+
*
|
151 |
+
* @return string The order information.
|
152 |
+
*/
|
153 |
+
public function get_orders() {
|
154 |
+
global $wpdb;
|
155 |
+
|
156 |
+
$count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM `$wpdb->pmpro_membership_orders`" );
|
157 |
+
|
158 |
+
// translators: %d: The total count of orders.
|
159 |
+
return sprintf( _n( '%d order', '%d orders', $count, 'paid-memberships-pro' ), $count );
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Get the payment gateway information.
|
164 |
+
*
|
165 |
+
* @since 2.6.2
|
166 |
+
*
|
167 |
+
* @return string The payment gateway information.
|
168 |
+
*/
|
169 |
+
public function get_gateway() {
|
170 |
+
$gateway = pmpro_getOption( 'gateway' );
|
171 |
+
$gateways = pmpro_gateways();
|
172 |
+
|
173 |
+
// Check if gateway is registered.
|
174 |
+
if ( ! isset( $gateways[ $gateway ] ) ) {
|
175 |
+
// translators: %s: The gateway name that is not registered.
|
176 |
+
return sprintf( __( '%s (gateway not registered)', 'paid-memberships-pro' ), $gateway );
|
177 |
+
}
|
178 |
+
|
179 |
+
$gateway_text = $gateways[ $gateway ];
|
180 |
+
|
181 |
+
// Custom Stripe gateway information.
|
182 |
+
if ( 'stripe' === $gateway ) {
|
183 |
+
$stripe = new PMProGateway_stripe();
|
184 |
+
|
185 |
+
$legacy = $stripe->using_legacy_keys();
|
186 |
+
$connect = $stripe->has_connect_credentials();
|
187 |
+
|
188 |
+
if ( $legacy ) {
|
189 |
+
$gateway_text .= ' (' . __( 'Legacy Keys', 'paid-memberships-pro' ) . ')';
|
190 |
+
}
|
191 |
+
|
192 |
+
if ( $connect ) {
|
193 |
+
$gateway_text .= ' (' . __( 'Stripe Connect', 'paid-memberships-pro' ) . ')';
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
return $gateway_text;
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Get the payment gateway environment information.
|
202 |
+
*
|
203 |
+
* @since 2.6.2
|
204 |
+
*
|
205 |
+
* @return string The payment gateway environment information.
|
206 |
+
*/
|
207 |
+
public function get_gateway_env() {
|
208 |
+
$environment = pmpro_getOption( 'gateway_environment' );
|
209 |
+
$environments = [
|
210 |
+
'sandbox' => __( 'Sandbox/Testing', 'paid-memberships-pro' ),
|
211 |
+
'live' => __( 'Live/Production', 'paid-memberships-pro' ),
|
212 |
+
];
|
213 |
+
|
214 |
+
// Check if environment is registered.
|
215 |
+
if ( ! isset( $environments[ $environment ] ) ) {
|
216 |
+
// translators: %s: The environment name that is not registered.
|
217 |
+
return sprintf( __( '%s (environment not registered)', 'paid-memberships-pro' ), $environment );
|
218 |
+
}
|
219 |
+
|
220 |
+
return $environments[ $environment ];
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Get the custom template information.
|
225 |
+
*
|
226 |
+
* @since 2.6.2
|
227 |
+
*
|
228 |
+
* @return string The custom template information.
|
229 |
+
*/
|
230 |
+
public function get_custom_templates() {
|
231 |
+
$parent_theme_path = get_template_directory() . '/paid-memberships-pro/';
|
232 |
+
$child_theme_path = get_stylesheet_directory() . '/paid-memberships-pro/';
|
233 |
+
|
234 |
+
$parent_theme_templates = $this->get_custom_templates_from_path( $parent_theme_path );
|
235 |
+
$child_theme_templates = null;
|
236 |
+
|
237 |
+
if ( $parent_theme_path !== $child_theme_path ) {
|
238 |
+
$child_theme_templates = $this->get_custom_templates_from_path( $child_theme_path );
|
239 |
+
}
|
240 |
+
|
241 |
+
if ( is_wp_error( $parent_theme_templates ) ) {
|
242 |
+
return $parent_theme_templates->get_error_message();
|
243 |
+
}
|
244 |
+
|
245 |
+
$templates = $parent_theme_templates;
|
246 |
+
|
247 |
+
if ( null !== $child_theme_templates ) {
|
248 |
+
if ( is_wp_error( $child_theme_templates ) ) {
|
249 |
+
$child_theme_templates = $child_theme_templates->get_error_message();
|
250 |
+
}
|
251 |
+
|
252 |
+
$templates = [
|
253 |
+
'parent' => $parent_theme_templates,
|
254 |
+
'child' => $child_theme_templates,
|
255 |
+
];
|
256 |
+
}
|
257 |
+
|
258 |
+
return wp_json_encode( $templates, JSON_PRETTY_PRINT );
|
259 |
+
}
|
260 |
+
|
261 |
+
private function get_custom_templates_from_path( $path ) {
|
262 |
+
require_once ABSPATH . 'wp-admin/includes/file.php';
|
263 |
+
|
264 |
+
/**
|
265 |
+
* @var $wp_filesystem WP_Filesystem_Base
|
266 |
+
*/
|
267 |
+
global $wp_filesystem;
|
268 |
+
|
269 |
+
WP_Filesystem();
|
270 |
+
|
271 |
+
if ( ! $wp_filesystem ) {
|
272 |
+
return new WP_Error( 'access-denied', __( 'Unable to verify', 'paid-memberships-pro' ) );
|
273 |
+
}
|
274 |
+
|
275 |
+
$override_path = get_stylesheet_directory() . '/paid-memberships-pro/';
|
276 |
+
$override_list = false;
|
277 |
+
|
278 |
+
if ( ! $wp_filesystem->is_dir( $path ) ) {
|
279 |
+
return new WP_Error( 'path-not-found', __( 'No template overrides', 'paid-membership-pro' ) );
|
280 |
+
}
|
281 |
+
|
282 |
+
$override_list = $wp_filesystem->dirlist( $path );
|
283 |
+
|
284 |
+
if ( ! $override_list ) {
|
285 |
+
return new WP_Error( 'path-empty', __( 'Empty override folder -- no template overrides', 'paid-membership-pro' ) );
|
286 |
+
}
|
287 |
+
|
288 |
+
$templates = [];
|
289 |
+
|
290 |
+
foreach ( $override_list as $template => $info ) {
|
291 |
+
$last_modified = $info['lastmod'] . ' ' . $info['time'];
|
292 |
+
|
293 |
+
if ( isset( $info['lastmodunix'] ) ) {
|
294 |
+
$last_modified = date( 'Y-m-d H:i:s', $info['lastmodunix'] );
|
295 |
+
}
|
296 |
+
|
297 |
+
$templates[ $template ] = [
|
298 |
+
'last_updated' => $last_modified,
|
299 |
+
'path' => str_replace( ABSPATH, '', $path ) . $template,
|
300 |
+
];
|
301 |
+
}
|
302 |
+
|
303 |
+
return $templates;
|
304 |
+
}
|
305 |
+
|
306 |
+
/**
|
307 |
+
* Get the cron job information.
|
308 |
+
*
|
309 |
+
* @since 2.6.2
|
310 |
+
*
|
311 |
+
* @return string The cron job information.
|
312 |
+
*/
|
313 |
+
public function get_cron_jobs() {
|
314 |
+
$crons = _get_cron_array();
|
315 |
+
|
316 |
+
$cron_times = [];
|
317 |
+
|
318 |
+
// These are our crons.
|
319 |
+
$expected_crons = [
|
320 |
+
'pmpro_cron_expire_memberships',
|
321 |
+
'pmpro_cron_expiration_warnings',
|
322 |
+
'pmpro_cron_credit_card_expiring_warnings',
|
323 |
+
'pmpro_cron_admin_activity_email',
|
324 |
+
];
|
325 |
+
|
326 |
+
$gateway = pmpro_getOption( 'gateway' );
|
327 |
+
|
328 |
+
if ( 'stripe' === $gateway ) {
|
329 |
+
$expected_crons[] = 'pmpro_cron_stripe_subscription_updates';
|
330 |
+
}
|
331 |
+
|
332 |
+
// Find any of our crons and when their next run is.
|
333 |
+
if ( $crons ) {
|
334 |
+
foreach ( $crons as $time => $cron ) {
|
335 |
+
$keys = array_keys( $cron );
|
336 |
+
$matches = array_intersect( $expected_crons, $keys );
|
337 |
+
|
338 |
+
foreach ( $matches as $cron_hook ) {
|
339 |
+
$cron_times[ $cron_hook ] = date( 'Y-m-d H:i:s', $time );
|
340 |
+
}
|
341 |
+
}
|
342 |
+
}
|
343 |
+
|
344 |
+
$missing_crons = array_diff( $expected_crons, array_keys( $cron_times ) );
|
345 |
+
|
346 |
+
$cron_information = [];
|
347 |
+
|
348 |
+
foreach ( $missing_crons as $cron_hook ) {
|
349 |
+
$cron_information[] = $cron_hook . ' (' . __( 'missing', 'paid-memberships-pro' ) . ')';
|
350 |
+
}
|
351 |
+
|
352 |
+
// Build the information of what crons are missing and what crons are going to run.
|
353 |
+
foreach ( $cron_times as $cron_hook => $next_run ) {
|
354 |
+
$cron_information[] = $cron_hook . ' (' . $next_run . ')';
|
355 |
+
}
|
356 |
+
|
357 |
+
return implode( " | \n", $cron_information );
|
358 |
+
}
|
359 |
+
|
360 |
+
/**
|
361 |
+
* Get the assigned Member pages and their URL's
|
362 |
+
*
|
363 |
+
* @since TBA
|
364 |
+
*
|
365 |
+
* @return string The member page information
|
366 |
+
*/
|
367 |
+
public function get_pmpro_pages() {
|
368 |
+
|
369 |
+
global $pmpro_pages;
|
370 |
+
|
371 |
+
$page_information = array();
|
372 |
+
|
373 |
+
if( !empty( $pmpro_pages ) ){
|
374 |
+
|
375 |
+
foreach( $pmpro_pages as $key => $val ){
|
376 |
+
|
377 |
+
$permalink = get_the_permalink( (int)$val );
|
378 |
+
|
379 |
+
if( empty( $permalink ) ){
|
380 |
+
$page_information[$key] = 'Not Set'; //Not translating this
|
381 |
+
} else {
|
382 |
+
$page_information[$key] = $permalink;
|
383 |
+
}
|
384 |
+
|
385 |
+
}
|
386 |
+
|
387 |
+
} else {
|
388 |
+
|
389 |
+
return __( 'No Membership Pages Found', 'paid-memberships-pro' );
|
390 |
+
|
391 |
+
}
|
392 |
+
|
393 |
+
return $page_information;
|
394 |
+
|
395 |
+
}
|
396 |
+
|
397 |
+
/**
|
398 |
+
* Get the .htaccess services/getfile.php usage information.
|
399 |
+
*
|
400 |
+
* @since 2.6.4
|
401 |
+
*
|
402 |
+
* @return string The .htaccess services/getfile.php usage information.
|
403 |
+
*/
|
404 |
+
public function get_getfile_usage() {
|
405 |
+
if ( ! defined( 'PMPRO_GETFILE_ENABLED' ) ) {
|
406 |
+
return __( 'PMPRO_GETFILE_ENABLED is not set', 'paid-memberships-pro' );
|
407 |
+
}
|
408 |
+
|
409 |
+
if ( ! PMPRO_GETFILE_ENABLED ) {
|
410 |
+
return __( 'PMPRO_GETFILE_ENABLED is off', 'paid-memberships-pro' );
|
411 |
+
}
|
412 |
+
|
413 |
+
require_once ABSPATH . 'wp-admin/includes/file.php';
|
414 |
+
|
415 |
+
/**
|
416 |
+
* @var $wp_filesystem WP_Filesystem_Base
|
417 |
+
*/
|
418 |
+
global $wp_filesystem;
|
419 |
+
|
420 |
+
WP_Filesystem();
|
421 |
+
|
422 |
+
if ( ! $wp_filesystem ) {
|
423 |
+
return __( 'Unable to access .htaccess file', 'paid-memberships-pro' );
|
424 |
+
}
|
425 |
+
|
426 |
+
if ( ! $wp_filesystem->exists( ABSPATH . '/.htaccess' ) ) {
|
427 |
+
return __( 'Off - No .htaccess file', 'paid-memberships-pro' );
|
428 |
+
}
|
429 |
+
|
430 |
+
$htaccess_contents = $wp_filesystem->get_contents( ABSPATH . '/.htaccess' );
|
431 |
+
|
432 |
+
if ( false === strpos( $htaccess_contents, '/services/getfile.php' ) ) {
|
433 |
+
return __( 'Off', 'paid-memberships-pro' );
|
434 |
+
}
|
435 |
+
|
436 |
+
return __( 'On - .htaccess contains services/getfile.php usage', 'paid-memberships-pro' );
|
437 |
+
}
|
438 |
+
|
439 |
+
/**
|
440 |
+
* Get the .htaccess cache usage information.
|
441 |
+
*
|
442 |
+
* @since 2.6.4
|
443 |
+
*
|
444 |
+
* @return string The .htaccess cache usage information.
|
445 |
+
*/
|
446 |
+
public function get_htaccess_cache_usage() {
|
447 |
+
require_once ABSPATH . 'wp-admin/includes/file.php';
|
448 |
+
|
449 |
+
/**
|
450 |
+
* @var $wp_filesystem WP_Filesystem_Base
|
451 |
+
*/
|
452 |
+
global $wp_filesystem;
|
453 |
+
|
454 |
+
WP_Filesystem();
|
455 |
+
|
456 |
+
if ( ! $wp_filesystem ) {
|
457 |
+
return __( 'Unable to access .htaccess file', 'paid-memberships-pro' );
|
458 |
+
}
|
459 |
+
|
460 |
+
if ( ! $wp_filesystem->exists( ABSPATH . '/.htaccess' ) ) {
|
461 |
+
return __( 'Off - No .htaccess file', 'paid-memberships-pro' );
|
462 |
+
}
|
463 |
+
|
464 |
+
$htaccess_contents = $wp_filesystem->get_contents( ABSPATH . '/.htaccess' );
|
465 |
+
|
466 |
+
if ( false !== strpos( $htaccess_contents, 'ExpiresByType text/html' ) ) {
|
467 |
+
return __( 'On - Browser cache enabled for HTML (ExpiresByType text/html), this may interfere with Content Restriction after Login. Remove that line from your .htaccess to resolve this problem.', 'paid-memberships-pro' );
|
468 |
+
} elseif ( false !== strpos( $htaccess_contents, 'ExpiresDefault' ) ) {
|
469 |
+
return __( 'On - Browser cache enabled for HTML (ExpiresDefault), this may interfere with Content Restriction after Login. Remove that line from your .htaccess to resolve this problem.', 'paid-memberships-pro' );
|
470 |
+
}
|
471 |
+
|
472 |
+
return __( 'Off', 'paid-memberships-pro' );
|
473 |
+
}
|
474 |
+
|
475 |
+
/**
|
476 |
+
* Get the constants site health information.
|
477 |
+
*
|
478 |
+
* @since 2.6.4
|
479 |
+
*
|
480 |
+
* @return array The constants site health information.
|
481 |
+
*/
|
482 |
+
public function get_constants() {
|
483 |
+
$constants = [
|
484 |
+
'PMPRO_CRON_LIMIT' => __( 'Cron Limit', 'paid-memberships-pro' ),
|
485 |
+
'PMPRO_DEFAULT_LEVEL' => __( 'Default Membership Level', 'paid-memberships-pro' ),
|
486 |
+
'PMPRO_USE_SESSIONS' => __( 'Use Sessions', 'paid-memberships-pro' ),
|
487 |
+
];
|
488 |
+
|
489 |
+
$gateway_specific_constants = [
|
490 |
+
'authorizenet' => [
|
491 |
+
'PMPRO_AUTHNET_SILENT_POST_DEBUG' => __( 'Authorize.net Silent Post Debug Mode', 'paid-memberships-pro' ),
|
492 |
+
],
|
493 |
+
'braintree' => [
|
494 |
+
'PMPRO_BRAINTREE_WEBHOOK_DEBUG' => __( 'Braintree Webhook Debug Mode', 'paid-memberships-pro' ),
|
495 |
+
],
|
496 |
+
'paypal' => [
|
497 |
+
'PMPRO_IPN_DEBUG' => __( 'PayPal IPN Debug Mode', 'paid-memberships-pro' ),
|
498 |
+
],
|
499 |
+
'paypalexpress' => [
|
500 |
+
'PMPRO_IPN_DEBUG' => __( 'PayPal IPN Debug Mode', 'paid-memberships-pro' ),
|
501 |
+
],
|
502 |
+
'paypalstandard' => [
|
503 |
+
'PMPRO_IPN_DEBUG' => __( 'PayPal IPN Debug Mode', 'paid-memberships-pro' ),
|
504 |
+
],
|
505 |
+
'stripe' => [
|
506 |
+
'PMPRO_STRIPE_WEBHOOK_DELAY' => __( 'Stripe Webhook Delay', 'paid-memberships-pro' ),
|
507 |
+
'PMPRO_STRIPE_WEBHOOK_DEBUG' => __( 'Stripe Webhook Debug Mode', 'paid-memberships-pro' ),
|
508 |
+
],
|
509 |
+
'twocheckout' => [
|
510 |
+
'PMPRO_INS_DEBUG' => __( '2Checkout INS Debug Mode', 'paid-memberships-pro' ),
|
511 |
+
],
|
512 |
+
];
|
513 |
+
|
514 |
+
$gateway = pmpro_getOption( 'gateway' );
|
515 |
+
|
516 |
+
if ( $gateway && isset( $gateway_specific_constants[ $gateway ] ) ) {
|
517 |
+
$constants = array_merge( $constants, $gateway_specific_constants[ $gateway ] );
|
518 |
+
}
|
519 |
+
|
520 |
+
/**
|
521 |
+
* Allow filtering the supported Site Health constants by other add ons.
|
522 |
+
*
|
523 |
+
* @since 2.6.4
|
524 |
+
*
|
525 |
+
* @param array $constants The list of constants to show in Site Health.
|
526 |
+
* @param string $gateway The current payment gateway.
|
527 |
+
*/
|
528 |
+
$constants = apply_filters( 'pmpro_site_health_constants', $constants, $gateway );
|
529 |
+
|
530 |
+
// Get and format constant information.
|
531 |
+
$constants_formatted = [];
|
532 |
+
|
533 |
+
foreach ( $constants as $constant => $label ) {
|
534 |
+
// Only get site health info for constants that are set.
|
535 |
+
if ( ! defined( $constant ) ) {
|
536 |
+
continue;
|
537 |
+
}
|
538 |
+
|
539 |
+
$constants_formatted[ 'pmpro-constants-' . $constant ] = [
|
540 |
+
'label' => $label . ' (' . $constant . ')',
|
541 |
+
'value' => var_export( constant( $constant ), true ),
|
542 |
+
];
|
543 |
+
}
|
544 |
+
|
545 |
+
return $constants_formatted;
|
546 |
+
}
|
547 |
+
|
548 |
+
}
|
classes/class.memberorder.php
CHANGED
@@ -151,6 +151,68 @@
|
|
151 |
return false; //didn't find it in the DB
|
152 |
}
|
153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
/**
|
155 |
* Set up the Gateway class to use with this order.
|
156 |
*
|
@@ -494,6 +556,8 @@
|
|
494 |
|
495 |
//set values array for filter
|
496 |
$values = array("price" => $price, "tax_state" => $tax_state, "tax_rate" => $tax_rate);
|
|
|
|
|
497 |
if(!empty($this->billing->state))
|
498 |
$values['billing_state'] = $this->billing->state;
|
499 |
if(!empty($this->billing->city))
|
@@ -536,6 +600,10 @@
|
|
536 |
* Change the timestamp of an order by passing in year, month, day, time.
|
537 |
*
|
538 |
* $time should be adjusted for local timezone.
|
|
|
|
|
|
|
|
|
539 |
*/
|
540 |
function updateTimestamp($year, $month, $day, $time = NULL)
|
541 |
{
|
@@ -552,8 +620,11 @@
|
|
552 |
global $wpdb;
|
553 |
$this->sqlQuery = "UPDATE $wpdb->pmpro_membership_orders SET timestamp = '" . $date . "' WHERE id = '" . $this->id . "' LIMIT 1";
|
554 |
|
|
|
555 |
if($wpdb->query($this->sqlQuery) !== "false") {
|
556 |
$this->timestamp = strtotime( $date );
|
|
|
|
|
557 |
return $this->getMemberOrderByID($this->id);
|
558 |
} else {
|
559 |
return false;
|
@@ -592,10 +663,12 @@
|
|
592 |
//calculate total
|
593 |
if(!empty($this->total))
|
594 |
$total = $this->total;
|
595 |
-
|
596 |
$total = (float)$amount + (float)$tax;
|
597 |
$this->total = $total;
|
598 |
-
}
|
|
|
|
|
599 |
|
600 |
//these fix some warnings/notices
|
601 |
if(empty($this->billing))
|
@@ -767,22 +840,24 @@
|
|
767 |
/**
|
768 |
* Get a random code to use as the order code.
|
769 |
*/
|
770 |
-
function getRandomCode()
|
771 |
-
{
|
772 |
global $wpdb;
|
773 |
|
774 |
-
|
775 |
-
|
|
|
776 |
|
777 |
-
|
778 |
-
$
|
779 |
-
$code =
|
780 |
-
$
|
781 |
-
|
|
|
782 |
$code = NULL;
|
|
|
783 |
}
|
784 |
|
785 |
-
return strtoupper($code);
|
786 |
}
|
787 |
|
788 |
/**
|
@@ -795,12 +870,17 @@
|
|
795 |
if(empty($this->id))
|
796 |
return false;
|
797 |
|
798 |
-
$this->status = $newstatus;
|
799 |
$this->sqlQuery = "UPDATE $wpdb->pmpro_membership_orders SET status = '" . esc_sql($newstatus) . "' WHERE id = '" . $this->id . "' LIMIT 1";
|
800 |
-
|
|
|
|
|
|
|
|
|
|
|
801 |
return true;
|
802 |
-
else
|
803 |
return false;
|
|
|
804 |
}
|
805 |
|
806 |
/**
|
@@ -857,8 +937,10 @@
|
|
857 |
$this->gateway,
|
858 |
$this->gateway_environment,
|
859 |
$this->subscription_transaction_id
|
860 |
-
);
|
|
|
861 |
$wpdb->query($sqlQuery);
|
|
|
862 |
|
863 |
//cancel the gateway subscription first
|
864 |
if (is_object($this->Gateway)) {
|
@@ -948,6 +1030,58 @@
|
|
948 |
return false;
|
949 |
}
|
950 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
951 |
/**
|
952 |
* Delete an order and associated data.
|
953 |
*/
|
@@ -966,4 +1100,46 @@
|
|
966 |
else
|
967 |
return false;
|
968 |
}
|
969 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
return false; //didn't find it in the DB
|
152 |
}
|
153 |
|
154 |
+
/**
|
155 |
+
* Get the first order for this subscription.
|
156 |
+
* Useful to find the original order from a recurring order.
|
157 |
+
* @since 2.5
|
158 |
+
* @return mixed Order object if found or false if not.
|
159 |
+
*/
|
160 |
+
function get_original_subscription_order( $subscription_id = '' ){
|
161 |
+
global $wpdb;
|
162 |
+
|
163 |
+
// Default to use the subscription ID on this order object.
|
164 |
+
if ( empty( $subscription_id ) && ! empty( $this->subscription_transaction_id ) ) {
|
165 |
+
$subscription_id = $this->subscription_transaction_id;
|
166 |
+
}
|
167 |
+
|
168 |
+
// Must have a subscription ID.
|
169 |
+
if ( empty( $subscription_id ) ) {
|
170 |
+
return false;
|
171 |
+
}
|
172 |
+
|
173 |
+
// Get some other values from this order to narrow the search.
|
174 |
+
if ( ! empty( $this->user_id ) ) {
|
175 |
+
$user_id = $this->user_id;
|
176 |
+
} else {
|
177 |
+
$user_id = '';
|
178 |
+
}
|
179 |
+
if ( ! empty( $this->gateway ) ) {
|
180 |
+
$gateway = $this->gateway;
|
181 |
+
} else {
|
182 |
+
$gateway = '';
|
183 |
+
}
|
184 |
+
if ( ! empty( $this->gateway_environment ) ) {
|
185 |
+
$gateway_environment = $this->gateway_environment;
|
186 |
+
} else {
|
187 |
+
$gateway_environment = '';
|
188 |
+
}
|
189 |
+
|
190 |
+
// Double check for a user_id, gateway and gateway environment.
|
191 |
+
$sql = $wpdb->prepare(
|
192 |
+
"SELECT ID
|
193 |
+
FROM $wpdb->pmpro_membership_orders
|
194 |
+
WHERE `subscription_transaction_id` = %s
|
195 |
+
AND `user_id` = %d
|
196 |
+
AND `gateway` = %s
|
197 |
+
AND `gateway_environment` = %s
|
198 |
+
ORDER BY id ASC
|
199 |
+
LIMIT 1",
|
200 |
+
array(
|
201 |
+
$subscription_id,
|
202 |
+
$user_id,
|
203 |
+
$gateway,
|
204 |
+
$gateway_environment
|
205 |
+
)
|
206 |
+
);
|
207 |
+
|
208 |
+
$order_id = $wpdb->get_var( $sql );
|
209 |
+
if ( ! empty( $order_id ) ) {
|
210 |
+
return new MemberOrder( $order_id );
|
211 |
+
} else {
|
212 |
+
return false;
|
213 |
+
}
|
214 |
+
}
|
215 |
+
|
216 |
/**
|
217 |
* Set up the Gateway class to use with this order.
|
218 |
*
|
556 |
|
557 |
//set values array for filter
|
558 |
$values = array("price" => $price, "tax_state" => $tax_state, "tax_rate" => $tax_rate);
|
559 |
+
if(!empty($this->billing->street))
|
560 |
+
$values['billing_street'] = $this->billing->street;
|
561 |
if(!empty($this->billing->state))
|
562 |
$values['billing_state'] = $this->billing->state;
|
563 |
if(!empty($this->billing->city))
|
600 |
* Change the timestamp of an order by passing in year, month, day, time.
|
601 |
*
|
602 |
* $time should be adjusted for local timezone.
|
603 |
+
*
|
604 |
+
* NOTE: This function should no longer be used. Instead, set the timestamp
|
605 |
+
* for the order directly and call the MemberOrder->saveOrder() function.
|
606 |
+
* This function is no longer used on the /adminpages/orders.php page.
|
607 |
*/
|
608 |
function updateTimestamp($year, $month, $day, $time = NULL)
|
609 |
{
|
620 |
global $wpdb;
|
621 |
$this->sqlQuery = "UPDATE $wpdb->pmpro_membership_orders SET timestamp = '" . $date . "' WHERE id = '" . $this->id . "' LIMIT 1";
|
622 |
|
623 |
+
do_action('pmpro_update_order', $this);
|
624 |
if($wpdb->query($this->sqlQuery) !== "false") {
|
625 |
$this->timestamp = strtotime( $date );
|
626 |
+
do_action('pmpro_updated_order', $this);
|
627 |
+
|
628 |
return $this->getMemberOrderByID($this->id);
|
629 |
} else {
|
630 |
return false;
|
663 |
//calculate total
|
664 |
if(!empty($this->total))
|
665 |
$total = $this->total;
|
666 |
+
elseif ( ! isset( $this->total ) || $this->total === '' ) {
|
667 |
$total = (float)$amount + (float)$tax;
|
668 |
$this->total = $total;
|
669 |
+
} else {
|
670 |
+
$total = 0;
|
671 |
+
}
|
672 |
|
673 |
//these fix some warnings/notices
|
674 |
if(empty($this->billing))
|
840 |
/**
|
841 |
* Get a random code to use as the order code.
|
842 |
*/
|
843 |
+
function getRandomCode() {
|
|
|
844 |
global $wpdb;
|
845 |
|
846 |
+
// We mix this with the seed to make sure we get unique codes.
|
847 |
+
static $count = 0;
|
848 |
+
$count++;
|
849 |
|
850 |
+
while( empty( $code ) ) {
|
851 |
+
$scramble = md5( AUTH_KEY . microtime() . SECURE_AUTH_KEY . $count );
|
852 |
+
$code = substr( $scramble, 0, 10 );
|
853 |
+
$code = apply_filters( 'pmpro_random_code', $code, $this ); //filter
|
854 |
+
$check = $wpdb->get_var( "SELECT id FROM $wpdb->pmpro_membership_orders WHERE code = '$code' LIMIT 1" );
|
855 |
+
if( $check || is_numeric( $code ) ) {
|
856 |
$code = NULL;
|
857 |
+
}
|
858 |
}
|
859 |
|
860 |
+
return strtoupper( $code );
|
861 |
}
|
862 |
|
863 |
/**
|
870 |
if(empty($this->id))
|
871 |
return false;
|
872 |
|
|
|
873 |
$this->sqlQuery = "UPDATE $wpdb->pmpro_membership_orders SET status = '" . esc_sql($newstatus) . "' WHERE id = '" . $this->id . "' LIMIT 1";
|
874 |
+
|
875 |
+
do_action('pmpro_update_order', $this);
|
876 |
+
if($wpdb->query($this->sqlQuery) !== false){
|
877 |
+
$this->status = $newstatus;
|
878 |
+
do_action('pmpro_updated_order', $this);
|
879 |
+
|
880 |
return true;
|
881 |
+
}else{
|
882 |
return false;
|
883 |
+
}
|
884 |
}
|
885 |
|
886 |
/**
|
937 |
$this->gateway,
|
938 |
$this->gateway_environment,
|
939 |
$this->subscription_transaction_id
|
940 |
+
);
|
941 |
+
do_action('pmpro_update_order', $this);
|
942 |
$wpdb->query($sqlQuery);
|
943 |
+
do_action('pmpro_updated_order', $this);
|
944 |
|
945 |
//cancel the gateway subscription first
|
946 |
if (is_object($this->Gateway)) {
|
1030 |
return false;
|
1031 |
}
|
1032 |
|
1033 |
+
/**
|
1034 |
+
* Sets the billing address fields on the order object.
|
1035 |
+
* Checks the last order for the same sub or pulls from user meta.
|
1036 |
+
* @since 2.5.5
|
1037 |
+
*/
|
1038 |
+
function find_billing_address() {
|
1039 |
+
global $wpdb;
|
1040 |
+
|
1041 |
+
if ( empty( $this->billing ) || empty( $this->billing->street ) ) {
|
1042 |
+
// We do not already have a billing address.
|
1043 |
+
$last_subscription_order = new MemberOrder();
|
1044 |
+
$last_subscription_order->getLastMemberOrderBySubscriptionTransactionID( $this->subscription_transaction_id );
|
1045 |
+
if ( ! empty( $last_subscription_order->billing ) && ! empty( $last_subscription_order->billing->street ) ) {
|
1046 |
+
// Last order in subscription has biling information. Pull data from there.
|
1047 |
+
$this->Address1 = $last_subscription_order->billing->street;
|
1048 |
+
$this->City = $last_subscription_order->billing->city;
|
1049 |
+
$this->State = $last_subscription_order->billing->state;
|
1050 |
+
$this->Zip = $last_subscription_order->billing->zip;
|
1051 |
+
$this->CountryCode = $last_subscription_order->billing->country;
|
1052 |
+
$this->PhoneNumber = $last_subscription_order->billing->phone;
|
1053 |
+
$this->Email = $wpdb->get_var("SELECT user_email FROM $wpdb->users WHERE ID = '" . $this->user_id . "' LIMIT 1");
|
1054 |
+
|
1055 |
+
$this->billing = new stdClass();
|
1056 |
+
$this->billing->name = $last_subscription_order->billing->name;
|
1057 |
+
$this->billing->street = $last_subscription_order->billing->street;
|
1058 |
+
$this->billing->city = $last_subscription_order->billing->city;
|
1059 |
+
$this->billing->state = $last_subscription_order->billing->state;
|
1060 |
+
$this->billing->zip = $last_subscription_order->billing->zip;
|
1061 |
+
$this->billing->country = $last_subscription_order->billing->country;
|
1062 |
+
$this->billing->phone = $last_subscription_order->billing->phone;
|
1063 |
+
} else {
|
1064 |
+
// Last order did not have billing information. Try to pull from usermeta.
|
1065 |
+
$this->Address1 = get_user_meta( $this->user_id, "pmpro_baddress1", true );
|
1066 |
+
$this->City = get_user_meta( $this->user_id, "pmpro_bcity", true );
|
1067 |
+
$this->State = get_user_meta( $this->user_id, "pmpro_bstate", true );
|
1068 |
+
$this->Zip = get_user_meta( $this->user_id, "pmpro_bzip", true );
|
1069 |
+
$this->CountryCode = get_user_meta( $this->user_id, "pmpro_bcountry", true );
|
1070 |
+
$this->PhoneNumber = get_user_meta( $this->user_id, "pmpro_bphone", true );
|
1071 |
+
$this->Email = $wpdb->get_var("SELECT user_email FROM $wpdb->users WHERE ID = '" . $this->user_id . "' LIMIT 1");
|
1072 |
+
|
1073 |
+
$this->billing = new stdClass();
|
1074 |
+
$this->billing->name = get_user_meta( $this->user_id, "pmpro_bfirstname", true ) . " " . get_user_meta( $this->user_id, "pmpro_blastname", true ) ;
|
1075 |
+
$this->billing->street = $this->Address1;
|
1076 |
+
$this->billing->city = $this->City;
|
1077 |
+
$this->billing->state = $this->State;
|
1078 |
+
$this->billing->zip = $this->Zip;
|
1079 |
+
$this->billing->country = $this->CountryCode;
|
1080 |
+
$this->billing->phone = $this->PhoneNumber;
|
1081 |
+
}
|
1082 |
+
}
|
1083 |
+
}
|
1084 |
+
|
1085 |
/**
|
1086 |
* Delete an order and associated data.
|
1087 |
*/
|
1100 |
else
|
1101 |
return false;
|
1102 |
}
|
1103 |
+
|
1104 |
+
/*
|
1105 |
+
* Generates a test order on the fly for orders.
|
1106 |
+
*/
|
1107 |
+
function get_test_order() {
|
1108 |
+
global $current_user;
|
1109 |
+
|
1110 |
+
//$test_order = $this->getEmptyMemberOrder();
|
1111 |
+
$all_levels = pmpro_getAllLevels();
|
1112 |
+
|
1113 |
+
if ( ! empty( $all_levels ) ) {
|
1114 |
+
$first_level = array_shift( $all_levels );
|
1115 |
+
$this->membership_id = $first_level->id;
|
1116 |
+
$this->InitialPayment = $first_level->initial_payment;
|
1117 |
+
} else {
|
1118 |
+
$this->membership_id = 1;
|
1119 |
+
$this->InitialPayment = 1;
|
1120 |
+
}
|
1121 |
+
$this->user_id = $current_user->ID;
|
1122 |
+
$this->cardtype = "Visa";
|
1123 |
+
$this->accountnumber = "4111111111111111";
|
1124 |
+
$this->expirationmonth = date( 'm', current_time( 'timestamp' ) );
|
1125 |
+
$this->expirationyear = ( intval( date( 'Y', current_time( 'timestamp' ) ) ) + 1 );
|
1126 |
+
$this->ExpirationDate = $this->expirationmonth . $this->expirationyear;
|
1127 |
+
$this->CVV2 = '123';
|
1128 |
+
$this->FirstName = 'Jane';
|
1129 |
+
$this->LastName = 'Doe';
|
1130 |
+
$this->Address1 = '123 Street';
|
1131 |
+
$this->billing = new stdClass();
|
1132 |
+
$this->billing->name = 'Jane Doe';
|
1133 |
+
$this->billing->street = '123 Street';
|
1134 |
+
$this->billing->city = 'City';
|
1135 |
+
$this->billing->state = 'ST';
|
1136 |
+
$this->billing->country = 'US';
|
1137 |
+
$this->billing->zip = '12345';
|
1138 |
+
$this->billing->phone = '5558675309';
|
1139 |
+
$this->gateway_environment = 'sandbox';
|
1140 |
+
$this->timestamp = time();
|
1141 |
+
$this->notes = __( 'This is a test order used with the PMPro Email Templates addon.', 'paid-memberships-pro' );
|
1142 |
+
|
1143 |
+
return apply_filters( 'pmpro_test_order_data', $this );
|
1144 |
+
}
|
1145 |
+
} // End of Class
|
classes/class.pmproemail.php
CHANGED
@@ -1,13 +1,14 @@
|
|
1 |
<?php
|
2 |
class PMProEmail
|
3 |
{
|
|
|
4 |
function __construct()
|
5 |
{
|
6 |
$this->email = $this->from = $this->fromname = $this->subject = $this->template = $this->data = $this->body = NULL;
|
7 |
}
|
8 |
|
9 |
function sendEmail($email = NULL, $from = NULL, $fromname = NULL, $subject = NULL, $template = NULL, $data = NULL)
|
10 |
-
{
|
11 |
//if values were passed
|
12 |
if($email)
|
13 |
$this->email = $email;
|
@@ -21,9 +22,16 @@
|
|
21 |
$this->template = $template;
|
22 |
if($data)
|
23 |
$this->data = $data;
|
24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
//default values
|
26 |
-
global $current_user;
|
27 |
if(!$this->email)
|
28 |
$this->email = $current_user->user_email;
|
29 |
|
@@ -32,15 +40,20 @@
|
|
32 |
|
33 |
if(!$this->fromname)
|
34 |
$this->fromname = pmpro_getOption("from_name");
|
35 |
-
|
36 |
-
if(!$this->subject)
|
37 |
-
$this->subject = sprintf(__("An Email From %s", 'paid-memberships-pro' ), get_option("blogname"));
|
38 |
-
|
39 |
-
//decode the subject line in case there are apostrophes/etc in it
|
40 |
-
$this->subject = html_entity_decode($this->subject, ENT_QUOTES, 'UTF-8');
|
41 |
|
42 |
if(!$this->template)
|
43 |
$this->template = "default";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
$this->headers = array("Content-Type: text/html");
|
46 |
|
@@ -49,7 +62,9 @@
|
|
49 |
//load the template
|
50 |
$locale = apply_filters("plugin_locale", get_locale(), "paid-memberships-pro");
|
51 |
|
52 |
-
if(
|
|
|
|
|
53 |
$this->body = file_get_contents(get_stylesheet_directory() . "/paid-memberships-pro/email/" . $locale . "/" . $this->template . ".html"); //localized email folder in child theme
|
54 |
elseif(file_exists(get_stylesheet_directory() . "/paid-memberships-pro/email/" . $this->template . ".html"))
|
55 |
$this->body = file_get_contents(get_stylesheet_directory() . "/paid-memberships-pro/email/" . $this->template . ".html"); //email folder in child theme
|
@@ -67,25 +82,29 @@
|
|
67 |
$this->body = file_get_contents(WP_LANG_DIR . '/pmpro/email/' . $this->template . ".html"); //email folder in WP language folder
|
68 |
elseif(file_exists(PMPRO_DIR . "/languages/email/" . $locale . "/" . $this->template . ".html"))
|
69 |
$this->body = file_get_contents(PMPRO_DIR . "/languages/email/" . $locale . "/" . $this->template . ".html"); //email folder in PMPro language folder
|
70 |
-
elseif($this->
|
71 |
-
$this->body = $
|
72 |
-
elseif(file_exists(PMPRO_DIR . "/email/" . $this->template . ".html"))
|
73 |
-
$this->body = file_get_contents(PMPRO_DIR . "/email/" . $this->template . ".html"); //default template in plugin
|
74 |
elseif(!empty($this->data) && !empty($this->data['body']))
|
75 |
$this->body = $this->data['body']; //data passed in
|
76 |
|
77 |
-
|
78 |
-
|
79 |
-
if(
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
if(file_exists(get_template_directory() . "/email_footer.html"))
|
84 |
-
{
|
85 |
-
$this->body = $this->body . "\n" . file_get_contents(get_template_directory() . "/email_footer.html");
|
86 |
}
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
//if data is a string, assume we mean to replace !!body!! with it
|
90 |
if(is_string($this->data))
|
91 |
$this->data = array("body"=>$data);
|
@@ -93,13 +112,14 @@
|
|
93 |
//filter for data
|
94 |
$this->data = apply_filters("pmpro_email_data", $this->data, $this); //filter
|
95 |
|
96 |
-
//swap data into body
|
97 |
if(is_array($this->data))
|
98 |
{
|
99 |
foreach($this->data as $key => $value)
|
100 |
{
|
101 |
if ( 'body' != $key ) {
|
102 |
$this->body = str_replace("!!" . $key . "!!", $value, $this->body);
|
|
|
103 |
}
|
104 |
}
|
105 |
}
|
@@ -195,15 +215,10 @@
|
|
195 |
if(!$user)
|
196 |
return false;
|
197 |
|
198 |
-
//check settings
|
199 |
-
$send = pmpro_getOption("email_admin_cancels");
|
200 |
-
if(empty($send))
|
201 |
-
return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
|
202 |
-
|
203 |
$this->email = get_bloginfo("admin_email");
|
204 |
$this->subject = sprintf(__("Membership for %s at %s has been CANCELLED", 'paid-memberships-pro'), $user->user_login, get_option("blogname"));
|
205 |
|
206 |
-
$this->data = array("user_login" => $user->user_login, "user_email" => $user->user_email, "display_name" => $user->display_name, "sitename" => get_option("blogname"), "siteemail" => pmpro_getOption("from_email"), "login_link" => pmpro_login_url());
|
207 |
|
208 |
if(!empty($old_level_id)) {
|
209 |
if(!is_array($old_level_id))
|
@@ -236,7 +251,7 @@
|
|
236 |
|
237 |
function sendCheckoutEmail($user = NULL, $invoice = NULL)
|
238 |
{
|
239 |
-
global $wpdb, $current_user;
|
240 |
if(!$user)
|
241 |
$user = $current_user;
|
242 |
|
@@ -265,27 +280,38 @@
|
|
265 |
"membership_level_confirmation_message" => $confirmation_message,
|
266 |
"membership_cost" => pmpro_getLevelCost($user->membership_level),
|
267 |
"login_link" => pmpro_login_url(),
|
|
|
268 |
"display_name" => $user->display_name,
|
269 |
"user_email" => $user->user_email,
|
270 |
);
|
271 |
-
|
272 |
-
|
273 |
-
{
|
274 |
-
if($invoice->
|
275 |
-
$
|
276 |
-
|
277 |
-
|
278 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
$this->data["instructions"] = wpautop(pmpro_getOption("instructions"));
|
280 |
}
|
281 |
-
|
282 |
-
$this->template = "checkout_trial";
|
283 |
-
else
|
284 |
-
$this->template = "checkout_paid";
|
285 |
-
|
286 |
-
//BUG: Didn't apply template filter before it was being used in sendEmail()
|
287 |
-
$this->template = apply_filters("pmpro_email_template", $this->template, $this);
|
288 |
-
|
289 |
$this->data["invoice_id"] = $invoice->code;
|
290 |
$this->data["invoice_total"] = pmpro_formatPrice($invoice->total);
|
291 |
$this->data["invoice_date"] = date_i18n( get_option( 'date_format' ), $invoice->getTimestamp() );
|
@@ -309,55 +335,46 @@
|
|
309 |
$invoice->billing->country,
|
310 |
$invoice->billing->phone);
|
311 |
|
312 |
-
if($invoice->getDiscountCode())
|
313 |
$this->data["discount_code"] = "<p>" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $invoice->discount_code->code . "</p>\n";
|
314 |
-
else
|
315 |
$this->data["discount_code"] = "";
|
316 |
-
|
317 |
-
elseif(
|
318 |
-
|
319 |
-
$this->template = "checkout_free";
|
320 |
-
global $discount_code;
|
321 |
-
if(!empty($discount_code))
|
322 |
$this->data["discount_code"] = "<p>" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $discount_code . "</p>\n";
|
323 |
-
else
|
324 |
-
$this->data["discount_code"] = "";
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
$this->template = "checkout_freetrial";
|
329 |
-
global $discount_code;
|
330 |
-
if(!empty($discount_code))
|
331 |
$this->data["discount_code"] = "<p>" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $discount_code . "</p>\n";
|
332 |
-
else
|
333 |
-
$this->data["discount_code"] = "";
|
|
|
334 |
}
|
335 |
|
336 |
$enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(CONVERT_TZ(enddate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
|
337 |
-
if($enddate)
|
338 |
$this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", 'paid-memberships-pro' ), date_i18n(get_option('date_format'), $enddate)) . "</p>\n";
|
339 |
-
else
|
340 |
$this->data["membership_expiration"] = "";
|
|
|
341 |
|
342 |
return $this->sendEmail();
|
343 |
}
|
344 |
|
345 |
function sendCheckoutAdminEmail($user = NULL, $invoice = NULL)
|
346 |
{
|
347 |
-
global $wpdb, $current_user;
|
348 |
if(!$user)
|
349 |
$user = $current_user;
|
350 |
|
351 |
if(!$user)
|
352 |
return false;
|
353 |
|
354 |
-
//check settings
|
355 |
-
$send = pmpro_getOption("email_admin_checkout");
|
356 |
-
if(empty($send))
|
357 |
-
return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
|
358 |
-
|
359 |
$this->email = get_bloginfo("admin_email");
|
360 |
-
$this->subject = sprintf(__("Member
|
361 |
|
362 |
$this->data = array(
|
363 |
"subject" => $this->subject,
|
@@ -369,23 +386,34 @@
|
|
369 |
"membership_level_name" => $user->membership_level->name,
|
370 |
"membership_cost" => pmpro_getLevelCost($user->membership_level),
|
371 |
"login_link" => pmpro_login_url(),
|
|
|
372 |
"display_name" => $user->display_name,
|
373 |
"user_email" => $user->user_email,
|
374 |
);
|
375 |
|
376 |
-
|
377 |
-
{
|
378 |
-
if($invoice->
|
379 |
-
$
|
380 |
-
|
381 |
-
$
|
382 |
-
|
383 |
-
$
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
389 |
$this->data["invoice_id"] = $invoice->code;
|
390 |
$this->data["invoice_total"] = pmpro_formatPrice($invoice->total);
|
391 |
$this->data["invoice_date"] = date_i18n(get_option('date_format'), $invoice->getTimestamp());
|
@@ -409,31 +437,27 @@
|
|
409 |
$invoice->billing->country,
|
410 |
$invoice->billing->phone);
|
411 |
|
412 |
-
if($invoice->getDiscountCode())
|
413 |
$this->data["discount_code"] = "<p>" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $invoice->discount_code->code . "</p>\n";
|
414 |
-
else
|
415 |
$this->data["discount_code"] = "";
|
416 |
-
|
417 |
-
elseif(
|
418 |
-
|
419 |
-
$this->template = "checkout_free_admin";
|
420 |
-
global $discount_code;
|
421 |
-
if(!empty($discount_code))
|
422 |
$this->data["discount_code"] = "<p>" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $discount_code . "</p>\n";
|
423 |
-
else
|
424 |
-
$this->data["discount_code"] = "";
|
425 |
-
|
426 |
-
|
427 |
-
{
|
428 |
-
$this->template = "checkout_freetrial_admin";
|
429 |
$this->data["discount_code"] = "";
|
430 |
-
}
|
431 |
|
432 |
$enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(CONVERT_TZ(enddate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
|
433 |
-
if($enddate)
|
434 |
$this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", 'paid-memberships-pro' ), date_i18n(get_option('date_format'), $enddate)) . "</p>\n";
|
435 |
-
else
|
436 |
$this->data["membership_expiration"] = "";
|
|
|
437 |
|
438 |
return $this->sendEmail();
|
439 |
}
|
@@ -471,7 +495,8 @@
|
|
471 |
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
472 |
"expirationmonth" => $invoice->expirationmonth,
|
473 |
"expirationyear" => $invoice->expirationyear,
|
474 |
-
"login_link" => pmpro_login_url()
|
|
|
475 |
);
|
476 |
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
477 |
$invoice->billing->street,
|
@@ -496,11 +521,6 @@
|
|
496 |
if(!$user || !$invoice)
|
497 |
return false;
|
498 |
|
499 |
-
//check settings
|
500 |
-
$send = pmpro_getOption("email_admin_billing");
|
501 |
-
if(empty($send))
|
502 |
-
return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
|
503 |
-
|
504 |
$this->email = get_bloginfo("admin_email");
|
505 |
$this->subject = sprintf(__("Billing information has been updated for %s at %s", "paid-memberships-pro"), $user->user_login, get_option("blogname"));
|
506 |
|
@@ -525,7 +545,8 @@
|
|
525 |
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
526 |
"expirationmonth" => $invoice->expirationmonth,
|
527 |
"expirationyear" => $invoice->expirationyear,
|
528 |
-
"login_link" => pmpro_login_url()
|
|
|
529 |
);
|
530 |
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
531 |
$invoice->billing->street,
|
@@ -549,9 +570,11 @@
|
|
549 |
|
550 |
if(!$user || !$invoice)
|
551 |
return false;
|
|
|
|
|
552 |
|
553 |
$this->email = $user->user_email;
|
554 |
-
$this->subject = sprintf(__("Membership
|
555 |
|
556 |
$this->data = array(
|
557 |
"subject" => $this->subject,
|
@@ -559,8 +582,8 @@
|
|
559 |
"user_login" => $user->user_login,
|
560 |
"sitename" => get_option("blogname"),
|
561 |
"siteemail" => pmpro_getOption("from_email"),
|
562 |
-
"membership_id" => $
|
563 |
-
"membership_level_name" => $
|
564 |
"display_name" => $user->display_name,
|
565 |
"user_email" => $user->user_email,
|
566 |
"billing_name" => $invoice->billing->name,
|
@@ -574,7 +597,8 @@
|
|
574 |
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
575 |
"expirationmonth" => $invoice->expirationmonth,
|
576 |
"expirationyear" => $invoice->expirationyear,
|
577 |
-
"login_link" => pmpro_login_url(pmpro_url("billing"))
|
|
|
578 |
);
|
579 |
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
580 |
$invoice->billing->street,
|
@@ -596,9 +620,10 @@
|
|
596 |
return false;
|
597 |
|
598 |
$user = get_userdata($invoice->user_id);
|
|
|
599 |
|
600 |
$this->email = $email;
|
601 |
-
$this->subject = sprintf(__("Membership
|
602 |
|
603 |
$this->data = array(
|
604 |
"subject" => $this->subject,
|
@@ -606,8 +631,8 @@
|
|
606 |
"user_login" => $user->user_login,
|
607 |
"sitename" => get_option("blogname"),
|
608 |
"siteemail" => pmpro_getOption("from_email"),
|
609 |
-
"membership_id" => $
|
610 |
-
"membership_level_name" => $
|
611 |
"display_name" => $user->display_name,
|
612 |
"user_email" => $user->user_email,
|
613 |
"billing_name" => $invoice->billing->name,
|
@@ -621,7 +646,8 @@
|
|
621 |
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
622 |
"expirationmonth" => $invoice->expirationmonth,
|
623 |
"expirationyear" => $invoice->expirationyear,
|
624 |
-
"login_link" => pmpro_login_url( get_edit_user_link( $user->ID ) )
|
|
|
625 |
);
|
626 |
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
627 |
$invoice->billing->street,
|
@@ -646,7 +672,7 @@
|
|
646 |
return false;
|
647 |
|
648 |
$this->email = $user->user_email;
|
649 |
-
$this->subject = sprintf(__("Credit
|
650 |
|
651 |
$this->data = array(
|
652 |
"subject" => $this->subject,
|
@@ -669,7 +695,8 @@
|
|
669 |
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
670 |
"expirationmonth" => $invoice->expirationmonth,
|
671 |
"expirationyear" => $invoice->expirationyear,
|
672 |
-
"login_link" => pmpro_login_url(pmpro_url("billing"))
|
|
|
673 |
);
|
674 |
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
675 |
$invoice->billing->street,
|
@@ -697,7 +724,7 @@
|
|
697 |
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID);
|
698 |
|
699 |
$this->email = $user->user_email;
|
700 |
-
$this->subject = sprintf(__("
|
701 |
|
702 |
$this->data = array(
|
703 |
"subject" => $this->subject,
|
@@ -724,8 +751,10 @@
|
|
724 |
"expirationmonth" => $invoice->expirationmonth,
|
725 |
"expirationyear" => $invoice->expirationyear,
|
726 |
"login_link" => pmpro_login_url(),
|
727 |
-
"
|
728 |
-
|
|
|
|
|
729 |
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
730 |
$invoice->billing->street,
|
731 |
"", //address 2
|
@@ -784,7 +813,8 @@
|
|
784 |
"membership_id" => $user->membership_level->id,
|
785 |
"membership_level_name" => $user->membership_level->name,
|
786 |
"siteemail" => pmpro_getOption("from_email"),
|
787 |
-
"login_link" => pmpro_login_url(),
|
|
|
788 |
"display_name" => $user->display_name,
|
789 |
"user_email" => $user->user_email,
|
790 |
"billing_amount" => pmpro_formatPrice($user->membership_level->billing_amount),
|
@@ -812,7 +842,7 @@
|
|
812 |
$this->email = $user->user_email;
|
813 |
$this->subject = sprintf(__("Your membership at %s has ended", "paid-memberships-pro"), get_option("blogname"));
|
814 |
|
815 |
-
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "siteemail" => pmpro_getOption("from_email"), "login_link" => pmpro_login_url(), "display_name" => $user->display_name, "user_email" => $user->user_email, "levels_link" => pmpro_url("levels"));
|
816 |
|
817 |
$this->template = apply_filters("pmpro_email_template", "membership_expired", $this);
|
818 |
|
@@ -839,7 +869,7 @@
|
|
839 |
$this->email = $user->user_email;
|
840 |
$this->subject = sprintf(__("Your membership at %s will end soon", "paid-memberships-pro"), get_option("blogname"));
|
841 |
|
842 |
-
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "membership_id" => $user->membership_level->id, "membership_level_name" => $user->membership_level->name, "siteemail" => pmpro_getOption("from_email"), "login_link" => pmpro_login_url(), "enddate" => date_i18n(get_option('date_format'), $user->membership_level->enddate), "display_name" => $user->display_name, "user_email" => $user->user_email);
|
843 |
|
844 |
$this->template = apply_filters("pmpro_email_template", "membership_expiring", $this);
|
845 |
|
@@ -860,30 +890,30 @@
|
|
860 |
|
861 |
if(!empty($user->membership_level) && !empty($user->membership_level->name)) {
|
862 |
$membership_level_name = $user->membership_level->name;
|
863 |
-
$membership_level_id =
|
864 |
} else {
|
865 |
$membership_level_name = __('None', 'paid-memberships-pro');
|
866 |
-
$membership_level_id =
|
867 |
}
|
868 |
|
869 |
$this->email = $user->user_email;
|
870 |
$this->subject = sprintf(__("Your membership at %s has been changed", "paid-memberships-pro"), get_option("blogname"));
|
871 |
|
872 |
-
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "display_name" => $user->display_name, "user_login" => $user->user_login, "user_email" => $user->user_email, "sitename" => get_option("blogname"), "membership_id" => $membership_level_id, "membership_level_name" => $membership_level_name, "siteemail" => pmpro_getOption("from_email"), "login_link" => pmpro_login_url());
|
873 |
|
874 |
if(!empty($user->membership_level) && !empty($user->membership_level->ID)) {
|
875 |
-
$this->data["membership_change"] = sprintf(__("The new level is %s", 'paid-memberships-pro' ), $user->membership_level->name);
|
876 |
} else {
|
877 |
-
$this->data["membership_change"] = __("Your membership has been cancelled", "paid-memberships-pro");
|
878 |
}
|
879 |
|
880 |
if(!empty($user->membership_level->enddate))
|
881 |
{
|
882 |
-
$this->data["membership_change"] .= "
|
883 |
}
|
884 |
elseif(!empty($this->expiration_changed))
|
885 |
{
|
886 |
-
$this->data["membership_change"] .= "
|
887 |
}
|
888 |
|
889 |
$this->template = apply_filters("pmpro_email_template", "admin_change", $this);
|
@@ -899,41 +929,36 @@
|
|
899 |
|
900 |
if(!$user)
|
901 |
return false;
|
902 |
-
|
903 |
-
//check settings
|
904 |
-
$send = pmpro_getOption("email_admin_changes");
|
905 |
-
if(empty($send))
|
906 |
-
return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
|
907 |
-
|
908 |
//make sure we have the current membership level data
|
909 |
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID, true);
|
910 |
|
911 |
if(!empty($user->membership_level) && !empty($user->membership_level->name)) {
|
912 |
$membership_level_name = $user->membership_level->name;
|
913 |
-
$membership_level_id =
|
914 |
} else {
|
915 |
$membership_level_name = __('None', 'paid-memberships-pro');
|
916 |
-
$membership_level_id =
|
917 |
}
|
918 |
|
919 |
$this->email = get_bloginfo("admin_email");
|
920 |
$this->subject = sprintf(__("Membership for %s at %s has been changed", "paid-memberships-pro"), $user->user_login, get_option("blogname"));
|
921 |
|
922 |
-
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "display_name" => $user->display_name, "user_login" => $user->user_login, "user_email" => $user->user_email, "sitename" => get_option("blogname"), "membership_id" => $membership_level_id, "membership_level_name" => $membership_level_name, "siteemail" => get_bloginfo("admin_email"), "login_link" => pmpro_login_url());
|
923 |
|
924 |
if(!empty($user->membership_level) && !empty($user->membership_level->ID)) {
|
925 |
-
$this->data["membership_change"] = sprintf(__("The new level is %s", 'paid-memberships-pro' ), $user->membership_level->name);
|
926 |
} else {
|
927 |
-
$this->data["membership_change"] = __("Membership has been cancelled", 'paid-memberships-pro' );
|
928 |
}
|
929 |
|
930 |
if(!empty($user->membership_level) && !empty($user->membership_level->enddate))
|
931 |
{
|
932 |
-
$this->data["membership_change"] .= "
|
933 |
}
|
934 |
elseif(!empty($this->expiration_changed))
|
935 |
{
|
936 |
-
$this->data["membership_change"] .= "
|
937 |
}
|
938 |
|
939 |
$this->template = apply_filters("pmpro_email_template", "admin_change_admin", $this);
|
@@ -964,7 +989,7 @@
|
|
964 |
$level = pmpro_getLevel($order->membership_id);
|
965 |
|
966 |
$this->email = $user->user_email;
|
967 |
-
$this->subject = __('Invoice for
|
968 |
|
969 |
// Load invoice template
|
970 |
if ( file_exists( get_stylesheet_directory() . '/paid-memberships-pro/pages/orders-email.php' ) ) {
|
@@ -984,7 +1009,10 @@
|
|
984 |
$this->data = array(
|
985 |
'order_code' => $order->code,
|
986 |
'login_link' => pmpro_login_url(),
|
|
|
987 |
'invoice_link' => pmpro_login_url(pmpro_url("invoice", "?invoice=" . $order->code)),
|
|
|
|
|
988 |
'invoice' => $invoice
|
989 |
);
|
990 |
|
@@ -1024,6 +1052,7 @@
|
|
1024 |
"user_login" => $user->user_login,
|
1025 |
"sitename" => get_option("blogname"),
|
1026 |
"siteemail" => pmpro_getOption("from_email"),
|
|
|
1027 |
"invoice_url" => $invoice_url,
|
1028 |
);
|
1029 |
|
@@ -1062,39 +1091,10 @@
|
|
1062 |
"sitename" => get_option("blogname"),
|
1063 |
"siteemail" => pmpro_getOption("from_email"),
|
1064 |
"user_email" => $user->user_email,
|
|
|
1065 |
"invoice_url" => $invoice_url,
|
1066 |
);
|
1067 |
|
1068 |
return $this->sendEmail();
|
1069 |
}
|
1070 |
-
|
1071 |
-
|
1072 |
-
/**
|
1073 |
-
* Load the text for each default email template.
|
1074 |
-
* This overrides the old /email/*.html templates.
|
1075 |
-
*/
|
1076 |
-
function getDefaultEmailTemplate( $template = null ) {
|
1077 |
-
if( empty( $template ) && !empty( $this->template ) )
|
1078 |
-
$template = $this->template;
|
1079 |
-
|
1080 |
-
if( empty( $template ) )
|
1081 |
-
return false;
|
1082 |
-
|
1083 |
-
$r = '';
|
1084 |
-
|
1085 |
-
switch($template) {
|
1086 |
-
case "admin_change":
|
1087 |
-
$r = __( "<p>An administrator at !!sitename!! has changed your membership level.</p>
|
1088 |
-
|
1089 |
-
<p>!!membership_change!!.</p>
|
1090 |
-
|
1091 |
-
<p>If you did not request this membership change and would like more information please contact us at !!siteemail!!</p>
|
1092 |
-
|
1093 |
-
<p>Log in to your membership account here: !!login_link!!</p>", 'paid-memberships-pro' );
|
1094 |
-
break;
|
1095 |
-
//repeat above for each template
|
1096 |
-
}
|
1097 |
-
|
1098 |
-
return $r;
|
1099 |
-
}
|
1100 |
}
|
1 |
<?php
|
2 |
class PMProEmail
|
3 |
{
|
4 |
+
|
5 |
function __construct()
|
6 |
{
|
7 |
$this->email = $this->from = $this->fromname = $this->subject = $this->template = $this->data = $this->body = NULL;
|
8 |
}
|
9 |
|
10 |
function sendEmail($email = NULL, $from = NULL, $fromname = NULL, $subject = NULL, $template = NULL, $data = NULL)
|
11 |
+
{
|
12 |
//if values were passed
|
13 |
if($email)
|
14 |
$this->email = $email;
|
22 |
$this->template = $template;
|
23 |
if($data)
|
24 |
$this->data = $data;
|
25 |
+
|
26 |
+
// If email is disabled don't send it.
|
27 |
+
// Note option may have 'false' stored as a string.
|
28 |
+
$template_disabled = pmpro_getOption( 'email_' . $this->template . '_disabled' );
|
29 |
+
if ( ! empty( $template_disabled ) && $template_disabled !== 'false' ) {
|
30 |
+
return false;
|
31 |
+
}
|
32 |
+
|
33 |
//default values
|
34 |
+
global $current_user, $pmpro_email_templates_defaults;
|
35 |
if(!$this->email)
|
36 |
$this->email = $current_user->user_email;
|
37 |
|
40 |
|
41 |
if(!$this->fromname)
|
42 |
$this->fromname = pmpro_getOption("from_name");
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
|
44 |
if(!$this->template)
|
45 |
$this->template = "default";
|
46 |
+
|
47 |
+
//Okay let's get the subject stuff.
|
48 |
+
$template_subject = pmpro_getOption( 'email_' . $this->template . '_subject' );
|
49 |
+
if ( ! empty( $template_subject ) ) {
|
50 |
+
$this->subject = $template_subject;
|
51 |
+
} elseif ( empty( $this->subject ) ) {
|
52 |
+
$this->subject = ! empty( $pmpro_email_templates_defaults[$this->template]['subject'] ) ? sanitize_text_field( $pmpro_email_templates_defaults[$this->template]['subject'] ) : sprintf(__("An Email From %s", 'paid-memberships-pro' ), get_option("blogname"));
|
53 |
+
}
|
54 |
+
|
55 |
+
//decode the subject line in case there are apostrophes/etc in it
|
56 |
+
$this->subject = html_entity_decode($this->subject, ENT_QUOTES, 'UTF-8');
|
57 |
|
58 |
$this->headers = array("Content-Type: text/html");
|
59 |
|
62 |
//load the template
|
63 |
$locale = apply_filters("plugin_locale", get_locale(), "paid-memberships-pro");
|
64 |
|
65 |
+
if( empty( $this->data['body'] ) && ! empty( pmpro_getOption( 'email_' . $this->template . '_body' ) ) )
|
66 |
+
$this->body = pmpro_getOption( 'email_' . $this->template . '_body' );
|
67 |
+
elseif(file_exists(get_stylesheet_directory() . "/paid-memberships-pro/email/" . $locale . "/" . $this->template . ".html"))
|
68 |
$this->body = file_get_contents(get_stylesheet_directory() . "/paid-memberships-pro/email/" . $locale . "/" . $this->template . ".html"); //localized email folder in child theme
|
69 |
elseif(file_exists(get_stylesheet_directory() . "/paid-memberships-pro/email/" . $this->template . ".html"))
|
70 |
$this->body = file_get_contents(get_stylesheet_directory() . "/paid-memberships-pro/email/" . $this->template . ".html"); //email folder in child theme
|
82 |
$this->body = file_get_contents(WP_LANG_DIR . '/pmpro/email/' . $this->template . ".html"); //email folder in WP language folder
|
83 |
elseif(file_exists(PMPRO_DIR . "/languages/email/" . $locale . "/" . $this->template . ".html"))
|
84 |
$this->body = file_get_contents(PMPRO_DIR . "/languages/email/" . $locale . "/" . $this->template . ".html"); //email folder in PMPro language folder
|
85 |
+
elseif( empty( $this->data['body'] ) && ! empty( $pmpro_email_templates_defaults[$this->template]['body'] ) )
|
86 |
+
$this->body = $pmpro_email_templates_defaults[$this->template]['body']; //default template in plugin
|
|
|
|
|
87 |
elseif(!empty($this->data) && !empty($this->data['body']))
|
88 |
$this->body = $this->data['body']; //data passed in
|
89 |
|
90 |
+
|
91 |
+
// Get template header.
|
92 |
+
if( pmpro_getOption( 'email_header_disabled' ) != 'true' ) {
|
93 |
+
$email_header = pmpro_email_templates_get_template_body('header');
|
94 |
+
} else {
|
95 |
+
$email_header = '';
|
|
|
|
|
|
|
96 |
}
|
97 |
+
|
98 |
+
// Get template footer
|
99 |
+
if( pmpro_getOption( 'email_footer_disabled' ) != 'true' ) {
|
100 |
+
$email_footer = pmpro_email_templates_get_template_body('footer');
|
101 |
+
} else {
|
102 |
+
$email_footer = '';
|
103 |
+
}
|
104 |
+
|
105 |
+
// Add header and footer to email body.
|
106 |
+
$this->body = $email_header . $this->body . $email_footer;
|
107 |
+
|
108 |
//if data is a string, assume we mean to replace !!body!! with it
|
109 |
if(is_string($this->data))
|
110 |
$this->data = array("body"=>$data);
|
112 |
//filter for data
|
113 |
$this->data = apply_filters("pmpro_email_data", $this->data, $this); //filter
|
114 |
|
115 |
+
//swap data into body and subject line
|
116 |
if(is_array($this->data))
|
117 |
{
|
118 |
foreach($this->data as $key => $value)
|
119 |
{
|
120 |
if ( 'body' != $key ) {
|
121 |
$this->body = str_replace("!!" . $key . "!!", $value, $this->body);
|
122 |
+
$this->subject = str_replace("!!" . $key . "!!", $value, $this->subject);
|
123 |
}
|
124 |
}
|
125 |
}
|
215 |
if(!$user)
|
216 |
return false;
|
217 |
|
|
|
|
|
|
|
|
|
|
|
218 |
$this->email = get_bloginfo("admin_email");
|
219 |
$this->subject = sprintf(__("Membership for %s at %s has been CANCELLED", 'paid-memberships-pro'), $user->user_login, get_option("blogname"));
|
220 |
|
221 |
+
$this->data = array("user_login" => $user->user_login, "user_email" => $user->user_email, "display_name" => $user->display_name, "sitename" => get_option("blogname"), "siteemail" => pmpro_getOption("from_email"), "login_link" => pmpro_login_url(), "login_url" => pmpro_login_url());
|
222 |
|
223 |
if(!empty($old_level_id)) {
|
224 |
if(!is_array($old_level_id))
|
251 |
|
252 |
function sendCheckoutEmail($user = NULL, $invoice = NULL)
|
253 |
{
|
254 |
+
global $wpdb, $current_user, $discount_code;
|
255 |
if(!$user)
|
256 |
$user = $current_user;
|
257 |
|
280 |
"membership_level_confirmation_message" => $confirmation_message,
|
281 |
"membership_cost" => pmpro_getLevelCost($user->membership_level),
|
282 |
"login_link" => pmpro_login_url(),
|
283 |
+
"login_url" => pmpro_login_url(),
|
284 |
"display_name" => $user->display_name,
|
285 |
"user_email" => $user->user_email,
|
286 |
);
|
287 |
+
|
288 |
+
// Figure out which template to use.
|
289 |
+
if ( empty( $this->template ) ) {
|
290 |
+
if( ! empty( $invoice ) && ! pmpro_isLevelFree( $user->membership_level ) ) {
|
291 |
+
if( $invoice->gateway == "paypalexpress") {
|
292 |
+
$this->template = "checkout_express";
|
293 |
+
} elseif( $invoice->gateway == "check" ) {
|
294 |
+
$this->template = "checkout_check";
|
295 |
+
} elseif( pmpro_isLevelTrial( $user->membership_level ) ) {
|
296 |
+
$this->template = "checkout_trial";
|
297 |
+
} else {
|
298 |
+
$this->template = "checkout_paid";
|
299 |
+
}
|
300 |
+
} elseif( pmpro_isLevelFree( $user->membership_level ) ) {
|
301 |
+
$this->template = "checkout_free";
|
302 |
+
} else {
|
303 |
+
$this->template = "checkout_freetrial";
|
304 |
+
}
|
305 |
+
}
|
306 |
+
|
307 |
+
$this->template = apply_filters( "pmpro_email_template", $this->template, $this );
|
308 |
+
|
309 |
+
// Gather data depending on template being used.
|
310 |
+
if( in_array( $this->template, array( 'checkout_express', 'checkout_check', 'checkout_trial', 'checkout_paid' ) ) ) {
|
311 |
+
if( $this->template === 'checkout_check' ) {
|
312 |
$this->data["instructions"] = wpautop(pmpro_getOption("instructions"));
|
313 |
}
|
314 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
315 |
$this->data["invoice_id"] = $invoice->code;
|
316 |
$this->data["invoice_total"] = pmpro_formatPrice($invoice->total);
|
317 |
$this->data["invoice_date"] = date_i18n( get_option( 'date_format' ), $invoice->getTimestamp() );
|
335 |
$invoice->billing->country,
|
336 |
$invoice->billing->phone);
|
337 |
|
338 |
+
if( $invoice->getDiscountCode() ) {
|
339 |
$this->data["discount_code"] = "<p>" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $invoice->discount_code->code . "</p>\n";
|
340 |
+
} else {
|
341 |
$this->data["discount_code"] = "";
|
342 |
+
}
|
343 |
+
} elseif( $this->template === 'checkout_free' ) {
|
344 |
+
if( ! empty( $discount_code ) ) {
|
|
|
|
|
|
|
345 |
$this->data["discount_code"] = "<p>" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $discount_code . "</p>\n";
|
346 |
+
} else {
|
347 |
+
$this->data["discount_code"] = "";
|
348 |
+
}
|
349 |
+
} elseif ( $this->template === 'checkout_freetrial' ) {
|
350 |
+
if( ! empty( $discount_code ) ) {
|
|
|
|
|
|
|
351 |
$this->data["discount_code"] = "<p>" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $discount_code . "</p>\n";
|
352 |
+
} else {
|
353 |
+
$this->data["discount_code"] = "";
|
354 |
+
}
|
355 |
}
|
356 |
|
357 |
$enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(CONVERT_TZ(enddate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
|
358 |
+
if( $enddate ) {
|
359 |
$this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", 'paid-memberships-pro' ), date_i18n(get_option('date_format'), $enddate)) . "</p>\n";
|
360 |
+
} else {
|
361 |
$this->data["membership_expiration"] = "";
|
362 |
+
}
|
363 |
|
364 |
return $this->sendEmail();
|
365 |
}
|
366 |
|
367 |
function sendCheckoutAdminEmail($user = NULL, $invoice = NULL)
|
368 |
{
|
369 |
+
global $wpdb, $current_user, $discount_code;
|
370 |
if(!$user)
|
371 |
$user = $current_user;
|
372 |
|
373 |
if(!$user)
|
374 |
return false;
|
375 |
|
|
|
|
|
|
|
|
|
|
|
376 |
$this->email = get_bloginfo("admin_email");
|
377 |
+
$this->subject = sprintf(__("Member checkout for %s at %s", 'paid-memberships-pro' ), $user->membership_level->name, get_option("blogname"));
|
378 |
|
379 |
$this->data = array(
|
380 |
"subject" => $this->subject,
|
386 |
"membership_level_name" => $user->membership_level->name,
|
387 |
"membership_cost" => pmpro_getLevelCost($user->membership_level),
|
388 |
"login_link" => pmpro_login_url(),
|
389 |
+
"login_url" => pmpro_login_url(),
|
390 |
"display_name" => $user->display_name,
|
391 |
"user_email" => $user->user_email,
|
392 |
);
|
393 |
|
394 |
+
// Figure out which template to use.
|
395 |
+
if ( empty( $this->template ) ) {
|
396 |
+
if( ! empty( $invoice ) && ! pmpro_isLevelFree( $user->membership_level ) ) {
|
397 |
+
if( $invoice->gateway == "paypalexpress") {
|
398 |
+
$this->template = "checkout_express_admin";
|
399 |
+
} elseif( $invoice->gateway == "check" ) {
|
400 |
+
$this->template = "checkout_check_admin";
|
401 |
+
} elseif( pmpro_isLevelTrial( $user->membership_level ) ) {
|
402 |
+
$this->template = "checkout_trial_admin";
|
403 |
+
} else {
|
404 |
+
$this->template = "checkout_paid_admin";
|
405 |
+
}
|
406 |
+
} elseif( pmpro_isLevelFree( $user->membership_level ) ) {
|
407 |
+
$this->template = "checkout_free_admin";
|
408 |
+
} else {
|
409 |
+
$this->template = "checkout_freetrial_admin";
|
410 |
+
}
|
411 |
+
}
|
412 |
+
|
413 |
+
$this->template = apply_filters( "pmpro_email_template", $this->template, $this );
|
414 |
+
|
415 |
+
// Gather data depending on template being used.
|
416 |
+
if( in_array( $this->template, array( 'checkout_express_admin', 'checkout_check_admin', 'checkout_trial_admin', 'checkout_paid_admin' ) ) ) {
|
417 |
$this->data["invoice_id"] = $invoice->code;
|
418 |
$this->data["invoice_total"] = pmpro_formatPrice($invoice->total);
|
419 |
$this->data["invoice_date"] = date_i18n(get_option('date_format'), $invoice->getTimestamp());
|
437 |
$invoice->billing->country,
|
438 |
$invoice->billing->phone);
|
439 |
|
440 |
+
if( $invoice->getDiscountCode() ) {
|
441 |
$this->data["discount_code"] = "<p>" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $invoice->discount_code->code . "</p>\n";
|
442 |
+
} else {
|
443 |
$this->data["discount_code"] = "";
|
444 |
+
}
|
445 |
+
} elseif( $this->template === 'checkout_free_admin' ) {
|
446 |
+
if( ! empty( $discount_code ) ) {
|
|
|
|
|
|
|
447 |
$this->data["discount_code"] = "<p>" . __("Discount Code", 'paid-memberships-pro' ) . ": " . $discount_code . "</p>\n";
|
448 |
+
} else {
|
449 |
+
$this->data["discount_code"] = "";
|
450 |
+
}
|
451 |
+
} elseif( $this->template === 'checkout_freetrial_admin' ) {
|
|
|
|
|
452 |
$this->data["discount_code"] = "";
|
453 |
+
}
|
454 |
|
455 |
$enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(CONVERT_TZ(enddate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
|
456 |
+
if( $enddate ) {
|
457 |
$this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", 'paid-memberships-pro' ), date_i18n(get_option('date_format'), $enddate)) . "</p>\n";
|
458 |
+
} else {
|
459 |
$this->data["membership_expiration"] = "";
|
460 |
+
}
|
461 |
|
462 |
return $this->sendEmail();
|
463 |
}
|
495 |
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
496 |
"expirationmonth" => $invoice->expirationmonth,
|
497 |
"expirationyear" => $invoice->expirationyear,
|
498 |
+
"login_link" => pmpro_login_url(),
|
499 |
+
"login_url" => pmpro_login_url(),
|
500 |
);
|
501 |
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
502 |
$invoice->billing->street,
|
521 |
if(!$user || !$invoice)
|
522 |
return false;
|
523 |
|
|
|
|
|
|
|
|
|
|
|
524 |
$this->email = get_bloginfo("admin_email");
|
525 |
$this->subject = sprintf(__("Billing information has been updated for %s at %s", "paid-memberships-pro"), $user->user_login, get_option("blogname"));
|
526 |
|
545 |
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
546 |
"expirationmonth" => $invoice->expirationmonth,
|
547 |
"expirationyear" => $invoice->expirationyear,
|
548 |
+
"login_link" => pmpro_login_url(),
|
549 |
+
"login_url" => pmpro_login_url(),
|
550 |
);
|
551 |
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
552 |
$invoice->billing->street,
|
570 |
|
571 |
if(!$user || !$invoice)
|
572 |
return false;
|
573 |
+
|
574 |
+
$membership_level = pmpro_getSpecificMembershipLevelForUser( $user->ID, $invoice->membership_id );
|
575 |
|
576 |
$this->email = $user->user_email;
|
577 |
+
$this->subject = sprintf(__("Membership payment failed at %s", "paid-memberships-pro"), get_option("blogname"));
|
578 |
|
579 |
$this->data = array(
|
580 |
"subject" => $this->subject,
|
582 |
"user_login" => $user->user_login,
|
583 |
"sitename" => get_option("blogname"),
|
584 |
"siteemail" => pmpro_getOption("from_email"),
|
585 |
+
"membership_id" => $membership_level->id,
|
586 |
+
"membership_level_name" => $membership_level->name,
|
587 |
"display_name" => $user->display_name,
|
588 |
"user_email" => $user->user_email,
|
589 |
"billing_name" => $invoice->billing->name,
|
597 |
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
598 |
"expirationmonth" => $invoice->expirationmonth,
|
599 |
"expirationyear" => $invoice->expirationyear,
|
600 |
+
"login_link" => pmpro_login_url(pmpro_url("billing")),
|
601 |
+
"login_url" => pmpro_login_url(pmpro_url("billing")),
|
602 |
);
|
603 |
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
604 |
$invoice->billing->street,
|
620 |
return false;
|
621 |
|
622 |
$user = get_userdata($invoice->user_id);
|
623 |
+
$membership_level = pmpro_getSpecificMembershipLevelForUser( $user->ID, $invoice->membership_id );
|
624 |
|
625 |
$this->email = $email;
|
626 |
+
$this->subject = sprintf(__("Membership payment failed For %s at %s", "paid-memberships-pro"), $user->display_name, get_option("blogname"));
|
627 |
|
628 |
$this->data = array(
|
629 |
"subject" => $this->subject,
|
631 |
"user_login" => $user->user_login,
|
632 |
"sitename" => get_option("blogname"),
|
633 |
"siteemail" => pmpro_getOption("from_email"),
|
634 |
+
"membership_id" => $membership_level->id,
|
635 |
+
"membership_level_name" => $membership_level->name,
|
636 |
"display_name" => $user->display_name,
|
637 |
"user_email" => $user->user_email,
|
638 |
"billing_name" => $invoice->billing->name,
|
646 |
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
647 |
"expirationmonth" => $invoice->expirationmonth,
|
648 |
"expirationyear" => $invoice->expirationyear,
|
649 |
+
"login_link" => pmpro_login_url( get_edit_user_link( $user->ID ) ),
|
650 |
+
"login_url" => pmpro_login_url( get_edit_user_link( $user->ID ) ),
|
651 |
);
|
652 |
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
653 |
$invoice->billing->street,
|
672 |
return false;
|
673 |
|
674 |
$this->email = $user->user_email;
|
675 |
+
$this->subject = sprintf(__("Credit card on file expiring soon at %s", "paid-memberships-pro"), get_option("blogname"));
|
676 |
|
677 |
$this->data = array(
|
678 |
"subject" => $this->subject,
|
695 |
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
696 |
"expirationmonth" => $invoice->expirationmonth,
|
697 |
"expirationyear" => $invoice->expirationyear,
|
698 |
+
"login_link" => pmpro_login_url(pmpro_url("billing")),
|
699 |
+
"login_url" => pmpro_login_url(pmpro_url("billing"))
|
700 |
);
|
701 |
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
702 |
$invoice->billing->street,
|
724 |
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID);
|
725 |
|
726 |
$this->email = $user->user_email;
|
727 |
+
$this->subject = sprintf(__("Invoice for %s membership", "paid-memberships-pro"), get_option("blogname"));
|
728 |
|
729 |
$this->data = array(
|
730 |
"subject" => $this->subject,
|
751 |
"expirationmonth" => $invoice->expirationmonth,
|
752 |
"expirationyear" => $invoice->expirationyear,
|
753 |
"login_link" => pmpro_login_url(),
|
754 |
+
"login_url" => pmpro_login_url(),
|
755 |
+
"invoice_link" => pmpro_login_url(pmpro_url("invoice", "?invoice=" . $invoice->code)),
|
756 |
+
"invoice_url" => pmpro_login_url(pmpro_url("invoice", "?invoice=" . $invoice->code))
|
757 |
+
);
|
758 |
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
759 |
$invoice->billing->street,
|
760 |
"", //address 2
|
813 |
"membership_id" => $user->membership_level->id,
|
814 |
"membership_level_name" => $user->membership_level->name,
|
815 |
"siteemail" => pmpro_getOption("from_email"),
|
816 |
+
"login_link" => pmpro_login_url(),
|
817 |
+
"login_url" => pmpro_login_url(),
|
818 |
"display_name" => $user->display_name,
|
819 |
"user_email" => $user->user_email,
|
820 |
"billing_amount" => pmpro_formatPrice($user->membership_level->billing_amount),
|
842 |
$this->email = $user->user_email;
|
843 |
$this->subject = sprintf(__("Your membership at %s has ended", "paid-memberships-pro"), get_option("blogname"));
|
844 |
|
845 |
+
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "siteemail" => pmpro_getOption("from_email"), "login_link" => pmpro_login_url(), "login_url" => pmpro_login_url(), "display_name" => $user->display_name, "user_email" => $user->user_email, "levels_link" => pmpro_url("levels"), "levels_url" => pmpro_url("levels"));
|
846 |
|
847 |
$this->template = apply_filters("pmpro_email_template", "membership_expired", $this);
|
848 |
|
869 |
$this->email = $user->user_email;
|
870 |
$this->subject = sprintf(__("Your membership at %s will end soon", "paid-memberships-pro"), get_option("blogname"));
|
871 |
|
872 |
+
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "membership_id" => $user->membership_level->id, "membership_level_name" => $user->membership_level->name, "siteemail" => pmpro_getOption("from_email"), "login_link" => pmpro_login_url(), "login_url" => pmpro_login_url(), "enddate" => date_i18n(get_option('date_format'), $user->membership_level->enddate), "display_name" => $user->display_name, "user_email" => $user->user_email);
|
873 |
|
874 |
$this->template = apply_filters("pmpro_email_template", "membership_expiring", $this);
|
875 |
|
890 |
|
891 |
if(!empty($user->membership_level) && !empty($user->membership_level->name)) {
|
892 |
$membership_level_name = $user->membership_level->name;
|
893 |
+
$membership_level_id = $user->membership_level->id;
|
894 |
} else {
|
895 |
$membership_level_name = __('None', 'paid-memberships-pro');
|
896 |
+
$membership_level_id = '';
|
897 |
}
|
898 |
|
899 |
$this->email = $user->user_email;
|
900 |
$this->subject = sprintf(__("Your membership at %s has been changed", "paid-memberships-pro"), get_option("blogname"));
|
901 |
|
902 |
+
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "display_name" => $user->display_name, "user_login" => $user->user_login, "user_email" => $user->user_email, "sitename" => get_option("blogname"), "membership_id" => $membership_level_id, "membership_level_name" => $membership_level_name, "siteemail" => pmpro_getOption("from_email"), "login_link" => pmpro_login_url(), "login_url" => pmpro_login_url());
|
903 |
|
904 |
if(!empty($user->membership_level) && !empty($user->membership_level->ID)) {
|
905 |
+
$this->data["membership_change"] = sprintf(__("The new level is %s.", 'paid-memberships-pro' ), $user->membership_level->name);
|
906 |
} else {
|
907 |
+
$this->data["membership_change"] = __("Your membership has been cancelled.", "paid-memberships-pro");
|
908 |
}
|
909 |
|
910 |
if(!empty($user->membership_level->enddate))
|
911 |
{
|
912 |
+
$this->data["membership_change"] .= " " . sprintf(__("This membership will expire on %s.", 'paid-memberships-pro' ), date_i18n(get_option('date_format'), $user->membership_level->enddate));
|
913 |
}
|
914 |
elseif(!empty($this->expiration_changed))
|
915 |
{
|
916 |
+
$this->data["membership_change"] .= " " . __("This membership does not expire.", 'paid-memberships-pro' );
|
917 |
}
|
918 |
|
919 |
$this->template = apply_filters("pmpro_email_template", "admin_change", $this);
|
929 |
|
930 |
if(!$user)
|
931 |
return false;
|
932 |
+
|
|
|
|
|
|
|
|
|
|
|
933 |
//make sure we have the current membership level data
|
934 |
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID, true);
|
935 |
|
936 |
if(!empty($user->membership_level) && !empty($user->membership_level->name)) {
|
937 |
$membership_level_name = $user->membership_level->name;
|
938 |
+
$membership_level_id = $user->membership_level->id;
|
939 |
} else {
|
940 |
$membership_level_name = __('None', 'paid-memberships-pro');
|
941 |
+
$membership_level_id = '';
|
942 |
}
|
943 |
|
944 |
$this->email = get_bloginfo("admin_email");
|
945 |
$this->subject = sprintf(__("Membership for %s at %s has been changed", "paid-memberships-pro"), $user->user_login, get_option("blogname"));
|
946 |
|
947 |
+
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "display_name" => $user->display_name, "user_login" => $user->user_login, "user_email" => $user->user_email, "sitename" => get_option("blogname"), "membership_id" => $membership_level_id, "membership_level_name" => $membership_level_name, "siteemail" => get_bloginfo("admin_email"), "login_link" => pmpro_login_url(), "login_url" => pmpro_login_url());
|
948 |
|
949 |
if(!empty($user->membership_level) && !empty($user->membership_level->ID)) {
|
950 |
+
$this->data["membership_change"] = sprintf(__("The new level is %s.", 'paid-memberships-pro' ), $user->membership_level->name);
|
951 |
} else {
|
952 |
+
$this->data["membership_change"] = __("Membership has been cancelled.", 'paid-memberships-pro' );
|
953 |
}
|
954 |
|
955 |
if(!empty($user->membership_level) && !empty($user->membership_level->enddate))
|
956 |
{
|
957 |
+
$this->data["membership_change"] .= " " . sprintf(__("This membership will expire on %s.", 'paid-memberships-pro' ), date_i18n(get_option('date_format'), $user->membership_level->enddate));
|
958 |
}
|
959 |
elseif(!empty($this->expiration_changed))
|
960 |
{
|
961 |
+
$this->data["membership_change"] .= " " . __("This membership does not expire.", 'paid-memberships-pro' );
|
962 |
}
|
963 |
|
964 |
$this->template = apply_filters("pmpro_email_template", "admin_change_admin", $this);
|
989 |
$level = pmpro_getLevel($order->membership_id);
|
990 |
|
991 |
$this->email = $user->user_email;
|
992 |
+
$this->subject = __('Invoice for order #: ', 'paid-memberships-pro') . $order->code;
|
993 |
|
994 |
// Load invoice template
|
995 |
if ( file_exists( get_stylesheet_directory() . '/paid-memberships-pro/pages/orders-email.php' ) ) {
|
1009 |
$this->data = array(
|
1010 |
'order_code' => $order->code,
|
1011 |
'login_link' => pmpro_login_url(),
|
1012 |
+
'login_url' => pmpro_login_url(),
|
1013 |
'invoice_link' => pmpro_login_url(pmpro_url("invoice", "?invoice=" . $order->code)),
|
1014 |
+
'invoice_url' => pmpro_login_url(pmpro_url("invoice", "?invoice=" . $order->code)),
|
1015 |
+
"invoice_id" => $order->id,
|
1016 |
'invoice' => $invoice
|
1017 |
);
|
1018 |
|
1052 |
"user_login" => $user->user_login,
|
1053 |
"sitename" => get_option("blogname"),
|
1054 |
"siteemail" => pmpro_getOption("from_email"),
|
1055 |
+
"invoice_link" => $invoice_url,
|
1056 |
"invoice_url" => $invoice_url,
|
1057 |
);
|
1058 |
|
1091 |
"sitename" => get_option("blogname"),
|
1092 |
"siteemail" => pmpro_getOption("from_email"),
|
1093 |
"user_email" => $user->user_email,
|
1094 |
+
"invoice_link" => $invoice_url,
|
1095 |
"invoice_url" => $invoice_url,
|
1096 |
);
|
1097 |
|
1098 |
return $this->sendEmail();
|
1099 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1100 |
}
|
classes/gateways/class.pmprogateway.php
CHANGED
@@ -20,7 +20,7 @@
|
|
20 |
if(!pmpro_isLevelTrial($order->membership_level))
|
21 |
{
|
22 |
//subscription will start today with a 1 period trial
|
23 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
24 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
25 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
26 |
$order->TrialBillingCycles = 1;
|
@@ -33,7 +33,7 @@
|
|
33 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
34 |
{
|
35 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
36 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
37 |
$order->TrialBillingCycles++;
|
38 |
|
39 |
//add a billing cycle to make up for the trial, if applicable
|
@@ -43,7 +43,7 @@
|
|
43 |
else
|
44 |
{
|
45 |
//add a period to the start date to account for the initial payment
|
46 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
47 |
}
|
48 |
|
49 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
@@ -67,7 +67,7 @@
|
|
67 |
if(!pmpro_isLevelTrial($order->membership_level))
|
68 |
{
|
69 |
//subscription will start today with a 1 period trial
|
70 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
71 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
72 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
73 |
$order->TrialBillingCycles = 1;
|
@@ -80,7 +80,7 @@
|
|
80 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
81 |
{
|
82 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
83 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
84 |
$order->TrialBillingCycles++;
|
85 |
|
86 |
//add a billing cycle to make up for the trial, if applicable
|
@@ -90,7 +90,7 @@
|
|
90 |
else
|
91 |
{
|
92 |
//add a period to the start date to account for the initial payment
|
93 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
94 |
}
|
95 |
|
96 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
20 |
if(!pmpro_isLevelTrial($order->membership_level))
|
21 |
{
|
22 |
//subscription will start today with a 1 period trial
|
23 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
24 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
25 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
26 |
$order->TrialBillingCycles = 1;
|
33 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
34 |
{
|
35 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
36 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
37 |
$order->TrialBillingCycles++;
|
38 |
|
39 |
//add a billing cycle to make up for the trial, if applicable
|
43 |
else
|
44 |
{
|
45 |
//add a period to the start date to account for the initial payment
|
46 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
47 |
}
|
48 |
|
49 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
67 |
if(!pmpro_isLevelTrial($order->membership_level))
|
68 |
{
|
69 |
//subscription will start today with a 1 period trial
|
70 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
71 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
72 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
73 |
$order->TrialBillingCycles = 1;
|
80 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
81 |
{
|
82 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
83 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
84 |
$order->TrialBillingCycles++;
|
85 |
|
86 |
//add a billing cycle to make up for the trial, if applicable
|
90 |
else
|
91 |
{
|
92 |
//add a period to the start date to account for the initial payment
|
93 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
94 |
}
|
95 |
|
96 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
classes/gateways/class.pmprogateway_authorizenet.php
CHANGED
@@ -123,7 +123,7 @@ class PMProGateway_authorizenet extends PMProGateway
|
|
123 |
<label for="transactionkey"><?php _e('Transaction Key', 'paid-memberships-pro' );?>:</label>
|
124 |
</th>
|
125 |
<td>
|
126 |
-
<input type="text" id="transactionkey" name="transactionkey" value="<?php echo esc_attr($values['transactionkey'])?>" class="regular-text code" />
|
127 |
</td>
|
128 |
</tr>
|
129 |
<tr class="gateway gateway_authorizenet" <?php if($gateway != "authorizenet") { ?>style="display: none;"<?php } ?>>
|
@@ -154,7 +154,7 @@ class PMProGateway_authorizenet extends PMProGateway
|
|
154 |
if(!pmpro_isLevelTrial($order->membership_level))
|
155 |
{
|
156 |
//subscription will start today with a 1 period trial
|
157 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
158 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
159 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
160 |
$order->TrialBillingCycles = 1;
|
@@ -167,7 +167,7 @@ class PMProGateway_authorizenet extends PMProGateway
|
|
167 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
168 |
{
|
169 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
170 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
171 |
$order->TrialBillingCycles++;
|
172 |
|
173 |
//add a billing cycle to make up for the trial, if applicable
|
@@ -177,7 +177,7 @@ class PMProGateway_authorizenet extends PMProGateway
|
|
177 |
else
|
178 |
{
|
179 |
//add a period to the start date to account for the initial payment
|
180 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
181 |
}
|
182 |
|
183 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
@@ -201,7 +201,7 @@ class PMProGateway_authorizenet extends PMProGateway
|
|
201 |
if(!pmpro_isLevelTrial($order->membership_level))
|
202 |
{
|
203 |
//subscription will start today with a 1 period trial
|
204 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
205 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
206 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
207 |
$order->TrialBillingCycles = 1;
|
@@ -214,7 +214,7 @@ class PMProGateway_authorizenet extends PMProGateway
|
|
214 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
215 |
{
|
216 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
217 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
218 |
$order->TrialBillingCycles++;
|
219 |
|
220 |
//add a billing cycle to make up for the trial, if applicable
|
@@ -224,7 +224,7 @@ class PMProGateway_authorizenet extends PMProGateway
|
|
224 |
else
|
225 |
{
|
226 |
//add a period to the start date to account for the initial payment
|
227 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
228 |
}
|
229 |
|
230 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
@@ -1097,4 +1097,4 @@ class PMProGateway_authorizenet extends PMProGateway
|
|
1097 |
return substr($haystack,$start_position,$end_position-$start_position);
|
1098 |
}
|
1099 |
}
|
1100 |
-
}
|
123 |
<label for="transactionkey"><?php _e('Transaction Key', 'paid-memberships-pro' );?>:</label>
|
124 |
</th>
|
125 |
<td>
|
126 |
+
<input type="text" id="transactionkey" name="transactionkey" value="<?php echo esc_attr($values['transactionkey'])?>" autocomplete="off" class="regular-text code pmpro-admin-secure-key" />
|
127 |
</td>
|
128 |
</tr>
|
129 |
<tr class="gateway gateway_authorizenet" <?php if($gateway != "authorizenet") { ?>style="display: none;"<?php } ?>>
|
154 |
if(!pmpro_isLevelTrial($order->membership_level))
|
155 |
{
|
156 |
//subscription will start today with a 1 period trial
|
157 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
158 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
159 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
160 |
$order->TrialBillingCycles = 1;
|
167 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
168 |
{
|
169 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
170 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
171 |
$order->TrialBillingCycles++;
|
172 |
|
173 |
//add a billing cycle to make up for the trial, if applicable
|
177 |
else
|
178 |
{
|
179 |
//add a period to the start date to account for the initial payment
|
180 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
181 |
}
|
182 |
|
183 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
201 |
if(!pmpro_isLevelTrial($order->membership_level))
|
202 |
{
|
203 |
//subscription will start today with a 1 period trial
|
204 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
205 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
206 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
207 |
$order->TrialBillingCycles = 1;
|
214 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
215 |
{
|
216 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
217 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
218 |
$order->TrialBillingCycles++;
|
219 |
|
220 |
//add a billing cycle to make up for the trial, if applicable
|
224 |
else
|
225 |
{
|
226 |
//add a period to the start date to account for the initial payment
|
227 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
228 |
}
|
229 |
|
230 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
1097 |
return substr($haystack,$start_position,$end_position-$start_position);
|
1098 |
}
|
1099 |
}
|
1100 |
+
}
|
classes/gateways/class.pmprogateway_braintree.php
CHANGED
@@ -329,7 +329,7 @@ use Braintree\WebhookNotification as Braintree_WebhookNotification;
|
|
329 |
<label for="braintree_privatekey"><?php _e('Private Key', 'paid-memberships-pro' );?>:</label>
|
330 |
</th>
|
331 |
<td>
|
332 |
-
<input type="text" id="braintree_privatekey" name="braintree_privatekey" value="<?php echo esc_attr($values['braintree_privatekey'])?>" class="regular-text code" />
|
333 |
</td>
|
334 |
</tr>
|
335 |
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
@@ -337,7 +337,7 @@ use Braintree\WebhookNotification as Braintree_WebhookNotification;
|
|
337 |
<label for="braintree_encryptionkey"><?php _e('Client-Side Encryption Key', 'paid-memberships-pro' );?>:</label>
|
338 |
</th>
|
339 |
<td>
|
340 |
-
<textarea id="braintree_encryptionkey" name="braintree_encryptionkey" rows="3" cols="50" class="large-text code"><?php echo esc_textarea($values['braintree_encryptionkey'])?></textarea>
|
341 |
</td>
|
342 |
</tr>
|
343 |
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
@@ -706,8 +706,7 @@ use Braintree\WebhookNotification as Braintree_WebhookNotification;
|
|
706 |
$this->customer = Braintree_Customer::find($customer_id);
|
707 |
|
708 |
//update the customer address, description and card
|
709 |
-
if(!empty($order->
|
710 |
-
{
|
711 |
//put data in array for Braintree API calls
|
712 |
$update_array = array(
|
713 |
'firstName' => $order->FirstName,
|
@@ -882,7 +881,7 @@ use Braintree\WebhookNotification as Braintree_WebhookNotification;
|
|
882 |
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
883 |
|
884 |
//convert to a profile start date
|
885 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp")))
|
886 |
|
887 |
//filter the start date
|
888 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
@@ -990,18 +989,17 @@ use Braintree\WebhookNotification as Braintree_WebhookNotification;
|
|
990 |
|
991 |
try {
|
992 |
$webhookNotification = Braintree_WebhookNotification::parse( $_POST['bt_signature'], $_POST['bt_payload'] );
|
|
|
|
|
|
|
|
|
993 |
} catch ( \Exception $e ) {
|
994 |
// Don't do anything
|
995 |
}
|
996 |
}
|
997 |
|
998 |
// Always cancel, even if Braintree fails
|
999 |
-
$order->updateStatus("cancelled" );
|
1000 |
-
|
1001 |
-
if ( Braintree_WebhookNotification::SUBSCRIPTION_CANCELED === $webhookNotification->kind ) {
|
1002 |
-
// Return, we're already processing the cancellation
|
1003 |
-
return true;
|
1004 |
-
}
|
1005 |
|
1006 |
//require a subscription id
|
1007 |
if(empty($order->subscription_transaction_id))
|
@@ -1071,4 +1069,44 @@ use Braintree\WebhookNotification as Braintree_WebhookNotification;
|
|
1071 |
*/
|
1072 |
return apply_filters( 'pmpro_braintree_plan_id', 'pmpro_' . $level_id, $level_id );
|
1073 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1074 |
}
|
329 |
<label for="braintree_privatekey"><?php _e('Private Key', 'paid-memberships-pro' );?>:</label>
|
330 |
</th>
|
331 |
<td>
|
332 |
+
<input type="text" id="braintree_privatekey" name="braintree_privatekey" value="<?php echo esc_attr($values['braintree_privatekey'])?>" autocomplete="off" class="regular-text code pmpro-admin-secure-key" />
|
333 |
</td>
|
334 |
</tr>
|
335 |
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
337 |
<label for="braintree_encryptionkey"><?php _e('Client-Side Encryption Key', 'paid-memberships-pro' );?>:</label>
|
338 |
</th>
|
339 |
<td>
|
340 |
+
<textarea id="braintree_encryptionkey" name="braintree_encryptionkey" autocomplete="off" rows="3" cols="50" class="large-text code pmpro-admin-secure-key"><?php echo esc_textarea($values['braintree_encryptionkey'])?></textarea>
|
341 |
</td>
|
342 |
</tr>
|
343 |
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
706 |
$this->customer = Braintree_Customer::find($customer_id);
|
707 |
|
708 |
//update the customer address, description and card
|
709 |
+
if( ! empty( $order->braintree ) && ! empty( $order->braintree->number ) ) {
|
|
|
710 |
//put data in array for Braintree API calls
|
711 |
$update_array = array(
|
712 |
'firstName' => $order->FirstName,
|
881 |
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
882 |
|
883 |
//convert to a profile start date
|
884 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp")));
|
885 |
|
886 |
//filter the start date
|
887 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
989 |
|
990 |
try {
|
991 |
$webhookNotification = Braintree_WebhookNotification::parse( $_POST['bt_signature'], $_POST['bt_payload'] );
|
992 |
+
if ( Braintree_WebhookNotification::SUBSCRIPTION_CANCELED === $webhookNotification->kind ) {
|
993 |
+
// Return, we're already processing the cancellation
|
994 |
+
return true;
|
995 |
+
}
|
996 |
} catch ( \Exception $e ) {
|
997 |
// Don't do anything
|
998 |
}
|
999 |
}
|
1000 |
|
1001 |
// Always cancel, even if Braintree fails
|
1002 |
+
$order->updateStatus("cancelled" );
|
|
|
|
|
|
|
|
|
|
|
1003 |
|
1004 |
//require a subscription id
|
1005 |
if(empty($order->subscription_transaction_id))
|
1069 |
*/
|
1070 |
return apply_filters( 'pmpro_braintree_plan_id', 'pmpro_' . $level_id, $level_id );
|
1071 |
}
|
1072 |
+
|
1073 |
+
function get_subscription( &$order ) {
|
1074 |
+
// Does order have a subscription?
|
1075 |
+
if ( empty( $order ) || empty( $order->subscription_transaction_id ) ) {
|
1076 |
+
return false;
|
1077 |
+
}
|
1078 |
+
|
1079 |
+
try {
|
1080 |
+
$subscription = Braintree_Subscription::find( $order->subscription_transaction_id );
|
1081 |
+
} catch ( Exception $e ) {
|
1082 |
+
$order->error = __( "Error getting subscription with Braintree:", 'paid-memberships-pro' ) . $e->getMessage();
|
1083 |
+
$order->shorterror = $order->error;
|
1084 |
+
return false;
|
1085 |
+
}
|
1086 |
+
|
1087 |
+
return $subscription;
|
1088 |
+
}
|
1089 |
+
|
1090 |
+
/**
|
1091 |
+
* Filter pmpro_next_payment to get date via API if possible
|
1092 |
+
*/
|
1093 |
+
static function pmpro_next_payment( $timestamp, $user_id, $order_status ) {
|
1094 |
+
// Check that we have a user ID...
|
1095 |
+
if ( ! empty( $user_id ) ) {
|
1096 |
+
// Get last order...
|
1097 |
+
$order = new MemberOrder();
|
1098 |
+
$order->getLastMemberOrder( $user_id, $order_status );
|
1099 |
+
|
1100 |
+
// Check if this is a Braintree order with a subscription transaction id...
|
1101 |
+
if ( ! empty( $order->id ) && ! empty( $order->subscription_transaction_id ) && $order->gateway == "braintree" ) {
|
1102 |
+
// Get the subscription and return the next billing date.
|
1103 |
+
$subscription = $order->Gateway->get_subscription( $order );
|
1104 |
+
if ( ! empty( $subscription ) ) {
|
1105 |
+
$timestamp = $subscription->nextBillingDate->getTimestamp();
|
1106 |
+
}
|
1107 |
+
}
|
1108 |
+
}
|
1109 |
+
|
1110 |
+
return $timestamp;
|
1111 |
+
}
|
1112 |
}
|
classes/gateways/class.pmprogateway_check.php
CHANGED
@@ -176,7 +176,7 @@
|
|
176 |
if(!pmpro_isLevelTrial($order->membership_level))
|
177 |
{
|
178 |
//subscription will start today with a 1 period trial
|
179 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
180 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
181 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
182 |
$order->TrialBillingCycles = 1;
|
@@ -189,7 +189,7 @@
|
|
189 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
190 |
{
|
191 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
192 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
193 |
$order->TrialBillingCycles++;
|
194 |
|
195 |
//add a billing cycle to make up for the trial, if applicable
|
@@ -199,7 +199,7 @@
|
|
199 |
else
|
200 |
{
|
201 |
//add a period to the start date to account for the initial payment
|
202 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
203 |
}
|
204 |
|
205 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
@@ -223,7 +223,7 @@
|
|
223 |
if(!pmpro_isLevelTrial($order->membership_level))
|
224 |
{
|
225 |
//subscription will start today with a 1 period trial
|
226 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
227 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
228 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
229 |
$order->TrialBillingCycles = 1;
|
@@ -236,7 +236,7 @@
|
|
236 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
237 |
{
|
238 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
239 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
240 |
$order->TrialBillingCycles++;
|
241 |
|
242 |
//add a billing cycle to make up for the trial, if applicable
|
@@ -246,7 +246,7 @@
|
|
246 |
else
|
247 |
{
|
248 |
//add a period to the start date to account for the initial payment
|
249 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
250 |
}
|
251 |
|
252 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
176 |
if(!pmpro_isLevelTrial($order->membership_level))
|
177 |
{
|
178 |
//subscription will start today with a 1 period trial
|
179 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
180 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
181 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
182 |
$order->TrialBillingCycles = 1;
|
189 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
190 |
{
|
191 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
192 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
193 |
$order->TrialBillingCycles++;
|
194 |
|
195 |
//add a billing cycle to make up for the trial, if applicable
|
199 |
else
|
200 |
{
|
201 |
//add a period to the start date to account for the initial payment
|
202 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
203 |
}
|
204 |
|
205 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
223 |
if(!pmpro_isLevelTrial($order->membership_level))
|
224 |
{
|
225 |
//subscription will start today with a 1 period trial
|
226 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
227 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
228 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
229 |
$order->TrialBillingCycles = 1;
|
236 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
237 |
{
|
238 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
239 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
240 |
$order->TrialBillingCycles++;
|
241 |
|
242 |
//add a billing cycle to make up for the trial, if applicable
|
246 |
else
|
247 |
{
|
248 |
//add a period to the start date to account for the initial payment
|
249 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
250 |
}
|
251 |
|
252 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
classes/gateways/class.pmprogateway_cybersource.php
CHANGED
@@ -102,7 +102,7 @@
|
|
102 |
<label for="cybersource_securitykey"><?php _e('Transaction Security Key', 'paid-memberships-pro' );?>:</label>
|
103 |
</th>
|
104 |
<td>
|
105 |
-
<textarea id="cybersource_securitykey" name="cybersource_securitykey" rows="3" cols="50" class="large-text code"><?php echo esc_textarea($values['cybersource_securitykey']);?></textarea>
|
106 |
</td>
|
107 |
</tr>
|
108 |
<?php
|
@@ -123,7 +123,7 @@
|
|
123 |
if(!pmpro_isLevelTrial($order->membership_level))
|
124 |
{
|
125 |
//subscription will start today with a 1 period trial
|
126 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
127 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
128 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
129 |
$order->TrialBillingCycles = 1;
|
@@ -135,7 +135,7 @@
|
|
135 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
136 |
{
|
137 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
138 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
139 |
$order->TrialBillingCycles++;
|
140 |
//add a billing cycle to make up for the trial, if applicable
|
141 |
if($order->TotalBillingCycles)
|
@@ -144,7 +144,7 @@
|
|
144 |
else
|
145 |
{
|
146 |
//add a period to the start date to account for the initial payment
|
147 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
148 |
}
|
149 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
150 |
return $this->subscribe($order);
|
@@ -167,7 +167,7 @@
|
|
167 |
if(!pmpro_isLevelTrial($order->membership_level))
|
168 |
{
|
169 |
//subscription will start today with a 1 period trial
|
170 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
171 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
172 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
173 |
$order->TrialBillingCycles = 1;
|
@@ -179,7 +179,7 @@
|
|
179 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
180 |
{
|
181 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
182 |
-
$order->ProfileStartDate = date_i18n("Y-m-d
|
183 |
$order->TrialBillingCycles++;
|
184 |
//add a billing cycle to make up for the trial, if applicable
|
185 |
if(!empty($order->TotalBillingCycles))
|
@@ -188,7 +188,7 @@
|
|
188 |
else
|
189 |
{
|
190 |
//add a period to the start date to account for the initial payment
|
191 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
192 |
}
|
193 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
194 |
if($this->subscribe($order))
|
@@ -572,7 +572,7 @@
|
|
572 |
else
|
573 |
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
574 |
//convert to a profile start date
|
575 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp")))
|
576 |
//filter the start date
|
577 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
578 |
//convert back to days
|
102 |
<label for="cybersource_securitykey"><?php _e('Transaction Security Key', 'paid-memberships-pro' );?>:</label>
|
103 |
</th>
|
104 |
<td>
|
105 |
+
<textarea id="cybersource_securitykey" name="cybersource_securitykey" autocomplete="off" rows="3" cols="50" class="large-text code pmpro-admin-secure-key"><?php echo esc_textarea($values['cybersource_securitykey']);?></textarea>
|
106 |
</td>
|
107 |
</tr>
|
108 |
<?php
|
123 |
if(!pmpro_isLevelTrial($order->membership_level))
|
124 |
{
|
125 |
//subscription will start today with a 1 period trial
|
126 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
127 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
128 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
129 |
$order->TrialBillingCycles = 1;
|
135 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
136 |
{
|
137 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
138 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
139 |
$order->TrialBillingCycles++;
|
140 |
//add a billing cycle to make up for the trial, if applicable
|
141 |
if($order->TotalBillingCycles)
|
144 |
else
|
145 |
{
|
146 |
//add a period to the start date to account for the initial payment
|
147 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
148 |
}
|
149 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
150 |
return $this->subscribe($order);
|
167 |
if(!pmpro_isLevelTrial($order->membership_level))
|
168 |
{
|
169 |
//subscription will start today with a 1 period trial
|
170 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
171 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
172 |
$order->TrialBillingFrequency = $order->BillingFrequency;
|
173 |
$order->TrialBillingCycles = 1;
|
179 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
180 |
{
|
181 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
182 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
183 |
$order->TrialBillingCycles++;
|
184 |
//add a billing cycle to make up for the trial, if applicable
|
185 |
if(!empty($order->TotalBillingCycles))
|
188 |
else
|
189 |
{
|
190 |
//add a period to the start date to account for the initial payment
|
191 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
192 |
}
|
193 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
194 |
if($this->subscribe($order))
|
572 |
else
|
573 |
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
574 |
//convert to a profile start date
|
575 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp")));
|
576 |
//filter the start date
|
577 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
578 |
//convert back to days
|
classes/gateways/class.pmprogateway_payflowpro.php
CHANGED
@@ -163,7 +163,7 @@
|
|
163 |
if($authorization_id)
|
164 |
{
|
165 |
$this->void($order, $authorization_id);
|
166 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
167 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
168 |
return $this->subscribe($order);
|
169 |
}
|
@@ -182,7 +182,7 @@
|
|
182 |
//set up recurring billing
|
183 |
if(pmpro_isLevelRecurring($order->membership_level))
|
184 |
{
|
185 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
186 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
187 |
if($this->subscribe($order))
|
188 |
{
|
@@ -320,7 +320,22 @@
|
|
320 |
|
321 |
//paypal profile stuff
|
322 |
$nvpStr = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
323 |
$nvpStr .="&AMT=" . $amount . "&TAXAMT=" . $amount_tax . "&CURRENCY=" . $pmpro_currency;
|
|
|
324 |
/* PayFlow Pro doesn't use IPN so this is a little confusing */
|
325 |
// $nvpStr .= "&NOTIFYURL=" . urlencode( add_query_arg( 'action', 'ipnhandler', admin_url('admin-ajax.php') ) );
|
326 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
@@ -390,7 +405,19 @@
|
|
390 |
|
391 |
//paypal profile stuff
|
392 |
$nvpStr = "&ACTION=A";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
393 |
$nvpStr .="&AMT=" . $amount . "&TAXAMT=" . $amount_tax . "&CURRENCY=" . $pmpro_currency;
|
|
|
394 |
/* PayFlow Pro doesn't use IPN so this is a little confusing */
|
395 |
// $nvpStr .= "&NOTIFYURL=" . urlencode( add_query_arg( 'action', 'ipnhandler', admin_url('admin-ajax.php') ) );
|
396 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
@@ -426,7 +453,7 @@
|
|
426 |
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
427 |
|
428 |
//convert to a profile start date
|
429 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp")))
|
430 |
|
431 |
//filter the start date
|
432 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
@@ -449,7 +476,7 @@
|
|
449 |
}
|
450 |
|
451 |
//convert back into a date
|
452 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp")))
|
453 |
|
454 |
//start date
|
455 |
$nvpStr .= "&START=" . date_i18n("mdY", strtotime($order->ProfileStartDate));
|
@@ -497,6 +524,17 @@
|
|
497 |
|
498 |
//paypal profile stuff
|
499 |
$nvpStr = "&ORIGPROFILEID=" . $order->subscription_transaction_id . "&ACTION=M";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
500 |
/* PayFlow Pro doesn't use IPN so this is a little confusing */
|
501 |
// $nvpStr .= "&NOTIFYURL=" . urlencode( add_query_arg( 'action', 'ipnhandler', admin_url('admin-ajax.php') ) );
|
502 |
|
163 |
if($authorization_id)
|
164 |
{
|
165 |
$this->void($order, $authorization_id);
|
166 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
167 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
168 |
return $this->subscribe($order);
|
169 |
}
|
182 |
//set up recurring billing
|
183 |
if(pmpro_isLevelRecurring($order->membership_level))
|
184 |
{
|
185 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
186 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
187 |
if($this->subscribe($order))
|
188 |
{
|
320 |
|
321 |
//paypal profile stuff
|
322 |
$nvpStr = "";
|
323 |
+
|
324 |
+
// Only add CARDONFILE for initial charge if it's recurring.
|
325 |
+
if ( pmpro_isLevelRecurring( $order->membership_level ) ) {
|
326 |
+
/*
|
327 |
+
* Card on File is now required.
|
328 |
+
*
|
329 |
+
* CITR: The customer just performed an action to make the transaction.
|
330 |
+
* MITR: The customer passively approved during CITR to make this subsequent (recurring) transaction.
|
331 |
+
*
|
332 |
+
* @link https://developer.paypal.com/docs/payflow/integration-guide/card-on-file/
|
333 |
+
*/
|
334 |
+
$nvpStr .= "&CARDONFILE=CITR";
|
335 |
+
}
|
336 |
+
|
337 |
$nvpStr .="&AMT=" . $amount . "&TAXAMT=" . $amount_tax . "&CURRENCY=" . $pmpro_currency;
|
338 |
+
|
339 |
/* PayFlow Pro doesn't use IPN so this is a little confusing */
|
340 |
// $nvpStr .= "&NOTIFYURL=" . urlencode( add_query_arg( 'action', 'ipnhandler', admin_url('admin-ajax.php') ) );
|
341 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
405 |
|
406 |
//paypal profile stuff
|
407 |
$nvpStr = "&ACTION=A";
|
408 |
+
|
409 |
+
/*
|
410 |
+
* Card on File is now required.
|
411 |
+
*
|
412 |
+
* CITR: The customer just performed an action to make the transaction.
|
413 |
+
* MITR: The customer passively approved during CITR to make this subsequent (recurring) transaction.
|
414 |
+
*
|
415 |
+
* @link https://developer.paypal.com/docs/payflow/integration-guide/card-on-file/
|
416 |
+
*/
|
417 |
+
$nvpStr .="&CARDONFILE=CITR";
|
418 |
+
|
419 |
$nvpStr .="&AMT=" . $amount . "&TAXAMT=" . $amount_tax . "&CURRENCY=" . $pmpro_currency;
|
420 |
+
|
421 |
/* PayFlow Pro doesn't use IPN so this is a little confusing */
|
422 |
// $nvpStr .= "&NOTIFYURL=" . urlencode( add_query_arg( 'action', 'ipnhandler', admin_url('admin-ajax.php') ) );
|
423 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
453 |
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
454 |
|
455 |
//convert to a profile start date
|
456 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp")));
|
457 |
|
458 |
//filter the start date
|
459 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
476 |
}
|
477 |
|
478 |
//convert back into a date
|
479 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp")));
|
480 |
|
481 |
//start date
|
482 |
$nvpStr .= "&START=" . date_i18n("mdY", strtotime($order->ProfileStartDate));
|
524 |
|
525 |
//paypal profile stuff
|
526 |
$nvpStr = "&ORIGPROFILEID=" . $order->subscription_transaction_id . "&ACTION=M";
|
527 |
+
|
528 |
+
/*
|
529 |
+
* Card on File is now required.
|
530 |
+
*
|
531 |
+
* CITR: The customer just performed an action to make the transaction.
|
532 |
+
* MITR: The customer passively approved during CIT to make this subsequent (recurring) transaction.
|
533 |
+
*
|
534 |
+
* @link https://developer.paypal.com/docs/payflow/integration-guide/card-on-file/
|
535 |
+
*/
|
536 |
+
$nvpStr .= "&CARDONFILE=CITR";
|
537 |
+
|
538 |
/* PayFlow Pro doesn't use IPN so this is a little confusing */
|
539 |
// $nvpStr .= "&NOTIFYURL=" . urlencode( add_query_arg( 'action', 'ipnhandler', admin_url('admin-ajax.php') ) );
|
540 |
|
classes/gateways/class.pmprogateway_paypal.php
CHANGED
@@ -169,7 +169,7 @@
|
|
169 |
<label for="apipassword"><?php _e('API Password', 'paid-memberships-pro' );?>:</label>
|
170 |
</th>
|
171 |
<td>
|
172 |
-
<input type="text" id="apipassword" name="apipassword" value="<?php echo esc_attr($values['apipassword'])?>" class="regular-text code" />
|
173 |
</td>
|
174 |
</tr>
|
175 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
@@ -305,7 +305,7 @@
|
|
305 |
if($authorization_id)
|
306 |
{
|
307 |
$this->void($order, $authorization_id);
|
308 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
309 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
310 |
return $this->subscribe($order);
|
311 |
}
|
@@ -324,7 +324,7 @@
|
|
324 |
//set up recurring billing
|
325 |
if(pmpro_isLevelRecurring($order->membership_level))
|
326 |
{
|
327 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
328 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
329 |
if($this->subscribe($order))
|
330 |
{
|
@@ -601,8 +601,16 @@
|
|
601 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&COUNTRYCODE=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&SHIPTOPHONENUM=" . $order->billing->phone;
|
602 |
}
|
603 |
|
|
|
|
|
|
|
|
|
|
|
604 |
//for debugging let's add this to the class object
|
605 |
$this->nvpStr = $nvpStr;
|
|
|
|
|
|
|
606 |
|
607 |
$this->httpParsedResponseAr = $this->PPHttpPost('CreateRecurringPaymentsProfile', $nvpStr);
|
608 |
|
@@ -625,7 +633,7 @@
|
|
625 |
{
|
626 |
//paypal profile stuff
|
627 |
$nvpStr = "";
|
628 |
-
$nvpStr .= "&PROFILEID=" . $order->subscription_transaction_id;
|
629 |
|
630 |
//credit card fields
|
631 |
if($order->cardtype == "American Express")
|
@@ -635,26 +643,26 @@
|
|
635 |
|
636 |
//credit card fields
|
637 |
if($cardtype)
|
638 |
-
$nvpStr .= "&CREDITCARDTYPE=" . $cardtype . "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->ExpirationDate . "&CVV2=" . $order->CVV2;
|
639 |
|
640 |
//Maestro/Solo card fields. (Who uses these?) :)
|
641 |
if($order->StartDate)
|
642 |
-
$nvpStr .= "&STARTDATE=" . $order->StartDate . "&ISSUENUMBER=" . $order->IssueNumber;
|
643 |
|
644 |
// Name and email info
|
645 |
if ( $order->FirstName && $order->LastName && $order->Email ) {
|
646 |
-
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName;
|
647 |
}
|
648 |
|
649 |
//billing address, etc
|
650 |
if($order->Address1)
|
651 |
{
|
652 |
-
$nvpStr .= "&STREET=" . $order->Address1;
|
653 |
|
654 |
if($order->Address2)
|
655 |
-
$nvpStr .= "&STREET2=" . $order->Address2;
|
656 |
|
657 |
-
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&COUNTRYCODE=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&SHIPTOPHONENUM=" . $order->billing->phone;
|
658 |
}
|
659 |
|
660 |
$this->httpParsedResponseAr = $this->PPHttpPost('UpdateRecurringPaymentsProfile', $nvpStr);
|
169 |
<label for="apipassword"><?php _e('API Password', 'paid-memberships-pro' );?>:</label>
|
170 |
</th>
|
171 |
<td>
|
172 |
+
<input type="text" id="apipassword" name="apipassword" value="<?php echo esc_attr($values['apipassword'])?>" autocomplete="off" class="regular-text code pmpro-admin-secure-key" />
|
173 |
</td>
|
174 |
</tr>
|
175 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
305 |
if($authorization_id)
|
306 |
{
|
307 |
$this->void($order, $authorization_id);
|
308 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
309 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
310 |
return $this->subscribe($order);
|
311 |
}
|
324 |
//set up recurring billing
|
325 |
if(pmpro_isLevelRecurring($order->membership_level))
|
326 |
{
|
327 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
328 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
329 |
if($this->subscribe($order))
|
330 |
{
|
601 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&COUNTRYCODE=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&SHIPTOPHONENUM=" . $order->billing->phone;
|
602 |
}
|
603 |
|
604 |
+
// Set MAXFAILEDPAYMENTS so subscriptions are cancelled after 1 failed payment.
|
605 |
+
$nvpStr .= "&MAXFAILEDPAYMENTS=1";
|
606 |
+
|
607 |
+
$nvpStr = apply_filters("pmpro_create_recurring_payments_profile_nvpstr", $nvpStr, $order);
|
608 |
+
|
609 |
//for debugging let's add this to the class object
|
610 |
$this->nvpStr = $nvpStr;
|
611 |
+
|
612 |
+
///echo str_replace("&", "&<br />", $nvpStr);
|
613 |
+
///exit;
|
614 |
|
615 |
$this->httpParsedResponseAr = $this->PPHttpPost('CreateRecurringPaymentsProfile', $nvpStr);
|
616 |
|
633 |
{
|
634 |
//paypal profile stuff
|
635 |
$nvpStr = "";
|
636 |
+
$nvpStr .= "&PROFILEID=" . urlencode( $order->subscription_transaction_id );
|
637 |
|
638 |
//credit card fields
|
639 |
if($order->cardtype == "American Express")
|
643 |
|
644 |
//credit card fields
|
645 |
if($cardtype)
|
646 |
+
$nvpStr .= "&CREDITCARDTYPE=" . urlencode( $cardtype ) . "&ACCT=" . urlencode( $order->accountnumber ) . "&EXPDATE=" . urlencode( $order->ExpirationDate ) . "&CVV2=" . urlencode( $order->CVV2 );
|
647 |
|
648 |
//Maestro/Solo card fields. (Who uses these?) :)
|
649 |
if($order->StartDate)
|
650 |
+
$nvpStr .= "&STARTDATE=" . urlencode( $order->StartDate ) . "&ISSUENUMBER=" . urlencode( $order->IssueNumber );
|
651 |
|
652 |
// Name and email info
|
653 |
if ( $order->FirstName && $order->LastName && $order->Email ) {
|
654 |
+
$nvpStr .= "&EMAIL=" . urlencode( $order->Email ) . "&FIRSTNAME=" . urlencode( $order->FirstName ) . "&LASTNAME=" . urlencode( $order->LastName );
|
655 |
}
|
656 |
|
657 |
//billing address, etc
|
658 |
if($order->Address1)
|
659 |
{
|
660 |
+
$nvpStr .= "&STREET=" . urlencode( $order->Address1 );
|
661 |
|
662 |
if($order->Address2)
|
663 |
+
$nvpStr .= "&STREET2=" . urlencode( $order->Address2 );
|
664 |
|
665 |
+
$nvpStr .= "&CITY=" . urlencode( $order->billing->city ) . "&STATE=" . urlencode( $order->billing->state ) . "&COUNTRYCODE=" . urlencode( $order->billing->country ) . "&ZIP=" . urlencode( $order->billing->zip ) . "&SHIPTOPHONENUM=" . urlencode( $order->billing->phone );
|
666 |
}
|
667 |
|
668 |
$this->httpParsedResponseAr = $this->PPHttpPost('UpdateRecurringPaymentsProfile', $nvpStr);
|
classes/gateways/class.pmprogateway_paypalexpress.php
CHANGED
@@ -7,6 +7,16 @@
|
|
7 |
|
8 |
class PMProGateway_paypalexpress extends PMProGateway
|
9 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
function __construct($gateway = NULL)
|
11 |
{
|
12 |
$this->gateway = $gateway;
|
@@ -178,7 +188,7 @@
|
|
178 |
<label for="apipassword"><?php _e('API Password', 'paid-memberships-pro' );?>:</label>
|
179 |
</th>
|
180 |
<td>
|
181 |
-
<input type="text" id="apipassword" name="apipassword" value="<?php echo esc_attr($values['apipassword'])?>" class="regular-text code" />
|
182 |
</td>
|
183 |
</tr>
|
184 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
@@ -273,7 +283,7 @@
|
|
273 |
else
|
274 |
$username = "";
|
275 |
if(isset($_REQUEST['password']))
|
276 |
-
$password =
|
277 |
else
|
278 |
$password = "";
|
279 |
if(isset($_REQUEST['bemail']))
|
@@ -322,22 +332,28 @@
|
|
322 |
|
323 |
$morder = new MemberOrder();
|
324 |
$morder->getMemberOrderByPayPalToken(sanitize_text_field($_REQUEST['token']));
|
325 |
-
|
326 |
-
if($morder->
|
327 |
-
|
328 |
-
if($morder->
|
329 |
{
|
330 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
331 |
}
|
332 |
else
|
333 |
{
|
334 |
-
$pmpro_msg =
|
335 |
$pmpro_msgt = "pmpro_error";
|
336 |
}
|
337 |
-
}
|
338 |
-
|
339 |
-
{
|
340 |
-
$pmpro_msg = __("The PayPal Token was lost.", 'paid-memberships-pro' );
|
341 |
$pmpro_msgt = "pmpro_error";
|
342 |
}
|
343 |
}
|
@@ -358,7 +374,7 @@
|
|
358 |
$morder->discount_code = $discount_code;
|
359 |
$morder->InitialPayment = pmpro_round_price( $pmpro_level->initial_payment );
|
360 |
$morder->PaymentAmount = pmpro_round_price( $pmpro_level->billing_amount );
|
361 |
-
$morder->ProfileStartDate = date_i18n("Y-m-d
|
362 |
$morder->BillingPeriod = $pmpro_level->cycle_period;
|
363 |
$morder->BillingFrequency = $pmpro_level->cycle_number;
|
364 |
$morder->Email = $bemail;
|
@@ -415,9 +431,15 @@
|
|
415 |
if(!$current_user->ID)
|
416 |
{
|
417 |
//reload the user fields
|
418 |
-
|
419 |
-
|
420 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
|
422 |
//unset the user fields in session
|
423 |
unset($_SESSION['pmpro_signup_username']);
|
@@ -437,8 +459,10 @@
|
|
437 |
{
|
438 |
$order->payment_type = "PayPal Express";
|
439 |
$order->cardtype = "";
|
440 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod))
|
441 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
|
|
|
|
442 |
|
443 |
return $this->setExpressCheckout($order);
|
444 |
}
|
@@ -452,8 +476,10 @@
|
|
452 |
{
|
453 |
if(pmpro_isLevelRecurring($order->membership_level))
|
454 |
{
|
455 |
-
$order->ProfileStartDate = date_i18n("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")))
|
456 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
|
|
|
|
457 |
return $this->subscribe($order);
|
458 |
}
|
459 |
else
|
@@ -572,6 +598,15 @@
|
|
572 |
//update order
|
573 |
$order->saveOrder();
|
574 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
575 |
//redirect to paypal
|
576 |
$paypal_url = "https://www.paypal.com/webscr?cmd=_express-checkout&useraction=commit&token=" . $this->httpParsedResponseAr['TOKEN'];
|
577 |
$environment = pmpro_getOption("gateway_environment");
|
@@ -585,7 +620,6 @@
|
|
585 |
|
586 |
//exit('SetExpressCheckout Completed Successfully: '.print_r($this->httpParsedResponseAr, true));
|
587 |
} else {
|
588 |
-
$order->status = "error";
|
589 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
590 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
591 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
@@ -619,7 +653,6 @@
|
|
619 |
|
620 |
return true;
|
621 |
} else {
|
622 |
-
$order->status = "error";
|
623 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
624 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
625 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
@@ -673,7 +706,6 @@
|
|
673 |
|
674 |
return true;
|
675 |
} else {
|
676 |
-
$order->status = "error";
|
677 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
678 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
679 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
@@ -684,7 +716,7 @@
|
|
684 |
|
685 |
function subscribe(&$order)
|
686 |
{
|
687 |
-
global $pmpro_currency;
|
688 |
|
689 |
if(empty($order->code))
|
690 |
$order->code = $order->getRandomCode();
|
@@ -729,8 +761,12 @@
|
|
729 |
if(!empty($order->TrialBillingCycles))
|
730 |
$nvpStr .= "&TRIALTOTALBILLINGCYCLES=" . $order->TrialBillingCycles;
|
731 |
|
|
|
|
|
|
|
732 |
$nvpStr = apply_filters("pmpro_create_recurring_payments_profile_nvpstr", $nvpStr, $order);
|
733 |
|
|
|
734 |
$this->nvpStr = $nvpStr;
|
735 |
|
736 |
///echo str_replace("&", "&<br />", $nvpStr);
|
@@ -739,16 +775,44 @@
|
|
739 |
$this->httpParsedResponseAr = $this->PPHttpPost('CreateRecurringPaymentsProfile', $nvpStr);
|
740 |
|
741 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
742 |
-
|
743 |
-
|
744 |
-
|
|
|
|
|
|
|
745 |
|
746 |
-
|
747 |
-
|
|
|
748 |
|
749 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
750 |
} else {
|
751 |
-
|
|
|
|
|
752 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
753 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
754 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
@@ -786,7 +850,6 @@
|
|
786 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
787 |
return true;
|
788 |
} else {
|
789 |
-
$order->status = "error";
|
790 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
791 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']) . ". " . __("Please contact the site owner or cancel your subscription from within PayPal to make sure you are not charged going forward.", 'paid-memberships-pro' );
|
792 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
@@ -814,7 +877,6 @@
|
|
814 |
}
|
815 |
else
|
816 |
{
|
817 |
-
$order->status = "error";
|
818 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
819 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
820 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
@@ -842,60 +904,76 @@
|
|
842 |
return false;
|
843 |
|
844 |
if( $order->payment_transaction_id == $order->subscription_transaction_id ){
|
845 |
-
|
846 |
-
$
|
847 |
-
|
848 |
-
$nvpStr .= "&STARTDATE=" . urlencode( gmdate( DATE_W3C, $order->getTimestamp() - DAY_IN_SECONDS ) . 'Z' );
|
849 |
-
// filter results by a specific transaction id.
|
850 |
-
$nvpStr .= "&TRANSACTIONID=" . urlencode($order->subscription_transaction_id);
|
851 |
-
|
852 |
-
$this->httpParsedResponseAr = $this->PPHttpPost('TransactionSearch', $nvpStr);
|
853 |
-
|
854 |
-
if( ! in_array( strtoupper( $this->httpParsedResponseAr["ACK"] ), [ 'SUCCESS', 'SUCCESSWITHWARNING' ] ) ){
|
855 |
-
// since we are using TRANSACTIONID=I-... which is NOT a transaction id,
|
856 |
-
// paypal is returning an error. but the results are actually filtered by that transaction id, usually.
|
857 |
-
|
858 |
-
// let's double check it.
|
859 |
-
if( ! isset( $this->httpParsedResponseAr['L_TRANSACTIONID0'] ) ){
|
860 |
-
// really no results? it's a real error.
|
861 |
-
return false;
|
862 |
-
}
|
863 |
}
|
864 |
|
865 |
-
$
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
871 |
|
872 |
-
|
873 |
-
if( "I-" === substr( $this->httpParsedResponseAr["L_TRANSACTIONID$i"], 0 ,2 ) ){
|
874 |
-
if( $order->subscription_transaction_id != $this->httpParsedResponseAr["L_TRANSACTIONID$i"] ){
|
875 |
-
// if we got a result from another I- subscription transaction id,
|
876 |
-
// then something changed into paypal responses.
|
877 |
-
// var_dump( $this->httpParsedResponseAr, $this->httpParsedResponseAr["L_TRANSACTIONID$i"] );
|
878 |
-
throw new Exception();
|
879 |
-
}
|
880 |
|
881 |
-
|
882 |
-
|
|
|
883 |
|
884 |
-
|
|
|
|
|
|
|
885 |
}
|
|
|
886 |
|
887 |
-
|
888 |
-
|
889 |
-
|
|
|
|
|
890 |
}
|
891 |
|
892 |
-
//
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
898 |
}
|
|
|
|
|
|
|
|
|
|
|
899 |
}
|
900 |
|
901 |
function getTransactionDetails($payment_transaction_id)
|
@@ -956,13 +1034,50 @@
|
|
956 |
|
957 |
/**
|
958 |
* PAYPAL Function
|
959 |
-
* Send HTTP POST Request
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
960 |
*
|
961 |
* @param string The API method name
|
962 |
* @param string The POST Message fields in &name=value pair format
|
963 |
-
* @return array Parsed HTTP Response body
|
964 |
*/
|
965 |
-
function
|
966 |
global $gateway_environment;
|
967 |
$environment = $gateway_environment;
|
968 |
|
@@ -984,24 +1099,80 @@
|
|
984 |
'timeout' => 60,
|
985 |
'sslverify' => FALSE,
|
986 |
'httpversion' => '1.1',
|
987 |
-
'body' => $nvpreq
|
|
|
|
|
|
|
|
|
988 |
)
|
989 |
);
|
990 |
|
991 |
if ( is_wp_error( $response ) ) {
|
992 |
-
|
993 |
-
die( "methodName_ failed: $error_message" );
|
994 |
-
} else {
|
995 |
-
//extract the response details
|
996 |
-
$httpParsedResponseAr = array();
|
997 |
-
parse_str(wp_remote_retrieve_body($response), $httpParsedResponseAr);
|
998 |
-
|
999 |
-
//check for valid response
|
1000 |
-
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
|
1001 |
-
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
|
1002 |
-
}
|
1003 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1004 |
|
1005 |
return $httpParsedResponseAr;
|
1006 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1007 |
}
|
7 |
|
8 |
class PMProGateway_paypalexpress extends PMProGateway
|
9 |
{
|
10 |
+
/** @var int Maximum number of request retries */
|
11 |
+
protected static $maxNetworkRetries = 5;
|
12 |
+
|
13 |
+
/** @var float Maximum delay between retries, in seconds */
|
14 |
+
protected static $maxNetworkRetryDelay = 2.0;
|
15 |
+
|
16 |
+
/** @var float Initial delay between retries, in seconds */
|
17 |
+
protected static $initialNetworkRetryDelay = 0.5;
|
18 |
+
|
19 |
+
|
20 |
function __construct($gateway = NULL)
|
21 |
{
|
22 |
$this->gateway = $gateway;
|
188 |
<label for="apipassword"><?php _e('API Password', 'paid-memberships-pro' );?>:</label>
|
189 |
</th>
|
190 |
<td>
|
191 |
+
<input type="text" id="apipassword" name="apipassword" value="<?php echo esc_attr($values['apipassword'])?>" autocomplete="off" class="regular-text code pmpro-admin-secure-key" />
|
192 |
</td>
|
193 |
</tr>
|
194 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
283 |
else
|
284 |
$username = "";
|
285 |
if(isset($_REQUEST['password']))
|
286 |
+
$password = $_REQUEST['password'];
|
287 |
else
|
288 |
$password = "";
|
289 |
if(isset($_REQUEST['bemail']))
|
332 |
|
333 |
$morder = new MemberOrder();
|
334 |
$morder->getMemberOrderByPayPalToken(sanitize_text_field($_REQUEST['token']));
|
335 |
+
|
336 |
+
if( $morder->status === 'token' ){
|
337 |
+
$morder->Token = $morder->paypal_token; $pmpro_paypal_token = $morder->paypal_token;
|
338 |
+
if($morder->Token)
|
339 |
{
|
340 |
+
if($morder->Gateway->getExpressCheckoutDetails($morder))
|
341 |
+
{
|
342 |
+
$pmpro_review = true;
|
343 |
+
}
|
344 |
+
else
|
345 |
+
{
|
346 |
+
$pmpro_msg = $morder->error;
|
347 |
+
$pmpro_msgt = "pmpro_error";
|
348 |
+
}
|
349 |
}
|
350 |
else
|
351 |
{
|
352 |
+
$pmpro_msg = __("The PayPal Token was lost.", 'paid-memberships-pro' );
|
353 |
$pmpro_msgt = "pmpro_error";
|
354 |
}
|
355 |
+
}else{
|
356 |
+
$pmpro_msg = __("Checkout was already processed.", 'paid-memberships-pro' );
|
|
|
|
|
357 |
$pmpro_msgt = "pmpro_error";
|
358 |
}
|
359 |
}
|
374 |
$morder->discount_code = $discount_code;
|
375 |
$morder->InitialPayment = pmpro_round_price( $pmpro_level->initial_payment );
|
376 |
$morder->PaymentAmount = pmpro_round_price( $pmpro_level->billing_amount );
|
377 |
+
$morder->ProfileStartDate = date_i18n("Y-m-d\TH:i:s");
|
378 |
$morder->BillingPeriod = $pmpro_level->cycle_period;
|
379 |
$morder->BillingFrequency = $pmpro_level->cycle_number;
|
380 |
$morder->Email = $bemail;
|
431 |
if(!$current_user->ID)
|
432 |
{
|
433 |
//reload the user fields
|
434 |
+
if( ! empty( $_SESSION['pmpro_signup_username'] ) ){
|
435 |
+
$new_user_array['user_login'] = $_SESSION['pmpro_signup_username'];
|
436 |
+
}
|
437 |
+
if( ! empty( $_SESSION['pmpro_signup_password'] ) ){
|
438 |
+
$new_user_array['user_pass'] = $_SESSION['pmpro_signup_password'];
|
439 |
+
}
|
440 |
+
if( ! empty( $_SESSION['pmpro_signup_email'] ) ){
|
441 |
+
$new_user_array['user_email'] = $_SESSION['pmpro_signup_email'];
|
442 |
+
}
|
443 |
|
444 |
//unset the user fields in session
|
445 |
unset($_SESSION['pmpro_signup_username']);
|
459 |
{
|
460 |
$order->payment_type = "PayPal Express";
|
461 |
$order->cardtype = "";
|
462 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod));
|
463 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
464 |
+
// Convert to UTC for PayPal...
|
465 |
+
$order->ProfileStartDate = get_gmt_from_date( $order->ProfileStartDate, 'Y-m-d\TH:i:s\Z' );
|
466 |
|
467 |
return $this->setExpressCheckout($order);
|
468 |
}
|
476 |
{
|
477 |
if(pmpro_isLevelRecurring($order->membership_level))
|
478 |
{
|
479 |
+
$order->ProfileStartDate = date_i18n("Y-m-d\TH:i:s", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp")));
|
480 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
481 |
+
// Convert to UTC for PayPal...
|
482 |
+
$order->ProfileStartDate = get_gmt_from_date( $order->ProfileStartDate, 'Y-m-d\TH:i:s\Z' );
|
483 |
return $this->subscribe($order);
|
484 |
}
|
485 |
else
|
598 |
//update order
|
599 |
$order->saveOrder();
|
600 |
|
601 |
+
/**
|
602 |
+
* Allow performing actions just before sending the user to the gateway to complete the payment.
|
603 |
+
*
|
604 |
+
* @since 2.6.5
|
605 |
+
*
|
606 |
+
* @param MemberOrder $order The new order with status = token.
|
607 |
+
*/
|
608 |
+
do_action( 'pmpro_before_commit_express_checkout', $order );
|
609 |
+
|
610 |
//redirect to paypal
|
611 |
$paypal_url = "https://www.paypal.com/webscr?cmd=_express-checkout&useraction=commit&token=" . $this->httpParsedResponseAr['TOKEN'];
|
612 |
$environment = pmpro_getOption("gateway_environment");
|
620 |
|
621 |
//exit('SetExpressCheckout Completed Successfully: '.print_r($this->httpParsedResponseAr, true));
|
622 |
} else {
|
|
|
623 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
624 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
625 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
653 |
|
654 |
return true;
|
655 |
} else {
|
|
|
656 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
657 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
658 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
706 |
|
707 |
return true;
|
708 |
} else {
|
|
|
709 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
710 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
711 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
716 |
|
717 |
function subscribe(&$order)
|
718 |
{
|
719 |
+
global $pmpro_currency, $pmpro_review;
|
720 |
|
721 |
if(empty($order->code))
|
722 |
$order->code = $order->getRandomCode();
|
761 |
if(!empty($order->TrialBillingCycles))
|
762 |
$nvpStr .= "&TRIALTOTALBILLINGCYCLES=" . $order->TrialBillingCycles;
|
763 |
|
764 |
+
// Set MAXFAILEDPAYMENTS so subscriptions are cancelled after 1 failed payment.
|
765 |
+
$nvpStr .= "&MAXFAILEDPAYMENTS=1";
|
766 |
+
|
767 |
$nvpStr = apply_filters("pmpro_create_recurring_payments_profile_nvpstr", $nvpStr, $order);
|
768 |
|
769 |
+
//for debugging let's add this to the class object
|
770 |
$this->nvpStr = $nvpStr;
|
771 |
|
772 |
///echo str_replace("&", "&<br />", $nvpStr);
|
775 |
$this->httpParsedResponseAr = $this->PPHttpPost('CreateRecurringPaymentsProfile', $nvpStr);
|
776 |
|
777 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
778 |
+
// PayPal docs says that PROFILESTATUS can be:
|
779 |
+
// 1. ActiveProfile — The recurring payment profile has been successfully created and activated for scheduled payments according the billing instructions from the recurring payments profile.
|
780 |
+
// 2. PendingProfile — The system is in the process of creating the recurring payment profile. Please check your IPN messages for an update.
|
781 |
+
// Also, we have seen that PROFILESTATUS can be missing. That case would be an error.
|
782 |
+
if(isset($this->httpParsedResponseAr["PROFILESTATUS"]) && in_array($this->httpParsedResponseAr["PROFILESTATUS"], array("ActiveProfile", "PendingProfile"))) {
|
783 |
+
$order->status = "success";
|
784 |
|
785 |
+
// this is wrong, but we don't know the real transaction id at this point
|
786 |
+
$order->payment_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
|
787 |
+
$order->subscription_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
|
788 |
|
789 |
+
//update order
|
790 |
+
$order->saveOrder();
|
791 |
+
|
792 |
+
return true;
|
793 |
+
} else {
|
794 |
+
// stop processing the review request on checkout page
|
795 |
+
$pmpro_review = false;
|
796 |
+
|
797 |
+
$order->status = "error";
|
798 |
+
|
799 |
+
// this is wrong, but we don't know the real transaction id at this point
|
800 |
+
$order->payment_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
|
801 |
+
$order->subscription_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
|
802 |
+
|
803 |
+
$order->errorcode = '';
|
804 |
+
$order->error = __( 'Something went wrong creating plan with PayPal; missing PROFILESTATUS.', 'paid-memberships-pro' );
|
805 |
+
$order->shorterror = __( 'Error creating plan with PayPal.', 'paid-memberships-pro' );
|
806 |
+
|
807 |
+
//update order
|
808 |
+
$order->saveOrder();
|
809 |
+
|
810 |
+
return false;
|
811 |
+
}
|
812 |
} else {
|
813 |
+
// stop processing the review request on checkout page
|
814 |
+
$pmpro_review = false;
|
815 |
+
|
816 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
817 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
818 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
850 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
851 |
return true;
|
852 |
} else {
|
|
|
853 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
854 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']) . ". " . __("Please contact the site owner or cancel your subscription from within PayPal to make sure you are not charged going forward.", 'paid-memberships-pro' );
|
855 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
877 |
}
|
878 |
else
|
879 |
{
|
|
|
880 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
881 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
882 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
904 |
return false;
|
905 |
|
906 |
if( $order->payment_transaction_id == $order->subscription_transaction_id ){
|
907 |
+
$payment_transaction_id = $this->getRealPaymentTransactionId( $order );
|
908 |
+
if( ! $payment_transaction_id ){
|
909 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
910 |
}
|
911 |
|
912 |
+
return $this->getTransactionDetails( $payment_transaction_id );
|
913 |
+
}else{
|
914 |
+
/** Recurring payment **/
|
915 |
+
return $this->getTransactionDetails( $order->payment_transaction_id );
|
916 |
+
}
|
917 |
+
}
|
918 |
+
|
919 |
+
/**
|
920 |
+
* Try to recover the real payment_transaction_id when payment_transaction_id === subscription_transaction_id === I-xxxxxxxx.
|
921 |
+
*
|
922 |
+
* @since 1.8.5
|
923 |
+
*/
|
924 |
+
function getRealPaymentTransactionId(&$order)
|
925 |
+
{
|
926 |
+
/** Initial payment **/
|
927 |
+
$nvpStr = "";
|
928 |
+
// STARTDATE is Required, even if useless here. Start from 24h before the order timestamp, to avoid timezone related issues.
|
929 |
+
$nvpStr .= "&STARTDATE=" . urlencode( gmdate( DATE_W3C, $order->getTimestamp() - DAY_IN_SECONDS ) . 'Z' );
|
930 |
+
// filter results by a specific transaction id.
|
931 |
+
$nvpStr .= "&TRANSACTIONID=" . urlencode($order->subscription_transaction_id);
|
932 |
|
933 |
+
$this->httpParsedResponseAr = $this->PPHttpPost('TransactionSearch', $nvpStr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
934 |
|
935 |
+
if( ! in_array( strtoupper( $this->httpParsedResponseAr["ACK"] ), [ 'SUCCESS', 'SUCCESSWITHWARNING' ] ) ){
|
936 |
+
// since we are using TRANSACTIONID=I-... which is NOT a transaction id,
|
937 |
+
// paypal is returning an error. but the results are actually filtered by that transaction id, usually.
|
938 |
|
939 |
+
// let's double check it.
|
940 |
+
if( ! isset( $this->httpParsedResponseAr['L_TRANSACTIONID0'] ) ){
|
941 |
+
// really no results? it's a real error.
|
942 |
+
return false;
|
943 |
}
|
944 |
+
}
|
945 |
|
946 |
+
$transaction_ids = [];
|
947 |
+
for( $i = 0; $i < PHP_INT_MAX; $i++ ){
|
948 |
+
// loop until we have results
|
949 |
+
if( ! isset( $this->httpParsedResponseAr["L_TRANSACTIONID$i"] ) ){
|
950 |
+
break;
|
951 |
}
|
952 |
|
953 |
+
// ignore I-... results
|
954 |
+
if( "I-" === substr( $this->httpParsedResponseAr["L_TRANSACTIONID$i"], 0 ,2 ) ){
|
955 |
+
if( $order->subscription_transaction_id != $this->httpParsedResponseAr["L_TRANSACTIONID$i"] ){
|
956 |
+
// if we got a result from another I- subscription transaction id,
|
957 |
+
// then something changed into paypal responses.
|
958 |
+
// var_dump( $this->httpParsedResponseAr, $this->httpParsedResponseAr["L_TRANSACTIONID$i"] );
|
959 |
+
throw new Exception();
|
960 |
+
}
|
961 |
+
|
962 |
+
continue;
|
963 |
+
}
|
964 |
+
|
965 |
+
$transaction_ids[] = $this->httpParsedResponseAr["L_TRANSACTIONID$i"];
|
966 |
+
}
|
967 |
+
|
968 |
+
// no payment_transaction_ids in results
|
969 |
+
if( empty( $transaction_ids ) ){
|
970 |
+
return false;
|
971 |
}
|
972 |
+
|
973 |
+
// found the payment transaction id, it's the last one (the oldest)
|
974 |
+
$payment_transaction_id = end( $transaction_ids );
|
975 |
+
|
976 |
+
return $payment_transaction_id;
|
977 |
}
|
978 |
|
979 |
function getTransactionDetails($payment_transaction_id)
|
1034 |
|
1035 |
/**
|
1036 |
* PAYPAL Function
|
1037 |
+
* Send HTTP POST Request with retries
|
1038 |
+
*
|
1039 |
+
* @param string The API method name
|
1040 |
+
* @param string The POST Message fields in &name=value pair format
|
1041 |
+
*
|
1042 |
+
* @return array Parsed HTTP Response body
|
1043 |
+
*/
|
1044 |
+
function PPHttpPost( $methodName_, $nvpStr_ ) {
|
1045 |
+
// Create a UUID for this request, to enable idempotency which is supported
|
1046 |
+
// by PayPal Express even if it's legacy (thus it's not reported in the docs)
|
1047 |
+
// https://developer.paypal.com/docs/business/develop/idempotency/
|
1048 |
+
$uuid = self::RandomGenerator_uuid();
|
1049 |
+
|
1050 |
+
$numRetries = 0;
|
1051 |
+
do {
|
1052 |
+
$httpParsedResponseAr = $this->PPHttpPost_DontDieOnError( $methodName_, $nvpStr_, $uuid );
|
1053 |
+
if ( is_wp_error( $httpParsedResponseAr ) ) {
|
1054 |
+
$numRetries++;
|
1055 |
+
sleep( self::sleepTime( $numRetries ) );
|
1056 |
+
} else {
|
1057 |
+
break;
|
1058 |
+
}
|
1059 |
+
} while ( $numRetries <= self::$maxNetworkRetries );
|
1060 |
+
|
1061 |
+
// If we still have an error even with the retries, there's not much we can do.
|
1062 |
+
if ( is_wp_error( $httpParsedResponseAr ) ) {
|
1063 |
+
// exiting is never a good user experience and it's hard to debug, but we can
|
1064 |
+
// at least leave a trace in error log to make it easier to see this happening
|
1065 |
+
error_log( "Unable to complete $methodName_ request with $nvpStr_: " . $httpParsedResponseAr->get_error_message() );
|
1066 |
+
die( "Unable to complete $methodName_ request with $nvpStr_: " . $httpParsedResponseAr->get_error_message() );
|
1067 |
+
}
|
1068 |
+
|
1069 |
+
return $httpParsedResponseAr;
|
1070 |
+
}
|
1071 |
+
|
1072 |
+
/**
|
1073 |
+
* PAYPAL Function
|
1074 |
+
* Send HTTP POST Request with uuid
|
1075 |
*
|
1076 |
* @param string The API method name
|
1077 |
* @param string The POST Message fields in &name=value pair format
|
1078 |
+
* @return array|\WP_Error Parsed HTTP Response body
|
1079 |
*/
|
1080 |
+
function PPHttpPost_DontDieOnError($methodName_, $nvpStr_, $uuid) {
|
1081 |
global $gateway_environment;
|
1082 |
$environment = $gateway_environment;
|
1083 |
|
1099 |
'timeout' => 60,
|
1100 |
'sslverify' => FALSE,
|
1101 |
'httpversion' => '1.1',
|
1102 |
+
'body' => $nvpreq,
|
1103 |
+
'headers' => array(
|
1104 |
+
'content-type' => 'application/json',
|
1105 |
+
'PayPal-Request-Id' => $uuid,
|
1106 |
+
),
|
1107 |
)
|
1108 |
);
|
1109 |
|
1110 |
if ( is_wp_error( $response ) ) {
|
1111 |
+
return $response;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1112 |
}
|
1113 |
+
|
1114 |
+
//extract the response details
|
1115 |
+
$httpParsedResponseAr = array();
|
1116 |
+
parse_str(wp_remote_retrieve_body($response), $httpParsedResponseAr);
|
1117 |
+
|
1118 |
+
//check for valid response
|
1119 |
+
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
|
1120 |
+
return new WP_Error( 1, "Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint." );
|
1121 |
+
}
|
1122 |
|
1123 |
return $httpParsedResponseAr;
|
1124 |
}
|
1125 |
+
|
1126 |
+
/**
|
1127 |
+
* Provides the number of seconds to wait before retrying a request.
|
1128 |
+
* Inspired by Stripe\HttpClient\CurlClient::sleepTime
|
1129 |
+
*
|
1130 |
+
* @param int $numRetries
|
1131 |
+
*
|
1132 |
+
* @return int
|
1133 |
+
*/
|
1134 |
+
public static function sleepTime( $numRetries ) {
|
1135 |
+
// Apply exponential backoff with $initialNetworkRetryDelay on the
|
1136 |
+
// number of $numRetries so far as inputs. Do not allow the number to exceed
|
1137 |
+
// $maxNetworkRetryDelay.
|
1138 |
+
$sleepSeconds = \min(
|
1139 |
+
self::$maxNetworkRetryDelay * 1.0 * 2 ** ( $numRetries - 1 ),
|
1140 |
+
self::$maxNetworkRetryDelay
|
1141 |
+
);
|
1142 |
+
|
1143 |
+
// Apply some jitter by randomizing the value in the range of
|
1144 |
+
// ($sleepSeconds / 2) to ($sleepSeconds).
|
1145 |
+
$sleepSeconds *= 0.5 * ( 1 + self::randFloat() );
|
1146 |
+
|
1147 |
+
// But never sleep less than the base sleep seconds.
|
1148 |
+
$sleepSeconds = \max( self::$initialNetworkRetryDelay, $sleepSeconds );
|
1149 |
+
|
1150 |
+
return $sleepSeconds;
|
1151 |
+
}
|
1152 |
+
|
1153 |
+
/**
|
1154 |
+
* Returns a random value between 0 and $max.
|
1155 |
+
* From Stripe\Util\RandomGenerator::randFloat()
|
1156 |
+
*
|
1157 |
+
* @param float $max (optional)
|
1158 |
+
*
|
1159 |
+
* @return float
|
1160 |
+
*/
|
1161 |
+
public static function randFloat( $max = 1.0 ) {
|
1162 |
+
return \mt_rand() / \mt_getrandmax() * $max;
|
1163 |
+
}
|
1164 |
+
|
1165 |
+
/**
|
1166 |
+
* Returns a v4 UUID.
|
1167 |
+
* From Stripe\Util\RandomGenerator::uuid()
|
1168 |
+
*
|
1169 |
+
* @return string
|
1170 |
+
*/
|
1171 |
+
public static function RandomGenerator_uuid() {
|
1172 |
+
$arr = \array_values( \unpack( 'N1a/n4b/N1c', \openssl_random_pseudo_bytes( 16 ) ) );
|
1173 |
+
$arr[2] = ( $arr[2] & 0x0fff ) | 0x4000;
|
1174 |
+
$arr[3] = ( $arr[3] & 0x3fff ) | 0x8000;
|
1175 |
+
|
1176 |
+
return \vsprintf( '%08x-%04x-%04x-%04x-%04x%08x', $arr );
|
1177 |
+
}
|
1178 |
}
|
classes/gateways/class.pmprogateway_paypalstandard.php
CHANGED
@@ -170,7 +170,7 @@
|
|
170 |
<label for="apipassword"><?php _e('API Password', 'paid-memberships-pro' );?>:</label>
|
171 |
</th>
|
172 |
<td>
|
173 |
-
<input type="text" id="apipassword" name="apipassword" size="60" value="<?php echo esc_attr($values['apipassword'])?>" />
|
174 |
</td>
|
175 |
</tr>
|
176 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
@@ -238,12 +238,12 @@
|
|
238 |
?>
|
239 |
<span id="pmpro_paypalexpress_checkout" <?php if(($gateway != "paypalexpress" && $gateway != "paypalstandard") || !$pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
240 |
<input type="hidden" name="submit-checkout" value="1" />
|
241 |
-
<input type="image" value="<?php _e('Check Out with PayPal', 'paid-memberships-pro' );?> »" src="<?php echo apply_filters("pmpro_paypal_button_image", "https://www.paypalobjects.com/webstatic/en_US/i/buttons/checkout-logo-medium.png");?>" />
|
242 |
</span>
|
243 |
|
244 |
<span id="pmpro_submit_span" <?php if(($gateway == "paypalexpress" || $gateway == "paypalstandard") && $pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
245 |
<input type="hidden" name="submit-checkout" value="1" />
|
246 |
-
<input type="submit" class="<?php echo pmpro_get_element_class( 'pmpro_btn pmpro_btn-submit-checkout', 'pmpro_btn-submit-checkout' ); ?>" value="<?php if($pmpro_requirebilling) { _e('Submit and Check Out', 'paid-memberships-pro' ); } else { _e('Submit and Confirm', 'paid-memberships-pro' );}?> »" />
|
247 |
</span>
|
248 |
<?php
|
249 |
|
@@ -372,7 +372,8 @@
|
|
372 |
'notify_url' => add_query_arg( 'action', 'ipnhandler', admin_url("admin-ajax.php") ),
|
373 |
'src' => '1',
|
374 |
'sra' => '1',
|
375 |
-
'bn' => PAYPAL_BN_CODE
|
|
|
376 |
);
|
377 |
|
378 |
//trial?
|
170 |
<label for="apipassword"><?php _e('API Password', 'paid-memberships-pro' );?>:</label>
|
171 |
</th>
|
172 |
<td>
|
173 |
+
<input type="text" id="apipassword" name="apipassword" size="60" value="<?php echo esc_attr($values['apipassword'])?>" autocomplete="off" class="regular-text code pmpro-admin-secure-key" />
|
174 |
</td>
|
175 |
</tr>
|
176 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
238 |
?>
|
239 |
<span id="pmpro_paypalexpress_checkout" <?php if(($gateway != "paypalexpress" && $gateway != "paypalstandard") || !$pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
240 |
<input type="hidden" name="submit-checkout" value="1" />
|
241 |
+
<input type="image" id="pmpro_btn-submit-paypalstandard" class="<?php echo pmpro_get_element_class( 'pmpro_btn-submit-checkout' ); ?>" value="<?php _e('Check Out with PayPal', 'paid-memberships-pro' );?> »" src="<?php echo apply_filters("pmpro_paypal_button_image", "https://www.paypalobjects.com/webstatic/en_US/i/buttons/checkout-logo-medium.png");?>" />
|
242 |
</span>
|
243 |
|
244 |
<span id="pmpro_submit_span" <?php if(($gateway == "paypalexpress" || $gateway == "paypalstandard") && $pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
245 |
<input type="hidden" name="submit-checkout" value="1" />
|
246 |
+
<input type="submit" id="pmpro_btn-submit" class="<?php echo pmpro_get_element_class( 'pmpro_btn pmpro_btn-submit-checkout', 'pmpro_btn-submit-checkout' ); ?>" value="<?php if($pmpro_requirebilling) { _e('Submit and Check Out', 'paid-memberships-pro' ); } else { _e('Submit and Confirm', 'paid-memberships-pro' );}?> »" />
|
247 |
</span>
|
248 |
<?php
|
249 |
|
372 |
'notify_url' => add_query_arg( 'action', 'ipnhandler', admin_url("admin-ajax.php") ),
|
373 |
'src' => '1',
|
374 |
'sra' => '1',
|
375 |
+
'bn' => PAYPAL_BN_CODE,
|
376 |
+
'MAXFAILEDPAYMENTS' => 1
|
377 |
);
|
378 |
|
379 |
//trial?
|
classes/gateways/class.pmprogateway_stripe.php
CHANGED
@@ -3,14 +3,17 @@
|
|
3 |
use Stripe\Customer as Stripe_Customer;
|
4 |
use Stripe\Invoice as Stripe_Invoice;
|
5 |
use Stripe\Plan as Stripe_Plan;
|
|
|
|
|
6 |
use Stripe\Charge as Stripe_Charge;
|
7 |
use Stripe\PaymentIntent as Stripe_PaymentIntent;
|
8 |
use Stripe\SetupIntent as Stripe_SetupIntent;
|
9 |
-
use Stripe\Source as Stripe_Source;
|
10 |
use Stripe\PaymentMethod as Stripe_PaymentMethod;
|
11 |
use Stripe\Subscription as Stripe_Subscription;
|
|
|
12 |
use Stripe\WebhookEndpoint as Stripe_Webhook;
|
13 |
use Stripe\StripeClient as Stripe_Client; // Used for deleting webhook as of 2.4
|
|
|
14 |
|
15 |
define( "PMPRO_STRIPE_API_VERSION", "2020-03-02" );
|
16 |
|
@@ -48,66 +51,30 @@ class PMProGateway_stripe extends PMProGateway {
|
|
48 |
|
49 |
if ( true === $this->dependencies() ) {
|
50 |
$this->loadStripeLibrary();
|
51 |
-
Stripe\Stripe::setApiKey(
|
52 |
Stripe\Stripe::setAPIVersion( PMPRO_STRIPE_API_VERSION );
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
self::$is_loaded = true;
|
54 |
}
|
55 |
|
56 |
return $this->gateway;
|
57 |
}
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
* @return bool
|
63 |
-
* @since 1.8.6.8.1
|
64 |
-
* @since 1.8.13.6 - Add json dependency
|
65 |
-
*/
|
66 |
-
public static function dependencies() {
|
67 |
-
global $msg, $msgt, $pmpro_stripe_error;
|
68 |
-
|
69 |
-
if ( version_compare( PHP_VERSION, '5.3.29', '<' ) ) {
|
70 |
-
|
71 |
-
$pmpro_stripe_error = true;
|
72 |
-
$msg = - 1;
|
73 |
-
$msgt = sprintf( __( "The Stripe Gateway requires PHP 5.3.29 or greater. We recommend upgrading to PHP %s or greater. Ask your host to upgrade.", "paid-memberships-pro" ), PMPRO_PHP_MIN_VERSION );
|
74 |
-
|
75 |
-
if ( ! is_admin() ) {
|
76 |
-
pmpro_setMessage( $msgt, "pmpro_error" );
|
77 |
-
}
|
78 |
-
|
79 |
-
return false;
|
80 |
-
}
|
81 |
-
|
82 |
-
$modules = array( 'curl', 'mbstring', 'json' );
|
83 |
-
|
84 |
-
foreach ( $modules as $module ) {
|
85 |
-
if ( ! extension_loaded( $module ) ) {
|
86 |
-
$pmpro_stripe_error = true;
|
87 |
-
$msg = - 1;
|
88 |
-
$msgt = sprintf( __( "The %s gateway depends on the %s PHP extension. Please enable it, or ask your hosting provider to enable it.", 'paid-memberships-pro' ), 'Stripe', $module );
|
89 |
-
|
90 |
-
//throw error on checkout page
|
91 |
-
if ( ! is_admin() ) {
|
92 |
-
pmpro_setMessage( $msgt, 'pmpro_error' );
|
93 |
-
}
|
94 |
-
|
95 |
-
return false;
|
96 |
-
}
|
97 |
-
}
|
98 |
-
|
99 |
-
self::$is_loaded = true;
|
100 |
-
|
101 |
-
return true;
|
102 |
-
}
|
103 |
-
|
104 |
/**
|
105 |
* Load the Stripe API library.
|
106 |
*
|
107 |
* @since 1.8
|
108 |
* Moved into a method in version 1.8 so we only load it when needed.
|
109 |
*/
|
110 |
-
function loadStripeLibrary() {
|
111 |
//load Stripe library if it hasn't been loaded already (usually by another plugin using Stripe)
|
112 |
if ( ! class_exists( "Stripe\Stripe" ) ) {
|
113 |
require_once( PMPRO_DIR . "/includes/lib/Stripe/init.php" );
|
@@ -119,7 +86,7 @@ class PMProGateway_stripe extends PMProGateway {
|
|
119 |
*
|
120 |
* @since 1.8
|
121 |
*/
|
122 |
-
static function init() {
|
123 |
//make sure Stripe is a gateway option
|
124 |
add_filter( 'pmpro_gateways', array( 'PMProGateway_stripe', 'pmpro_gateways' ) );
|
125 |
|
@@ -140,7 +107,12 @@ class PMProGateway_stripe extends PMProGateway {
|
|
140 |
//old global RE showing billing address or not
|
141 |
global $pmpro_stripe_lite;
|
142 |
$pmpro_stripe_lite = apply_filters( "pmpro_stripe_lite", ! pmpro_getOption( "stripe_billingaddress" ) ); //default is oposite of the stripe_billingaddress setting
|
143 |
-
|
|
|
|
|
|
|
|
|
|
|
144 |
|
145 |
//updates cron
|
146 |
add_action( 'pmpro_cron_stripe_subscription_updates', array(
|
@@ -151,6 +123,7 @@ class PMProGateway_stripe extends PMProGateway {
|
|
151 |
//AJAX services for creating/disabling webhooks
|
152 |
add_action( 'wp_ajax_pmpro_stripe_create_webhook', array( 'PMProGateway_stripe', 'wp_ajax_pmpro_stripe_create_webhook' ) );
|
153 |
add_action( 'wp_ajax_pmpro_stripe_delete_webhook', array( 'PMProGateway_stripe', 'wp_ajax_pmpro_stripe_delete_webhook' ) );
|
|
|
154 |
|
155 |
/*
|
156 |
Filter pmpro_next_payment to get actual value
|
@@ -197,7 +170,13 @@ class PMProGateway_stripe extends PMProGateway {
|
|
197 |
) );
|
198 |
}
|
199 |
|
|
|
200 |
add_action( 'init', array( 'PMProGateway_stripe', 'clear_saved_subscriptions' ) );
|
|
|
|
|
|
|
|
|
|
|
201 |
}
|
202 |
|
203 |
/**
|
@@ -232,7 +211,7 @@ class PMProGateway_stripe extends PMProGateway {
|
|
232 |
*
|
233 |
* @since 1.8
|
234 |
*/
|
235 |
-
static function pmpro_gateways( $gateways ) {
|
236 |
if ( empty( $gateways['stripe'] ) ) {
|
237 |
$gateways['stripe'] = __( 'Stripe', 'paid-memberships-pro' );
|
238 |
}
|
@@ -245,20 +224,27 @@ class PMProGateway_stripe extends PMProGateway {
|
|
245 |
*
|
246 |
* @since 1.8
|
247 |
*/
|
248 |
-
static function getGatewayOptions() {
|
249 |
$options = array(
|
250 |
'sslseal',
|
251 |
'nuclear_HTTPS',
|
252 |
'gateway_environment',
|
253 |
'stripe_secretkey',
|
254 |
'stripe_publishablekey',
|
|
|
|
|
|
|
|
|
|
|
|
|
255 |
'stripe_webhook',
|
256 |
'stripe_billingaddress',
|
257 |
'currency',
|
258 |
'use_ssl',
|
259 |
'tax_state',
|
260 |
'tax_rate',
|
261 |
-
'accepted_credit_cards'
|
|
|
262 |
);
|
263 |
|
264 |
return $options;
|
@@ -269,7 +255,7 @@ class PMProGateway_stripe extends PMProGateway {
|
|
269 |
*
|
270 |
* @since 1.8
|
271 |
*/
|
272 |
-
static function pmpro_payment_options( $options ) {
|
273 |
//get stripe options
|
274 |
$stripe_options = self::getGatewayOptions();
|
275 |
|
@@ -284,120 +270,197 @@ class PMProGateway_stripe extends PMProGateway {
|
|
284 |
*
|
285 |
* @since 1.8
|
286 |
*/
|
287 |
-
static function pmpro_payment_option_fields( $values, $gateway ) {
|
288 |
-
|
289 |
-
if ( ! empty( $values['stripe_publishablekey'] ) && ! empty( $values['stripe_secretkey'] ) ) {
|
290 |
-
|
291 |
-
// Check if webhook is enabled or not.
|
292 |
-
$webhook = self::get_webhook_ids( $values['stripe_secretkey'] );
|
293 |
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
}
|
298 |
-
|
299 |
-
$required_update = false;
|
300 |
-
// Check to see if events are missing.
|
301 |
-
if ( is_array( $webhook ) ) {
|
302 |
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
|
307 |
-
|
|
|
308 |
$events = self::check_missing_webhook_events( $webhook['enabled_events'] );
|
309 |
-
|
310 |
if ( $events ) {
|
311 |
-
|
312 |
-
} else {
|
313 |
-
$required_update = false;
|
314 |
-
self::update_webhook_ids( $webhook['webhook_id'], $values['stripe_secretkey'] );
|
315 |
-
pmpro_setOption( 'stripe_webhook', 1 );
|
316 |
-
$values['stripe_webhook'] = 1; // Checkbox option.
|
317 |
}
|
318 |
}
|
319 |
|
320 |
-
|
321 |
-
|
322 |
-
$values['stripe_webhook'] = 1;
|
323 |
-
} else {
|
324 |
-
$require_update = true;
|
325 |
}
|
326 |
|
327 |
-
}
|
328 |
-
|
329 |
?>
|
330 |
-
|
331 |
-
|
332 |
-
<td><code><?php echo PMPRO_STRIPE_API_VERSION; ?></code></td>
|
333 |
-
</tr>
|
334 |
-
<tr class="pmpro_settings_divider gateway gateway_stripe"
|
335 |
-
<?php if ( $gateway != "stripe" ) { ?>style="display: none;"<?php } ?>>
|
336 |
-
<td colspan="2">
|
337 |
<hr />
|
338 |
-
<h2
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
347 |
<?php
|
348 |
$public_key_prefix = substr( $values['stripe_publishablekey'], 0, 3 );
|
349 |
if ( ! empty( $values['stripe_publishablekey'] ) && $public_key_prefix != 'pk_' ) {
|
350 |
?>
|
351 |
-
|
352 |
<?php
|
353 |
}
|
354 |
?>
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
<?php if ( self::
|
371 |
<button type="button" id="pmpro_stripe_create_webhook" class="button button-secondary" style="display: none;"><span class="dashicons dashicons-update-alt"></span> <?php _e( 'Create Webhook' ,'paid-memberships-pro' ); ?></button>
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
385 |
<tr class="gateway gateway_stripe" <?php if ( $gateway != "stripe" ) { ?>style="display: none;"<?php } ?>>
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
|
|
|
|
|
|
397 |
<p class="description"><?php _e( "Stripe doesn't require billing address fields. Choose 'No' to hide them on the checkout page.<br /><strong>If No, make sure you disable address verification in the Stripe dashboard settings.</strong>", 'paid-memberships-pro' ); ?></p>
|
398 |
-
|
399 |
-
|
400 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
401 |
$allowed_appe_html = array (
|
402 |
'a' => array (
|
403 |
'href' => array(),
|
@@ -417,48 +480,43 @@ class PMProGateway_stripe extends PMProGateway {
|
|
417 |
/**
|
418 |
* AJAX callback to create webhooks.
|
419 |
*/
|
420 |
-
static function wp_ajax_pmpro_stripe_create_webhook() {
|
421 |
$secretkey = sanitize_text_field( $_REQUEST['secretkey'] );
|
422 |
|
423 |
$stripe = new PMProGateway_stripe();
|
424 |
Stripe\Stripe::setApiKey( $secretkey );
|
425 |
|
426 |
-
$
|
427 |
-
|
428 |
-
if ( empty( $
|
|
|
429 |
$r = array(
|
430 |
'success' => false,
|
431 |
'notice' => 'error',
|
432 |
-
'message' =>
|
433 |
-
'response' => $
|
434 |
);
|
435 |
} else {
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
);
|
443 |
-
} else {
|
444 |
-
$r = array(
|
445 |
-
'success' => true,
|
446 |
-
'notice' => 'notice-success',
|
447 |
-
'message' => __( 'Your webhook is enabled.', 'paid-memberships-pro' ),
|
448 |
-
'response' => $r
|
449 |
-
);
|
450 |
-
}
|
451 |
}
|
452 |
|
453 |
-
|
454 |
-
|
455 |
-
|
|
|
|
|
|
|
456 |
}
|
457 |
|
458 |
/**
|
459 |
* AJAX callback to disable webhooks.
|
460 |
*/
|
461 |
-
static function wp_ajax_pmpro_stripe_delete_webhook() {
|
462 |
$secretkey = sanitize_text_field( $_REQUEST['secretkey'] );
|
463 |
|
464 |
$stripe = new PMProGateway_stripe();
|
@@ -466,43 +524,48 @@ class PMProGateway_stripe extends PMProGateway {
|
|
466 |
|
467 |
$webhook = self::does_webhook_exist();
|
468 |
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
$r = array(
|
480 |
'success' => false,
|
481 |
'notice' => 'error',
|
482 |
-
'message' => $
|
483 |
-
'response' => $r
|
484 |
);
|
485 |
-
}
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
501 |
}
|
502 |
}
|
503 |
|
504 |
echo json_encode( $r );
|
505 |
-
|
506 |
exit;
|
507 |
}
|
508 |
|
@@ -511,9 +574,8 @@ class PMProGateway_stripe extends PMProGateway {
|
|
511 |
*
|
512 |
* @since 1.8
|
513 |
*/
|
514 |
-
static function pmpro_checkout_after_preheader( $order ) {
|
515 |
-
|
516 |
-
global $gateway, $pmpro_level, $current_user, $pmpro_requirebilling, $pmpro_pages;
|
517 |
|
518 |
$default_gateway = pmpro_getOption( "gateway" );
|
519 |
|
@@ -522,22 +584,26 @@ class PMProGateway_stripe extends PMProGateway {
|
|
522 |
wp_enqueue_script( "stripe", "https://js.stripe.com/v3/", array(), null );
|
523 |
|
524 |
if ( ! function_exists( 'pmpro_stripe_javascript' ) ) {
|
525 |
-
|
526 |
$localize_vars = array(
|
527 |
-
'publishableKey' =>
|
|
|
528 |
'verifyAddress' => apply_filters( 'pmpro_stripe_verify_address', pmpro_getOption( 'stripe_billingaddress' ) ),
|
529 |
'ajaxUrl' => admin_url( "admin-ajax.php" ),
|
530 |
'msgAuthenticationValidated' => __( 'Verification steps confirmed. Your payment is processing.', 'paid-memberships-pro' ),
|
531 |
'pmpro_require_billing' => $pmpro_requirebilling,
|
|
|
|
|
|
|
|
|
|
|
532 |
);
|
533 |
|
534 |
if ( ! empty( $order ) ) {
|
535 |
-
if ( ! empty( $order->
|
536 |
-
$localize_vars['paymentIntent'] = $order->
|
537 |
}
|
538 |
-
if ( ! empty( $order->
|
539 |
-
$localize_vars['setupIntent'] = $order->
|
540 |
-
$localize_vars['subscription'] = $order->Gateway->subscription;
|
541 |
}
|
542 |
}
|
543 |
|
@@ -555,7 +621,7 @@ class PMProGateway_stripe extends PMProGateway {
|
|
555 |
* Don't require the CVV.
|
556 |
* Don't require address fields if they are set to hide.
|
557 |
*/
|
558 |
-
static function pmpro_required_billing_fields( $fields ) {
|
559 |
global $pmpro_stripe_lite, $current_user, $bemail, $bconfirmemail;
|
560 |
|
561 |
//CVV is not required if set that way at Stripe. The Stripe JS will require it if it is required.
|
@@ -589,389 +655,84 @@ class PMProGateway_stripe extends PMProGateway {
|
|
589 |
|
590 |
return $fields;
|
591 |
}
|
592 |
-
|
593 |
/**
|
594 |
-
*
|
595 |
*
|
596 |
-
* @since
|
597 |
*/
|
598 |
-
static function
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
$webhook_id = pmpro_getOption( 'stripe_webhook_id' );
|
604 |
-
if ( ! empty( $webhook_id ) ) {
|
605 |
-
// We store ids with the cooresponding secret key now.
|
606 |
-
// Assume this webhook is for the currently selected environment.
|
607 |
-
$secret_key = pmpro_getOption( 'stripe_secretkey' );
|
608 |
-
$webhook_ids = array( $secret_key => $webhook_id );
|
609 |
-
delete_option( 'pmpro_stripe_webhook_id' );
|
610 |
-
update_option( 'pmpro_stripe_webhook_ids', $webhook_ids );
|
611 |
-
}
|
612 |
}
|
613 |
-
|
614 |
-
//
|
615 |
-
if (
|
616 |
-
$
|
617 |
-
|
618 |
-
// No key, then there will be no webhook.
|
619 |
-
if ( empty( $secret_key ) ) {
|
620 |
-
return false;
|
621 |
-
}
|
622 |
}
|
623 |
-
|
624 |
-
//
|
625 |
-
if ( ! empty( $
|
626 |
-
$
|
627 |
-
if ( isset( $webhook_ids[$secret_key_hash] ) ) {
|
628 |
-
return $webhook_ids[$secret_key_hash];
|
629 |
-
} else {
|
630 |
-
return false;
|
631 |
-
}
|
632 |
}
|
633 |
-
|
634 |
-
|
635 |
-
|
|
|
636 |
}
|
637 |
-
|
638 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
639 |
}
|
640 |
-
|
641 |
/**
|
642 |
-
*
|
643 |
*
|
644 |
-
* @since
|
645 |
*/
|
646 |
-
static function
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
}
|
654 |
-
|
655 |
-
// Hash the secret key so it's not left behind in the DB.
|
656 |
-
$secret_key_hash = wp_hash( $secret_key );
|
657 |
-
|
658 |
-
$webhook_ids = self::get_webhook_ids();
|
659 |
-
|
660 |
-
if ( ! empty( $webhook_id ) ) {
|
661 |
-
$webhook_ids[$secret_key_hash] = $webhook_id;
|
662 |
-
} else {
|
663 |
-
unset( $webhook_ids[$secret_key_hash] );
|
664 |
}
|
665 |
-
|
666 |
-
update_option( 'pmpro_stripe_webhook_ids', $webhook_ids );
|
667 |
-
return true;
|
668 |
}
|
669 |
|
670 |
/**
|
671 |
-
*
|
672 |
-
*
|
673 |
-
* @since 2.4
|
674 |
*/
|
675 |
-
static function
|
676 |
-
|
677 |
-
|
|
|
678 |
}
|
679 |
|
680 |
-
|
681 |
-
$webhooks = Stripe_Webhook::all( [ 'limit' => apply_filters( 'pmpro_stripe_webhook_retrieve_limit', $limit ) ] );
|
682 |
-
} catch (\Throwable $th) {
|
683 |
-
$webhooks = $th->getMessage();
|
684 |
-
} catch (\Exception $e) {
|
685 |
-
$webhooks = $e->getMessage();
|
686 |
-
}
|
687 |
-
|
688 |
-
return $webhooks;
|
689 |
}
|
690 |
|
691 |
/**
|
692 |
-
*
|
693 |
-
*
|
694 |
-
* @since 2.4
|
695 |
*/
|
696 |
-
static function
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
/**
|
701 |
-
* List of current enabled events required for PMPro to work.
|
702 |
-
*
|
703 |
-
* @since 2.4
|
704 |
-
*/
|
705 |
-
static function webhook_events() {
|
706 |
-
return apply_filters( 'pmpro_stripe_webhook_events', array(
|
707 |
-
'invoice.payment_succeeded',
|
708 |
-
'invoice.payment_action_required',
|
709 |
-
'customer.subscription.deleted',
|
710 |
-
'charge.failed'
|
711 |
-
) );
|
712 |
-
}
|
713 |
-
|
714 |
-
/**
|
715 |
-
* Create webhook with relevant events
|
716 |
-
*
|
717 |
-
* @since 2.4
|
718 |
-
*/
|
719 |
-
static function create_webhook() {
|
720 |
-
try {
|
721 |
-
$create = Stripe_Webhook::create([
|
722 |
-
'url' => self::get_site_webhook_url(),
|
723 |
-
'enabled_events' => self::webhook_events(),
|
724 |
-
'api_version' => PMPRO_STRIPE_API_VERSION
|
725 |
-
]);
|
726 |
-
|
727 |
-
if ( $create ) {
|
728 |
-
self::update_webhook_ids( $create->id );
|
729 |
-
return $create->id;
|
730 |
-
}
|
731 |
-
} catch (\Throwable $th) {
|
732 |
-
//throw $th;
|
733 |
-
return new WP_Error( 'error', $th->getMessage() );
|
734 |
-
} catch (\Exception $e) {
|
735 |
-
//throw $th;
|
736 |
-
return new WP_Error( 'error', $e->getMessage() );
|
737 |
-
}
|
738 |
-
|
739 |
-
}
|
740 |
-
|
741 |
-
/**
|
742 |
-
* See if a webhook is registered with Stripe.
|
743 |
-
*
|
744 |
-
* @since 2.4
|
745 |
-
*/
|
746 |
-
static function does_webhook_exist() {
|
747 |
-
$saved_webhook = self::get_webhook_ids( true );
|
748 |
-
if ( $saved_webhook ) {
|
749 |
-
return $saved_webhook;
|
750 |
-
}
|
751 |
-
|
752 |
-
$webhooks = self::get_webhooks();
|
753 |
-
$webhook_id = false;
|
754 |
-
if ( ! empty( $webhooks ) && ! empty( $webhooks['data'] ) ) {
|
755 |
-
|
756 |
-
$pmpro_webhook_url = self::get_site_webhook_url();
|
757 |
-
|
758 |
-
foreach( $webhooks as $webhook ) {
|
759 |
-
if ( $webhook->url == $pmpro_webhook_url ) {
|
760 |
-
$webhook_id = $webhook->id;
|
761 |
-
$webhook_events = $webhook->enabled_events;
|
762 |
-
continue;
|
763 |
-
}
|
764 |
-
}
|
765 |
-
} else {
|
766 |
-
$webhook_id = false; // make sure it's false if none are found.
|
767 |
-
}
|
768 |
-
|
769 |
-
if ( $webhook_id ) {
|
770 |
-
$webhook_data = array();
|
771 |
-
$webhook_data['webhook_id'] = $webhook_id;
|
772 |
-
$webhook_data['enabled_events'] = $webhook_events;
|
773 |
-
return $webhook_data;
|
774 |
-
} else {
|
775 |
-
return false;
|
776 |
-
}
|
777 |
-
}
|
778 |
-
|
779 |
-
/**
|
780 |
-
* Get a list of events that are missing between the created existing webhook and required webhook events for Paid Memberships Pro.
|
781 |
-
*
|
782 |
-
* @since 2.4
|
783 |
-
*/
|
784 |
-
static function check_missing_webhook_events( $webhook_events ) {
|
785 |
-
|
786 |
-
// Get required events
|
787 |
-
$pmpro_webhook_events = self::webhook_events();
|
788 |
-
$event_missing = false;
|
789 |
-
|
790 |
-
// No missing events if webhook event is "All Events" selected.
|
791 |
-
if ( is_array( $webhook_events ) && $webhook_events[0] === '*' ) {
|
792 |
-
return false;
|
793 |
-
}
|
794 |
-
|
795 |
-
foreach( $pmpro_webhook_events as $event ) {
|
796 |
-
if ( ! in_array( $event, $webhook_events ) ) {
|
797 |
-
$event_missing = true;
|
798 |
-
}
|
799 |
-
}
|
800 |
-
|
801 |
-
if ( $event_missing ) {
|
802 |
-
$events = array_unique( array_merge( $pmpro_webhook_events, $webhook_events ) );
|
803 |
-
// Force reset of indexes for Stripe.
|
804 |
-
$events = array_values( $events );
|
805 |
-
} else {
|
806 |
-
$events = false;
|
807 |
-
}
|
808 |
-
|
809 |
-
return $events;
|
810 |
-
}
|
811 |
-
|
812 |
-
/**
|
813 |
-
* Update required webhook enabled events.
|
814 |
-
*
|
815 |
-
* @since 2.4
|
816 |
-
*/
|
817 |
-
static function update_webhook_events() {
|
818 |
-
|
819 |
-
// Also checks database to see if it's been saved.
|
820 |
-
$webhook = self::does_webhook_exist();
|
821 |
-
|
822 |
-
if ( empty( $webhook ) ) {
|
823 |
-
$create = self::create_webhook();
|
824 |
-
return $create;
|
825 |
-
}
|
826 |
-
|
827 |
-
// Bail if no enabled events for a webhook are passed through.
|
828 |
-
if ( ! isset( $webhook['enabled_events'] ) ) {
|
829 |
-
return;
|
830 |
-
}
|
831 |
-
|
832 |
-
$events = self::check_missing_webhook_events( $webhook['enabled_events'] );
|
833 |
-
|
834 |
-
if ( $events ) {
|
835 |
-
|
836 |
-
try {
|
837 |
-
$update = Stripe_Webhook::update(
|
838 |
-
$webhook['webhook_id'],
|
839 |
-
['enabled_events' => $events ]
|
840 |
-
);
|
841 |
-
|
842 |
-
if ( $update ) {
|
843 |
-
self:update_webhook_ids( $webhook['webhook_id'] );
|
844 |
-
return $update;
|
845 |
-
}
|
846 |
-
} catch (\Throwable $th) {
|
847 |
-
//throw $th;
|
848 |
-
return new WP_Error( 'error', $th->getMessage() );
|
849 |
-
} catch (\Exception $e) {
|
850 |
-
//throw $th;
|
851 |
-
return new WP_Error( 'error', $e->getMessage() );
|
852 |
-
}
|
853 |
-
|
854 |
-
} else {
|
855 |
-
self::update_webhook_ids( $webhook['webhook_id'] );
|
856 |
-
}
|
857 |
-
|
858 |
-
}
|
859 |
-
|
860 |
-
/**
|
861 |
-
* Delete an existing webhook.
|
862 |
-
*
|
863 |
-
* @since 2.4
|
864 |
-
*/
|
865 |
-
function delete_webhook( $webhook_id, $secretkey = false ) {
|
866 |
-
if ( empty( $secretkey ) ) {
|
867 |
-
$secretkey = pmpro_getOption( "stripe_secretkey" );
|
868 |
-
}
|
869 |
-
|
870 |
-
try {
|
871 |
-
$stripe = new Stripe_Client( $secretkey );
|
872 |
-
$delete = $stripe->webhookEndpoints->delete( $webhook_id, [] );
|
873 |
-
self::update_webhook_ids( '', $secretkey );
|
874 |
-
} catch (\Throwable $th) {
|
875 |
-
self::update_webhook_ids( '', $secretkey );
|
876 |
-
return new WP_Error( 'error', $th->getMessage() );
|
877 |
-
} catch (\Exception $e) {
|
878 |
-
self::update_webhook_ids( '', $secretkey );
|
879 |
-
return new WP_Error( 'error', $e->getMessage() );
|
880 |
-
}
|
881 |
-
|
882 |
-
return $delete;
|
883 |
-
}
|
884 |
-
|
885 |
-
/**
|
886 |
-
* Filtering orders at checkout.
|
887 |
-
*
|
888 |
-
* @since 1.8
|
889 |
-
*/
|
890 |
-
static function pmpro_checkout_order( $morder ) {
|
891 |
-
|
892 |
-
// Create a code for the order.
|
893 |
-
if ( empty( $morder->code ) ) {
|
894 |
-
$morder->code = $morder->getRandomCode();
|
895 |
-
}
|
896 |
-
|
897 |
-
// Add the PaymentIntent ID to the order.
|
898 |
-
if ( ! empty ( $_REQUEST['payment_intent_id'] ) ) {
|
899 |
-
$morder->payment_intent_id = sanitize_text_field( $_REQUEST['payment_intent_id'] );
|
900 |
-
}
|
901 |
-
|
902 |
-
// Add the SetupIntent ID to the order.
|
903 |
-
if ( ! empty ( $_REQUEST['setup_intent_id'] ) ) {
|
904 |
-
$morder->setup_intent_id = sanitize_text_field( $_REQUEST['setup_intent_id'] );
|
905 |
-
}
|
906 |
-
|
907 |
-
// Add the Subscription ID to the order.
|
908 |
-
if ( ! empty ( $_REQUEST['subscription_id'] ) ) {
|
909 |
-
$morder->subscription_transaction_id = sanitize_text_field( $_REQUEST['subscription_id'] );
|
910 |
-
}
|
911 |
-
|
912 |
-
// Add the PaymentMethod ID to the order.
|
913 |
-
if ( ! empty ( $_REQUEST['payment_method_id'] ) ) {
|
914 |
-
$morder->payment_method_id = sanitize_text_field( $_REQUEST['payment_method_id'] );
|
915 |
-
}
|
916 |
-
|
917 |
-
// Add the Customer ID to the order.
|
918 |
-
if ( empty( $morder->customer_id ) ) {
|
919 |
-
|
920 |
-
}
|
921 |
-
if ( ! empty ( $_REQUEST['customer_id'] ) ) {
|
922 |
-
$morder->customer_id = sanitize_text_field( $_REQUEST['customer_id'] );
|
923 |
-
}
|
924 |
-
|
925 |
-
//stripe lite code to get name from other sources if available
|
926 |
-
global $pmpro_stripe_lite, $current_user;
|
927 |
-
if ( ! empty( $pmpro_stripe_lite ) && empty( $morder->FirstName ) && empty( $morder->LastName ) ) {
|
928 |
-
if ( ! empty( $current_user->ID ) ) {
|
929 |
-
$morder->FirstName = get_user_meta( $current_user->ID, "first_name", true );
|
930 |
-
$morder->LastName = get_user_meta( $current_user->ID, "last_name", true );
|
931 |
-
} elseif ( ! empty( $_REQUEST['first_name'] ) && ! empty( $_REQUEST['last_name'] ) ) {
|
932 |
-
$morder->FirstName = sanitize_text_field( $_REQUEST['first_name'] );
|
933 |
-
$morder->LastName = sanitize_text_field( $_REQUEST['last_name'] );
|
934 |
-
}
|
935 |
-
}
|
936 |
-
|
937 |
-
return $morder;
|
938 |
-
}
|
939 |
-
|
940 |
-
/**
|
941 |
-
* Code to run after checkout
|
942 |
-
*
|
943 |
-
* @since 1.8
|
944 |
-
*/
|
945 |
-
static function pmpro_after_checkout( $user_id, $morder ) {
|
946 |
-
global $gateway;
|
947 |
-
|
948 |
-
if ( $gateway == "stripe" ) {
|
949 |
-
if ( self::$is_loaded && ! empty( $morder ) && ! empty( $morder->Gateway ) && ! empty( $morder->Gateway->customer ) && ! empty( $morder->Gateway->customer->id ) ) {
|
950 |
-
update_user_meta( $user_id, "pmpro_stripe_customerid", $morder->Gateway->customer->id );
|
951 |
-
}
|
952 |
-
}
|
953 |
-
}
|
954 |
-
|
955 |
-
/**
|
956 |
-
* Check settings if billing address should be shown.
|
957 |
-
* @since 1.8
|
958 |
-
*/
|
959 |
-
static function pmpro_include_billing_address_fields( $include ) {
|
960 |
-
//check settings RE showing billing address
|
961 |
-
if ( ! pmpro_getOption( "stripe_billingaddress" ) ) {
|
962 |
-
$include = false;
|
963 |
-
}
|
964 |
-
|
965 |
-
return $include;
|
966 |
-
}
|
967 |
-
|
968 |
-
/**
|
969 |
-
* Use our own payment fields at checkout. (Remove the name attributes.)
|
970 |
-
* @since 1.8
|
971 |
-
*/
|
972 |
-
static function pmpro_include_payment_information_fields( $include ) {
|
973 |
-
//global vars
|
974 |
-
global $pmpro_requirebilling, $pmpro_show_discount_code, $discount_code, $CardType, $AccountNumber, $ExpirationMonth, $ExpirationYear;
|
975 |
|
976 |
//get accepted credit cards
|
977 |
$pmpro_accepted_credit_cards = pmpro_getOption( "accepted_credit_cards" );
|
@@ -990,6 +751,15 @@ class PMProGateway_stripe extends PMProGateway {
|
|
990 |
<?php if ( ! empty( $sslseal ) ) { ?>
|
991 |
<div class="<?php echo pmpro_get_element_class( 'pmpro_checkout-fields-display-seal' ); ?>">
|
992 |
<?php } ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
993 |
<div class="pmpro_checkout-fields<?php if ( ! empty( $sslseal ) ) { ?> pmpro_checkout-fields-leftcol<?php } ?>">
|
994 |
<?php
|
995 |
$pmpro_include_cardtype_field = apply_filters( 'pmpro_include_cardtype_field', false );
|
@@ -1026,7 +796,7 @@ class PMProGateway_stripe extends PMProGateway {
|
|
1026 |
<?php if ( $pmpro_show_discount_code ) { ?>
|
1027 |
<div class="<?php echo pmpro_get_element_class( 'pmpro_checkout-field pmpro_payment-discount-code', 'pmpro_payment-discount-code' ); ?>">
|
1028 |
<label for="discount_code"><?php _e( 'Discount Code', 'paid-memberships-pro' ); ?></label>
|
1029 |
-
<input class="<?php echo pmpro_get_element_class( 'input', 'discount_code' ); ?>"
|
1030 |
id="discount_code" name="discount_code" type="text" size="10"
|
1031 |
value="<?php echo esc_attr( $discount_code ) ?>"/>
|
1032 |
<input type="button" id="discount_code_button" name="discount_code_button"
|
@@ -1051,18 +821,9 @@ class PMProGateway_stripe extends PMProGateway {
|
|
1051 |
*
|
1052 |
* @since 1.8
|
1053 |
*/
|
1054 |
-
static function user_profile_fields( $user ) {
|
1055 |
global $wpdb, $current_user, $pmpro_currency_symbol;
|
1056 |
|
1057 |
-
$cycles = array(
|
1058 |
-
__( 'Day(s)', 'paid-memberships-pro' ) => 'Day',
|
1059 |
-
__( 'Week(s)', 'paid-memberships-pro' ) => 'Week',
|
1060 |
-
__( 'Month(s)', 'paid-memberships-pro' ) => 'Month',
|
1061 |
-
__( 'Year(s)', 'paid-memberships-pro' ) => 'Year'
|
1062 |
-
);
|
1063 |
-
$current_year = date_i18n( "Y" );
|
1064 |
-
$current_month = date_i18n( "m" );
|
1065 |
-
|
1066 |
//make sure the current user has privileges
|
1067 |
$membership_level_capability = apply_filters( "pmpro_edit_member_capability", "manage_options" );
|
1068 |
if ( ! current_user_can( $membership_level_capability ) ) {
|
@@ -1075,223 +836,44 @@ class PMProGateway_stripe extends PMProGateway {
|
|
1075 |
return false;
|
1076 |
}
|
1077 |
|
1078 |
-
//
|
1079 |
-
$
|
1080 |
-
$
|
1081 |
-
|
1082 |
-
//assume no sub to start
|
1083 |
-
$sub = false;
|
1084 |
|
1085 |
-
//
|
1086 |
-
if (
|
1087 |
-
//
|
1088 |
-
|
|
|
|
|
|
|
|
|
1089 |
}
|
1090 |
-
|
1091 |
-
$customer_id = $user->pmpro_stripe_customerid;
|
1092 |
-
|
1093 |
-
if ( empty( $sub ) ) {
|
1094 |
-
//make sure we delete stripe updates
|
1095 |
-
update_user_meta( $user->ID, "pmpro_stripe_updates", array() );
|
1096 |
-
|
1097 |
-
//if the last order has a sub id, let the admin know there is no sub at Stripe
|
1098 |
-
if ( ! empty( $last_order ) && $last_order->gateway == "stripe" && ! empty( $last_order->subscription_transaction_id ) && strpos( $last_order->subscription_transaction_id, "sub_" ) !== false ) {
|
1099 |
-
?>
|
1100 |
-
<p><?php printf( __( '%1$sNote:%2$s Subscription %3$s%4$s%5$s could not be found at Stripe. It may have been deleted.', 'paid-memberships-pro' ), '<strong>', '</strong>', '<strong>', esc_attr( $last_order->subscription_transaction_id ), '</strong>' ); ?></p>
|
1101 |
-
<?php
|
1102 |
-
}
|
1103 |
-
} elseif ( true === self::$is_loaded ) {
|
1104 |
-
?>
|
1105 |
-
<h3><?php _e( "Subscription Updates", 'paid-memberships-pro' ); ?></h3>
|
1106 |
-
<p>
|
1107 |
-
<?php
|
1108 |
-
if ( empty( $_REQUEST['user_id'] ) ) {
|
1109 |
-
_e( "Subscription updates, allow you to change the member's subscription values at predefined times. Be sure to click Update Profile after making changes.", 'paid-memberships-pro' );
|
1110 |
-
} else {
|
1111 |
-
_e( "Subscription updates, allow you to change the member's subscription values at predefined times. Be sure to click Update User after making changes.", 'paid-memberships-pro' );
|
1112 |
-
}
|
1113 |
-
?>
|
1114 |
-
</p>
|
1115 |
-
<table class="form-table">
|
1116 |
-
<tr>
|
1117 |
-
<th><label for="membership_level"><?php _e( "Update", 'paid-memberships-pro' ); ?></label></th>
|
1118 |
-
<td id="updates_td">
|
1119 |
-
<?php
|
1120 |
-
$old_updates = $user->pmpro_stripe_updates;
|
1121 |
-
if ( is_array( $old_updates ) ) {
|
1122 |
-
$updates = array_merge(
|
1123 |
-
array(
|
1124 |
-
array(
|
1125 |
-
'template' => true,
|
1126 |
-
'when' => 'now',
|
1127 |
-
'date_month' => '',
|
1128 |
-
'date_day' => '',
|
1129 |
-
'date_year' => '',
|
1130 |
-
'billing_amount' => '',
|
1131 |
-
'cycle_number' => '',
|
1132 |
-
'cycle_period' => 'Month'
|
1133 |
-
)
|
1134 |
-
),
|
1135 |
-
$old_updates
|
1136 |
-
);
|
1137 |
-
} else {
|
1138 |
-
$updates = array(
|
1139 |
-
array(
|
1140 |
-
'template' => true,
|
1141 |
-
'when' => 'now',
|
1142 |
-
'date_month' => '',
|
1143 |
-
'date_day' => '',
|
1144 |
-
'date_year' => '',
|
1145 |
-
'billing_amount' => '',
|
1146 |
-
'cycle_number' => '',
|
1147 |
-
'cycle_period' => 'Month'
|
1148 |
-
)
|
1149 |
-
);
|
1150 |
-
}
|
1151 |
-
|
1152 |
-
foreach ( $updates as $update ) {
|
1153 |
-
?>
|
1154 |
-
<div class="updates_update"
|
1155 |
-
<?php if ( ! empty( $update['template'] ) ) { ?>style="display: none;"<?php } ?>>
|
1156 |
-
<select class="updates_when" name="updates_when[]">
|
1157 |
-
<option value="now" <?php selected( $update['when'], "now" ); ?>>Now</option>
|
1158 |
-
<option value="payment" <?php selected( $update['when'], "payment" ); ?>>After
|
1159 |
-
Next Payment
|
1160 |
-
</option>
|
1161 |
-
<option value="date" <?php selected( $update['when'], "date" ); ?>>On Date
|
1162 |
-
</option>
|
1163 |
-
</select>
|
1164 |
-
<span class="updates_date"
|
1165 |
-
<?php if ( $update['when'] != "date" ) { ?>style="display: none;"<?php } ?>>
|
1166 |
-
<select name="updates_date_month[]">
|
1167 |
-
<?php
|
1168 |
-
for ( $i = 1; $i < 13; $i ++ ) {
|
1169 |
-
?>
|
1170 |
-
<option value="<?php echo str_pad( $i, 2, "0", STR_PAD_LEFT ); ?>"
|
1171 |
-
<?php if ( ! empty( $update['date_month'] ) && $update['date_month'] == $i ) { ?>selected="selected"<?php } ?>>
|
1172 |
-
<?php echo date_i18n( "M", strtotime( $i . "/15/" . $current_year ) ); ?>
|
1173 |
-
</option>
|
1174 |
-
<?php
|
1175 |
-
}
|
1176 |
-
?>
|
1177 |
-
</select>
|
1178 |
-
<input name="updates_date_day[]" type="text" size="2"
|
1179 |
-
value="<?php if ( ! empty( $update['date_day'] ) ) {
|
1180 |
-
echo esc_attr( $update['date_day'] );
|
1181 |
-
} ?>"/>
|
1182 |
-
<input name="updates_date_year[]" type="text" size="4"
|
1183 |
-
value="<?php if ( ! empty( $update['date_year'] ) ) {
|
1184 |
-
echo esc_attr( $update['date_year'] );
|
1185 |
-
} ?>"/>
|
1186 |
-
</span>
|
1187 |
-
<span class="updates_billing"
|
1188 |
-
<?php if ( $update['when'] == "now" ) { ?>style="display: none;"<?php } ?>>
|
1189 |
-
<?php echo $pmpro_currency_symbol ?><input name="updates_billing_amount[]" type="text"
|
1190 |
-
size="10"
|
1191 |
-
value="<?php echo esc_attr( $update['billing_amount'] ); ?>"/>
|
1192 |
-
<small><?php _e( 'per', 'paid-memberships-pro' ); ?></small>
|
1193 |
-
<input name="updates_cycle_number[]" type="text" size="5"
|
1194 |
-
value="<?php echo esc_attr( $update['cycle_number'] ); ?>"/>
|
1195 |
-
<select name="updates_cycle_period[]">
|
1196 |
-
<?php
|
1197 |
-
foreach ( $cycles as $name => $value ) {
|
1198 |
-
echo "<option value='$value'";
|
1199 |
-
if ( ! empty( $update['cycle_period'] ) && $update['cycle_period'] == $value ) {
|
1200 |
-
echo " selected='selected'";
|
1201 |
-
}
|
1202 |
-
echo ">$name</option>";
|
1203 |
-
}
|
1204 |
-
?>
|
1205 |
-
</select>
|
1206 |
-
</span>
|
1207 |
-
<span>
|
1208 |
-
<a class="updates_remove" href="javascript:void(0);">Remove</a>
|
1209 |
-
</span>
|
1210 |
-
</div>
|
1211 |
-
<?php
|
1212 |
-
}
|
1213 |
-
?>
|
1214 |
-
<p><a id="updates_new_update" href="javascript:void(0);">+ New Update</a></p>
|
1215 |
-
</td>
|
1216 |
-
</tr>
|
1217 |
-
</table>
|
1218 |
-
<script>
|
1219 |
-
<!--
|
1220 |
-
jQuery(document).ready(function () {
|
1221 |
-
//function to update dropdowns/etc based on when field
|
1222 |
-
function updateSubscriptionUpdateFields(when) {
|
1223 |
-
if (jQuery(when).val() == 'date')
|
1224 |
-
jQuery(when).parent().children('.updates_date').show();
|
1225 |
-
else
|
1226 |
-
jQuery(when).parent().children('.updates_date').hide();
|
1227 |
-
|
1228 |
-
if (jQuery(when).val() == 'no')
|
1229 |
-
jQuery(when).parent().children('.updates_billing').hide();
|
1230 |
-
else
|
1231 |
-
jQuery(when).parent().children('.updates_billing').show();
|
1232 |
-
}
|
1233 |
-
|
1234 |
-
//and update on page load
|
1235 |
-
jQuery('.updates_when').each(function () {
|
1236 |
-
if (jQuery(this).parent().css('display') != 'none') updateSubscriptionUpdateFields(this);
|
1237 |
-
});
|
1238 |
-
|
1239 |
-
//add a new update when clicking to
|
1240 |
-
var num_updates_divs = <?php echo count( $updates );?>;
|
1241 |
-
jQuery('#updates_new_update').click(function () {
|
1242 |
-
//get updates
|
1243 |
-
updates = jQuery('.updates_update').toArray();
|
1244 |
-
|
1245 |
-
//clone the first one
|
1246 |
-
new_div = jQuery(updates[0]).clone();
|
1247 |
-
|
1248 |
-
//append
|
1249 |
-
new_div.insertBefore('#updates_new_update');
|
1250 |
-
|
1251 |
-
//update events
|
1252 |
-
addUpdateEvents()
|
1253 |
-
|
1254 |
-
//unhide it
|
1255 |
-
new_div.show();
|
1256 |
-
updateSubscriptionUpdateFields(new_div.children('.updates_when'));
|
1257 |
-
});
|
1258 |
-
|
1259 |
-
function addUpdateEvents() {
|
1260 |
-
//update when when changes
|
1261 |
-
jQuery('.updates_when').change(function () {
|
1262 |
-
updateSubscriptionUpdateFields(this);
|
1263 |
-
});
|
1264 |
-
|
1265 |
-
//remove updates when clicking
|
1266 |
-
jQuery('.updates_remove').click(function () {
|
1267 |
-
jQuery(this).parent().parent().remove();
|
1268 |
-
});
|
1269 |
-
}
|
1270 |
-
|
1271 |
-
addUpdateEvents();
|
1272 |
-
});
|
1273 |
-
-->
|
1274 |
-
</script>
|
1275 |
-
<?php
|
1276 |
-
}
|
1277 |
-
}
|
1278 |
|
1279 |
/**
|
1280 |
-
*
|
|
|
1281 |
*
|
1282 |
-
* @since
|
1283 |
*/
|
1284 |
static function user_profile_fields_save( $user_id ) {
|
1285 |
global $wpdb;
|
1286 |
-
|
1287 |
//check capabilities
|
1288 |
$membership_level_capability = apply_filters( "pmpro_edit_member_capability", "manage_options" );
|
1289 |
if ( ! current_user_can( $membership_level_capability ) ) {
|
1290 |
return false;
|
1291 |
}
|
1292 |
|
1293 |
-
//make sure
|
|
|
|
|
|
|
|
|
|
|
1294 |
if ( ! isset( $_POST['updates_when'] ) || ! is_array( $_POST['updates_when'] ) ) {
|
|
|
|
|
1295 |
return;
|
1296 |
}
|
1297 |
|
@@ -1299,8 +881,8 @@ class PMProGateway_stripe extends PMProGateway {
|
|
1299 |
$updates = array();
|
1300 |
$next_on_date_update = "";
|
1301 |
|
1302 |
-
//build array of updates
|
1303 |
-
for ( $i =
|
1304 |
$update = array();
|
1305 |
|
1306 |
//all updates have these values
|
@@ -1327,7 +909,7 @@ class PMProGateway_stripe extends PMProGateway {
|
|
1327 |
|
1328 |
//if when is now, update the subscription
|
1329 |
if ( $update['when'] == "now" ) {
|
1330 |
-
|
1331 |
|
1332 |
continue;
|
1333 |
} elseif ( $update['when'] == 'date' ) {
|
@@ -1352,27 +934,36 @@ class PMProGateway_stripe extends PMProGateway {
|
|
1352 |
/**
|
1353 |
* Cron activation for subscription updates.
|
1354 |
*
|
|
|
|
|
|
|
1355 |
* @since 1.8
|
1356 |
*/
|
1357 |
-
static function pmpro_activation() {
|
1358 |
pmpro_maybe_schedule_event( time(), 'daily', 'pmpro_cron_stripe_subscription_updates' );
|
1359 |
}
|
1360 |
|
1361 |
/**
|
1362 |
* Cron deactivation for subscription updates.
|
1363 |
*
|
|
|
|
|
|
|
1364 |
* @since 1.8
|
1365 |
*/
|
1366 |
-
static function pmpro_deactivation() {
|
1367 |
wp_clear_scheduled_hook( 'pmpro_cron_stripe_subscription_updates' );
|
1368 |
}
|
1369 |
|
1370 |
/**
|
1371 |
* Cron job for subscription updates.
|
1372 |
*
|
|
|
|
|
|
|
1373 |
* @since 1.8
|
1374 |
*/
|
1375 |
-
static function pmpro_cron_stripe_subscription_updates() {
|
1376 |
global $wpdb;
|
1377 |
|
1378 |
//get all updates for today (or before today)
|
@@ -1409,7 +1000,7 @@ class PMProGateway_stripe extends PMProGateway {
|
|
1409 |
if ( $ud['when'] == 'date' &&
|
1410 |
$ud['date_year'] . "-" . $ud['date_month'] . "-" . $ud['date_day'] <= date_i18n( "Y-m-d", current_time( 'timestamp' ) )
|
1411 |
) {
|
1412 |
-
|
1413 |
|
1414 |
//remove update from list
|
1415 |
unset( $user_updates[ $key ] );
|
@@ -1439,7 +1030,7 @@ class PMProGateway_stripe extends PMProGateway {
|
|
1439 |
* because of an expired credit card/etc and a user checks out to renew their subscription
|
1440 |
* instead of updating their billing information via the billing info page.
|
1441 |
*/
|
1442 |
-
static function pmpro_checkout_before_processing() {
|
1443 |
global $wpdb, $current_user;
|
1444 |
|
1445 |
// we're only worried about cases where the user is logged in
|
@@ -1483,7 +1074,7 @@ class PMProGateway_stripe extends PMProGateway {
|
|
1483 |
|
1484 |
//so let's cancel the user's susbcription
|
1485 |
if ( ! empty( $last_order ) && ! empty( $last_order->subscription_transaction_id ) ) {
|
1486 |
-
$subscription = $last_order->Gateway->
|
1487 |
if ( ! empty( $subscription ) ) {
|
1488 |
$last_order->Gateway->cancelSubscriptionAtGateway( $subscription, true );
|
1489 |
|
@@ -1514,413 +1105,544 @@ class PMProGateway_stripe extends PMProGateway {
|
|
1514 |
}
|
1515 |
|
1516 |
/**
|
1517 |
-
*
|
1518 |
-
*
|
1519 |
-
* @since 1.
|
1520 |
*/
|
1521 |
-
function
|
1522 |
-
|
1523 |
-
|
1524 |
-
|
1525 |
-
|
1526 |
-
|
1527 |
-
'process_subscriptions',
|
1528 |
-
);
|
1529 |
|
1530 |
-
|
1531 |
-
|
1532 |
-
|
1533 |
-
|
1534 |
-
|
1535 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1536 |
}
|
1537 |
}
|
1538 |
|
1539 |
-
|
1540 |
-
$order->status = 'success';
|
1541 |
-
$order->saveOrder();
|
1542 |
-
|
1543 |
-
return true;
|
1544 |
}
|
1545 |
|
1546 |
-
|
1547 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1548 |
*
|
1549 |
-
* @
|
1550 |
*/
|
1551 |
-
function
|
1552 |
-
|
1553 |
-
|
|
|
|
|
1554 |
|
1555 |
-
//
|
1556 |
-
if (
|
1557 |
-
|
1558 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1559 |
|
1560 |
-
|
1561 |
-
|
1562 |
-
|
|
|
|
|
|
|
1563 |
}
|
1564 |
|
1565 |
-
|
1566 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1567 |
|
1568 |
-
|
1569 |
-
|
1570 |
-
|
1571 |
-
|
|
|
|
|
|
|
1572 |
|
1573 |
-
|
1574 |
-
|
|
|
|
|
|
|
|
|
|
|
1575 |
|
1576 |
-
|
1577 |
-
|
1578 |
return false;
|
1579 |
}
|
1580 |
|
1581 |
-
//
|
1582 |
-
|
1583 |
-
|
1584 |
-
|
1585 |
-
|
1586 |
-
"customer" => $this->customer->id,
|
1587 |
-
"description" => apply_filters( 'pmpro_stripe_order_description', "Order #" . $order->code . ", " . trim( $order->FirstName . " " . $order->LastName ) . " (" . $order->Email . ")", $order )
|
1588 |
-
);
|
1589 |
-
/**
|
1590 |
-
* Filter params used to create the Stripe charge.
|
1591 |
-
*
|
1592 |
-
* @since 2.4.4
|
1593 |
-
*
|
1594 |
-
* @param array $params Array of params sent to Stripe.
|
1595 |
-
* @param object $order Order object for this checkout.
|
1596 |
-
*/
|
1597 |
-
$params = apply_filters( 'pmpro_stripe_charge_params', $params, $order );
|
1598 |
-
$response = Stripe_Charge::create( $params );
|
1599 |
-
} catch ( \Throwable $e ) {
|
1600 |
-
//$order->status = "error";
|
1601 |
-
$order->errorcode = true;
|
1602 |
-
$order->error = "Error: " . $e->getMessage();
|
1603 |
-
$order->shorterror = $order->error;
|
1604 |
|
1605 |
-
|
1606 |
-
|
1607 |
-
|
1608 |
-
|
1609 |
-
|
1610 |
-
|
1611 |
|
1612 |
-
|
1613 |
-
}
|
1614 |
|
1615 |
-
|
1616 |
-
//successful charge
|
1617 |
-
$order->payment_transaction_id = $response["id"];
|
1618 |
-
$order->updateStatus( "success" );
|
1619 |
-
$order->saveOrder();
|
1620 |
|
1621 |
-
|
|
|
|
|
|
|
|
|
1622 |
} else {
|
1623 |
-
|
1624 |
-
|
1625 |
-
|
1626 |
-
|
1627 |
-
|
1628 |
-
return false;
|
1629 |
}
|
1630 |
}
|
1631 |
|
1632 |
/**
|
1633 |
-
*
|
1634 |
*
|
1635 |
-
*
|
1636 |
-
* It first checks if the order has a subscription_transaction_id. If so, that's the customer id.
|
1637 |
-
* If not, it checks for a user_id on the order and searches for a customer id in the user meta.
|
1638 |
-
* If a customer id is found, it checks for a customer through the Stripe API.
|
1639 |
-
* If a customer is found and there is a stripeToken on the order passed, it will update the customer.
|
1640 |
-
* If no customer is found and there is a stripeToken on the order passed, it will create a customer.
|
1641 |
-
*
|
1642 |
-
* @return Stripe_Customer|false
|
1643 |
-
* @since 1.4
|
1644 |
*/
|
1645 |
-
function
|
1646 |
-
|
|
|
|
|
1647 |
|
1648 |
-
|
1649 |
-
|
1650 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1651 |
}
|
1652 |
|
1653 |
-
|
1654 |
-
|
1655 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1656 |
}
|
|
|
1657 |
|
1658 |
-
|
1659 |
-
|
1660 |
-
|
1661 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1662 |
|
1663 |
-
|
1664 |
-
if ( empty( $user_id ) && ! empty( $current_user->ID ) ) {
|
1665 |
-
$user_id = $current_user->ID;
|
1666 |
-
}
|
1667 |
|
1668 |
-
|
1669 |
-
$
|
1670 |
-
|
1671 |
-
$user = null;
|
1672 |
-
}
|
1673 |
|
1674 |
-
|
1675 |
-
|
1676 |
-
$customer_id = $order->subscription_transaction_id;
|
1677 |
-
} else {
|
1678 |
-
//try based on user id
|
1679 |
-
if ( ! empty( $user_id ) ) {
|
1680 |
-
$customer_id = get_user_meta( $user_id, "pmpro_stripe_customerid", true );
|
1681 |
}
|
1682 |
|
1683 |
-
|
1684 |
-
|
1685 |
-
if ( ! empty( $order->payment_transaction_id ) ) {
|
1686 |
-
$payment_transaction_id = $order->payment_transaction_id;
|
1687 |
-
} else {
|
1688 |
-
//find the user's last stripe order
|
1689 |
-
$last_order = new MemberOrder();
|
1690 |
-
$last_order->getLastMemberOrder( $user_id, array(
|
1691 |
-
'success',
|
1692 |
-
'cancelled'
|
1693 |
-
), null, 'stripe', $order->Gateway->gateway_environment );
|
1694 |
-
if ( ! empty( $last_order->payment_transaction_id ) ) {
|
1695 |
-
$payment_transaction_id = $last_order->payment_transaction_id;
|
1696 |
-
}
|
1697 |
-
}
|
1698 |
-
|
1699 |
-
//we have a transaction id to look up
|
1700 |
-
if ( ! empty( $payment_transaction_id ) ) {
|
1701 |
-
if ( strpos( $payment_transaction_id, "ch_" ) !== false ) {
|
1702 |
-
//charge, look it up
|
1703 |
-
try {
|
1704 |
-
$charge = Stripe_Charge::retrieve( $payment_transaction_id );
|
1705 |
-
} catch ( \Throwable $e ) {
|
1706 |
-
$order->error = sprintf( __( 'Error: %s', 'paid-memberships-pro' ), $e->getMessage() );
|
1707 |
-
|
1708 |
-
return false;
|
1709 |
-
} catch ( \Exception $e ) {
|
1710 |
-
$order->error = sprintf( __( 'Error: %s', 'paid-memberships-pro' ), $e->getMessage() );
|
1711 |
|
1712 |
-
|
1713 |
-
}
|
1714 |
|
1715 |
-
|
1716 |
-
|
1717 |
-
|
1718 |
-
|
1719 |
-
|
1720 |
-
try {
|
1721 |
-
$invoice = Stripe_Invoice::retrieve( $payment_transaction_id );
|
1722 |
-
} catch ( \Throwable $e ) {
|
1723 |
-
$order->error = sprintf( __( 'Error: %s', 'paid-memberships-pro' ), $e->getMessage() );
|
1724 |
-
|
1725 |
-
return false;
|
1726 |
-
} catch ( \Exception $e ) {
|
1727 |
-
$order->error = sprintf( __( 'Error: %s', 'paid-memberships-pro' ), $e->getMessage() );
|
1728 |
-
|
1729 |
-
return false;
|
1730 |
-
}
|
1731 |
|
1732 |
-
|
1733 |
-
|
1734 |
-
|
1735 |
-
}
|
1736 |
}
|
1737 |
|
1738 |
-
|
1739 |
-
if ( ! empty( $customer_id ) ) {
|
1740 |
-
update_user_meta( $user_id, "pmpro_stripe_customerid", $customer_id );
|
1741 |
-
}
|
1742 |
}
|
1743 |
}
|
1744 |
|
1745 |
-
|
1746 |
-
if ( ! empty( $order->FirstName ) && ! empty( $order->LastName ) ) {
|
1747 |
-
$name = trim( $order->FirstName . " " . $order->LastName );
|
1748 |
-
} elseif ( ! empty( $order->FirstName ) ) {
|
1749 |
-
$name = $order->FirstName;
|
1750 |
-
} elseif ( ! empty( $order->LastName ) ) {
|
1751 |
-
$name = $order->LastName;
|
1752 |
-
}
|
1753 |
|
1754 |
-
|
1755 |
-
|
1756 |
|
1757 |
-
|
1758 |
-
|
1759 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1760 |
}
|
1761 |
-
|
1762 |
-
$
|
1763 |
-
}
|
1764 |
-
|
1765 |
-
if ( ! empty( $order->Email ) ) {
|
1766 |
-
$email = $order->Email;
|
1767 |
} else {
|
1768 |
-
|
1769 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1770 |
|
1771 |
-
|
1772 |
-
|
1773 |
-
|
1774 |
-
|
1775 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1776 |
|
1777 |
-
|
1778 |
-
|
1779 |
-
|
1780 |
-
|
1781 |
-
|
1782 |
-
|
1783 |
-
$this->customer->description = $name . " (" . $email . ")";
|
1784 |
-
$this->customer->email = $email;
|
1785 |
-
$this->customer->save();
|
1786 |
}
|
1787 |
|
1788 |
-
|
1789 |
-
|
1790 |
-
|
1791 |
-
|
1792 |
-
|
1793 |
-
|
1794 |
-
|
1795 |
-
if ( ! function_exists( 'pmpro_user_register_stripe_customerid' ) ) {
|
1796 |
-
function pmpro_user_register_stripe_customerid( $user_id ) {
|
1797 |
-
global $pmpro_stripe_customer_id;
|
1798 |
-
update_user_meta( $user_id, "pmpro_stripe_customerid", $pmpro_stripe_customer_id );
|
1799 |
-
}
|
1800 |
|
1801 |
-
|
1802 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1803 |
}
|
1804 |
|
1805 |
-
|
1806 |
-
|
1807 |
-
|
1808 |
-
|
1809 |
-
//assume no customer found
|
1810 |
}
|
1811 |
-
}
|
1812 |
|
1813 |
-
|
1814 |
-
|
1815 |
-
|
1816 |
-
|
1817 |
-
|
1818 |
-
|
1819 |
-
|
1820 |
-
|
1821 |
-
|
1822 |
-
$order->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1823 |
|
1824 |
-
|
1825 |
-
|
1826 |
-
|
1827 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1828 |
|
1829 |
-
|
1830 |
-
|
1831 |
-
|
1832 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1833 |
|
1834 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1835 |
}
|
1836 |
|
1837 |
-
|
1838 |
-
|
1839 |
-
|
1840 |
-
|
1841 |
-
|
1842 |
-
|
1843 |
-
$
|
1844 |
-
|
1845 |
-
|
1846 |
-
|
1847 |
-
|
1848 |
-
|
|
|
1849 |
|
1850 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1851 |
}
|
1852 |
}
|
1853 |
|
1854 |
-
|
|
|
|
|
1855 |
}
|
1856 |
|
1857 |
-
return
|
1858 |
}
|
1859 |
|
1860 |
/**
|
1861 |
-
*
|
1862 |
*
|
1863 |
-
* @since
|
|
|
|
|
|
|
1864 |
*/
|
1865 |
-
function
|
1866 |
-
|
1867 |
-
|
1868 |
-
//no order?
|
1869 |
-
if ( empty( $order ) || empty( $order->code ) ) {
|
1870 |
-
return false;
|
1871 |
-
}
|
1872 |
-
|
1873 |
-
$result = $this->getCustomer( $order, true ); //force so we don't get a cached sub for someone else
|
1874 |
-
|
1875 |
-
//no customer?
|
1876 |
-
if ( empty( $result ) ) {
|
1877 |
-
return false;
|
1878 |
-
}
|
1879 |
|
1880 |
-
|
1881 |
-
|
1882 |
return false;
|
1883 |
}
|
1884 |
|
1885 |
-
//
|
1886 |
-
|
1887 |
-
try {
|
1888 |
-
$sub = $this->customer->subscriptions->retrieve( $order->subscription_transaction_id );
|
1889 |
-
} catch ( \Throwable $e ) {
|
1890 |
-
$order->error = __( "Error getting subscription with Stripe:", 'paid-memberships-pro' ) . $e->getMessage();
|
1891 |
-
$order->shorterror = $order->error;
|
1892 |
-
|
1893 |
-
return false;
|
1894 |
-
} catch ( \Exception $e ) {
|
1895 |
-
$order->error = __( "Error getting subscription with Stripe:", 'paid-memberships-pro' ) . $e->getMessage();
|
1896 |
-
$order->shorterror = $order->error;
|
1897 |
-
|
1898 |
-
return false;
|
1899 |
-
}
|
1900 |
|
1901 |
-
|
|
|
|
|
|
|
|
|
1902 |
}
|
1903 |
|
1904 |
-
//
|
1905 |
-
$
|
|
|
|
|
|
|
1906 |
|
1907 |
-
//
|
1908 |
-
if (
|
1909 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1910 |
}
|
1911 |
|
1912 |
-
|
1913 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1914 |
|
1915 |
-
//
|
1916 |
-
|
1917 |
-
|
1918 |
-
|
1919 |
-
|
|
|
|
|
1920 |
}
|
1921 |
-
|
1922 |
-
//didn't find anything yet
|
1923 |
-
return false;
|
1924 |
}
|
1925 |
|
1926 |
/**
|
@@ -1928,8 +1650,8 @@ class PMProGateway_stripe extends PMProGateway {
|
|
1928 |
*
|
1929 |
* @since 2.3
|
1930 |
*/
|
1931 |
-
function getSubscriptionStatus( &$order ) {
|
1932 |
-
$subscription = $this->
|
1933 |
|
1934 |
if ( ! empty( $subscription ) ) {
|
1935 |
return $subscription->status;
|
@@ -1939,222 +1661,1338 @@ class PMProGateway_stripe extends PMProGateway {
|
|
1939 |
}
|
1940 |
|
1941 |
/**
|
1942 |
-
*
|
1943 |
*
|
1944 |
* @since 1.4
|
1945 |
*/
|
1946 |
-
function
|
1947 |
-
|
1948 |
-
|
1949 |
-
|
1950 |
-
|
1951 |
-
|
1952 |
-
if ( is_array( $pmpro_currencies[ $pmpro_currency ] ) && isset( $pmpro_currencies[ $pmpro_currency ]['decimals'] ) && $pmpro_currencies[ $pmpro_currency ]['decimals'] == 0 ) {
|
1953 |
-
$currency_unit_multiplier = 1;
|
1954 |
}
|
1955 |
|
1956 |
-
|
1957 |
-
if ( empty( $
|
1958 |
-
|
|
|
|
|
|
|
1959 |
}
|
1960 |
|
1961 |
-
|
1962 |
-
|
1963 |
-
|
1964 |
-
|
1965 |
-
|
1966 |
-
|
1967 |
-
} else {
|
1968 |
-
global $current_user;
|
1969 |
-
$user_id = $current_user->ID;
|
1970 |
}
|
1971 |
|
1972 |
-
|
1973 |
-
|
1974 |
-
|
1975 |
-
|
1976 |
-
return false; //error retrieving customer
|
1977 |
}
|
1978 |
|
1979 |
-
|
1980 |
-
|
1981 |
-
$order->subscription_transaction_id = $this->customer['id']; //transaction id is the customer id, we save it in user meta later too
|
1982 |
|
1983 |
-
|
1984 |
-
|
1985 |
-
|
1986 |
-
|
|
|
|
|
|
|
1987 |
|
1988 |
-
|
1989 |
-
|
1990 |
-
|
1991 |
-
|
1992 |
|
1993 |
-
|
1994 |
-
|
1995 |
-
|
1996 |
-
if ( $order->BillingPeriod == "Year" ) {
|
1997 |
-
$trial_period_days = $order->BillingFrequency * 365; //annual
|
1998 |
-
} elseif ( $order->BillingPeriod == "Day" ) {
|
1999 |
-
$trial_period_days = $order->BillingFrequency * 1; //daily
|
2000 |
-
} elseif ( $order->BillingPeriod == "Week" ) {
|
2001 |
-
$trial_period_days = $order->BillingFrequency * 7; //weekly
|
2002 |
-
} else {
|
2003 |
-
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
2004 |
}
|
2005 |
|
2006 |
-
//
|
2007 |
-
$
|
2008 |
|
2009 |
-
|
2010 |
-
|
|
|
2011 |
|
2012 |
-
|
2013 |
-
|
|
|
|
|
|
|
|
|
|
|
2014 |
|
2015 |
-
|
2016 |
-
|
2017 |
-
$trialOccurrences = (int) $order->TrialBillingCycles;
|
2018 |
-
if ( $order->BillingPeriod == "Year" ) {
|
2019 |
-
$trial_period_days = $trial_period_days + ( 365 * $order->BillingFrequency * $trialOccurrences ); //annual
|
2020 |
-
} elseif ( $order->BillingPeriod == "Day" ) {
|
2021 |
-
$trial_period_days = $trial_period_days + ( 1 * $order->BillingFrequency * $trialOccurrences ); //daily
|
2022 |
-
} elseif ( $order->BillingPeriod == "Week" ) {
|
2023 |
-
$trial_period_days = $trial_period_days + ( 7 * $order->BillingFrequency * $trialOccurrences ); //weekly
|
2024 |
-
} else {
|
2025 |
-
$trial_period_days = $trial_period_days + ( 30 * $order->BillingFrequency * $trialOccurrences ); //assume monthly
|
2026 |
}
|
2027 |
-
} elseif ( ! empty( $order->TrialBillingCycles ) ) {
|
2028 |
-
/*
|
2029 |
-
Let's set the subscription to the trial and give the user an "update" to change the sub later to full price (since v2.0)
|
2030 |
|
2031 |
-
|
|
|
2032 |
*/
|
2033 |
-
$
|
2034 |
-
|
2035 |
-
|
2036 |
-
'billing_amount' => $order->PaymentAmount,
|
2037 |
-
'cycle_period' => $order->BillingPeriod,
|
2038 |
-
'cycle_number' => $order->BillingFrequency
|
2039 |
-
);
|
2040 |
-
|
2041 |
-
//now amount to equal the trial #s
|
2042 |
-
$amount = $order->TrialAmount;
|
2043 |
-
$amount_tax = $order->getTaxForPrice( $amount );
|
2044 |
-
$amount = pmpro_round_price( (float) $amount + (float) $amount_tax );
|
2045 |
-
}
|
2046 |
-
|
2047 |
-
//create a plan
|
2048 |
-
try {
|
2049 |
-
$plan = array(
|
2050 |
-
"amount" => $amount * $currency_unit_multiplier,
|
2051 |
-
"interval_count" => $order->BillingFrequency,
|
2052 |
-
"interval" => strtolower( $order->BillingPeriod ),
|
2053 |
-
"trial_period_days" => $trial_period_days,
|
2054 |
-
'product' => array( 'name' => $order->membership_name . " for order " . $order->code ),
|
2055 |
-
"currency" => strtolower( $pmpro_currency ),
|
2056 |
-
"id" => $order->code
|
2057 |
-
);
|
2058 |
-
|
2059 |
-
$plan = Stripe_Plan::create( apply_filters( 'pmpro_stripe_create_plan_array', $plan ) );
|
2060 |
-
} catch ( \Throwable $e ) {
|
2061 |
-
$order->error = __( "Error creating plan with Stripe:", 'paid-memberships-pro' ) . $e->getMessage();
|
2062 |
-
$order->shorterror = $order->error;
|
2063 |
|
2064 |
-
return
|
2065 |
-
}
|
2066 |
-
$order->error = __( "
|
2067 |
$order->shorterror = $order->error;
|
2068 |
|
2069 |
-
return false;
|
2070 |
}
|
|
|
2071 |
|
2072 |
-
// before subscribing, let's clear out the updates so we don't trigger any during sub
|
2073 |
-
if ( ! empty( $user_id ) ) {
|
2074 |
-
$old_user_updates = get_user_meta( $user_id, "pmpro_stripe_updates", true );
|
2075 |
-
update_user_meta( $user_id, "pmpro_stripe_updates", array() );
|
2076 |
-
}
|
2077 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2078 |
|
2079 |
-
|
2080 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2081 |
}
|
2082 |
|
2083 |
-
|
2084 |
-
|
2085 |
-
|
2086 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2087 |
} catch ( \Throwable $e ) {
|
2088 |
-
//
|
2089 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2090 |
|
2091 |
-
|
2092 |
-
|
2093 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2094 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2095 |
|
2096 |
-
|
2097 |
-
|
2098 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2099 |
|
2100 |
-
|
2101 |
-
|
2102 |
-
|
2103 |
-
|
2104 |
|
2105 |
-
|
2106 |
-
|
2107 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2108 |
}
|
|
|
|
|
|
|
2109 |
|
2110 |
-
|
2111 |
-
$
|
2112 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2113 |
|
|
|
|
|
2114 |
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2115 |
}
|
2116 |
|
2117 |
-
|
2118 |
-
|
2119 |
-
$plan->delete();
|
2120 |
|
2121 |
-
|
2122 |
-
|
2123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2124 |
|
2125 |
-
//
|
2126 |
-
|
2127 |
-
//empty out updates unless set above
|
2128 |
-
if ( empty( $new_user_updates ) ) {
|
2129 |
-
$new_user_updates = array();
|
2130 |
-
}
|
2131 |
|
2132 |
-
|
2133 |
-
|
2134 |
-
|
2135 |
-
|
2136 |
-
//need to remember the user updates to save later
|
2137 |
-
global $pmpro_stripe_updates;
|
2138 |
-
$pmpro_stripe_updates = $new_user_updates;
|
2139 |
-
function pmpro_user_register_stripe_updates( $user_id ) {
|
2140 |
-
global $pmpro_stripe_updates;
|
2141 |
-
update_user_meta( $user_id, "pmpro_stripe_updates", $pmpro_stripe_updates );
|
2142 |
-
}
|
2143 |
|
2144 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2145 |
}
|
2146 |
-
|
2147 |
-
//give them their old updates back
|
2148 |
-
update_user_meta( $user_id, "pmpro_stripe_updates", $old_user_updates );
|
2149 |
}
|
|
|
|
|
2150 |
|
2151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2152 |
}
|
2153 |
|
2154 |
/**
|
2155 |
* Helper method to save the subscription ID to make sure the membership doesn't get cancelled by the webhook
|
|
|
|
|
2156 |
*/
|
2157 |
-
static function ignoreCancelWebhookForThisSubscription( $subscription_id, $user_id = null ) {
|
|
|
|
|
2158 |
if ( empty( $user_id ) ) {
|
2159 |
global $current_user;
|
2160 |
$user_id = $current_user->ID;
|
@@ -2174,9 +3012,14 @@ class PMProGateway_stripe extends PMProGateway {
|
|
2174 |
}
|
2175 |
|
2176 |
/**
|
2177 |
-
* Helper method to process a Stripe subscription update
|
|
|
|
|
|
|
|
|
2178 |
*/
|
2179 |
static function updateSubscription( $update, $user_id ) {
|
|
|
2180 |
global $wpdb;
|
2181 |
|
2182 |
//get level for user
|
@@ -2186,9 +3029,9 @@ class PMProGateway_stripe extends PMProGateway {
|
|
2186 |
$last_order = new MemberOrder();
|
2187 |
$last_order->getLastMemberOrder( $user_id );
|
2188 |
$last_order->setGateway( 'stripe' );
|
2189 |
-
$last_order->Gateway->
|
2190 |
|
2191 |
-
$subscription = $last_order->Gateway->
|
2192 |
|
2193 |
if ( ! empty( $subscription ) ) {
|
2194 |
$end_timestamp = $subscription->current_period_end;
|
@@ -2236,7 +3079,8 @@ class PMProGateway_stripe extends PMProGateway {
|
|
2236 |
}, 10, 2 );
|
2237 |
|
2238 |
//update subscription
|
2239 |
-
$update_order->Gateway->
|
|
|
2240 |
$update_order->Gateway->process_subscriptions( $update_order );
|
2241 |
|
2242 |
//update membership
|
@@ -2260,46 +3104,27 @@ class PMProGateway_stripe extends PMProGateway {
|
|
2260 |
}
|
2261 |
|
2262 |
/**
|
2263 |
-
*
|
2264 |
*
|
2265 |
-
*
|
|
|
|
|
|
|
|
|
2266 |
*/
|
2267 |
-
function
|
2268 |
-
|
2269 |
-
$steps = array(
|
2270 |
-
'set_customer',
|
2271 |
-
'set_payment_method',
|
2272 |
-
'attach_payment_method_to_customer',
|
2273 |
-
'update_payment_method_for_subscriptions',
|
2274 |
-
);
|
2275 |
-
|
2276 |
-
foreach ( $steps as $key => $step ) {
|
2277 |
-
do_action( "pmpro_update_billing_before_{$step}", $order );
|
2278 |
-
$this->$step( $order );
|
2279 |
-
do_action( "pmpro_update_billing_after_{$step}", $order );
|
2280 |
-
if ( ! empty( $order->error ) ) {
|
2281 |
-
return false;
|
2282 |
-
}
|
2283 |
-
}
|
2284 |
-
|
2285 |
-
return true;
|
2286 |
|
2287 |
-
}
|
2288 |
-
|
2289 |
-
/**
|
2290 |
-
* Update the payment method for a subscription.
|
2291 |
-
*/
|
2292 |
-
function update_payment_method_for_subscriptions( &$order ) {
|
2293 |
// get customer
|
2294 |
-
$this->
|
2295 |
|
2296 |
-
if ( empty( $
|
2297 |
return false;
|
2298 |
}
|
2299 |
|
2300 |
// get all subscriptions
|
2301 |
-
if ( ! empty( $
|
2302 |
-
$subscriptions = $
|
2303 |
}
|
2304 |
|
2305 |
foreach( $subscriptions as $subscription ) {
|
@@ -2309,77 +3134,28 @@ class PMProGateway_stripe extends PMProGateway {
|
|
2309 |
}
|
2310 |
|
2311 |
// check if we have a related order for it
|
2312 |
-
$one_order = new MemberOrder();
|
2313 |
-
$one_order->getLastMemberOrderBySubscriptionTransactionID( $subscription->id );
|
2314 |
-
if ( empty( $one_order ) || empty( $one_order->id ) ) {
|
2315 |
-
continue;
|
2316 |
-
}
|
2317 |
-
|
2318 |
-
// update the payment method
|
2319 |
-
$subscription->default_payment_method = $this->customer->invoice_settings->default_payment_method;
|
2320 |
-
$subscription->save();
|
2321 |
-
}
|
2322 |
-
}
|
2323 |
-
|
2324 |
-
/**
|
2325 |
-
* Cancel a subscription at Stripe
|
2326 |
-
*
|
2327 |
-
* @since 1.4
|
2328 |
-
*/
|
2329 |
-
function cancel( &$order, $update_status = true ) {
|
2330 |
-
global $pmpro_stripe_event;
|
2331 |
-
|
2332 |
-
//no matter what happens below, we're going to cancel the order in our system
|
2333 |
-
if ( $update_status ) {
|
2334 |
-
$order->updateStatus( "cancelled" );
|
2335 |
-
}
|
2336 |
-
|
2337 |
-
//require a subscription id
|
2338 |
-
if ( empty( $order->subscription_transaction_id ) ) {
|
2339 |
-
return false;
|
2340 |
-
}
|
2341 |
-
|
2342 |
-
//find the customer
|
2343 |
-
$result = $this->getCustomer( $order );
|
2344 |
-
|
2345 |
-
if ( ! empty( $result ) ) {
|
2346 |
-
//find subscription with this order code
|
2347 |
-
$subscription = $this->getSubscription( $order );
|
2348 |
-
|
2349 |
-
if ( ! empty( $subscription )
|
2350 |
-
&& ( empty( $pmpro_stripe_event ) || empty( $pmpro_stripe_event->type ) || $pmpro_stripe_event->type != 'customer.subscription.deleted' ) ) {
|
2351 |
-
if ( $this->cancelSubscriptionAtGateway( $subscription ) ) {
|
2352 |
-
//we're okay, going to return true later
|
2353 |
-
} else {
|
2354 |
-
$order->error = __( "Could not cancel old subscription.", 'paid-memberships-pro' );
|
2355 |
-
$order->shorterror = $order->error;
|
2356 |
-
|
2357 |
-
return false;
|
2358 |
-
}
|
2359 |
-
}
|
2360 |
-
|
2361 |
-
/*
|
2362 |
-
Clear updates for this user. (But not if checking out, we would have already done that.)
|
2363 |
-
*/
|
2364 |
-
if ( empty( $_REQUEST['submit-checkout'] ) ) {
|
2365 |
-
update_user_meta( $order->user_id, "pmpro_stripe_updates", array() );
|
2366 |
}
|
2367 |
-
|
2368 |
-
|
2369 |
-
|
2370 |
-
$
|
2371 |
-
$order->shorterror = $order->error;
|
2372 |
-
|
2373 |
-
return false; //no customer found
|
2374 |
}
|
|
|
2375 |
}
|
2376 |
|
2377 |
/**
|
2378 |
* Helper method to cancel a subscription at Stripe and also clear up any upaid invoices.
|
2379 |
*
|
2380 |
* @since 1.8
|
|
|
2381 |
*/
|
2382 |
-
function cancelSubscriptionAtGateway( $subscription, $preserve_local_membership = false ) {
|
|
|
|
|
2383 |
// Check if a valid sub.
|
2384 |
if ( empty( $subscription ) || empty( $subscription->id ) ) {
|
2385 |
return false;
|
@@ -2403,10 +3179,10 @@ class PMProGateway_stripe extends PMProGateway {
|
|
2403 |
}
|
2404 |
|
2405 |
// Okay have an order, so get customer so we can cancel invoices too
|
2406 |
-
$this->
|
2407 |
|
2408 |
// Get open invoices.
|
2409 |
-
$invoices = Stripe_Invoice::all(['customer' => $
|
2410 |
|
2411 |
// Found it, cancel it.
|
2412 |
try {
|
@@ -2421,7 +3197,7 @@ class PMProGateway_stripe extends PMProGateway {
|
|
2421 |
|
2422 |
// Sometimes we don't want to cancel the local membership when Stripe sends its webhook.
|
2423 |
if ( $preserve_local_membership ) {
|
2424 |
-
|
2425 |
}
|
2426 |
|
2427 |
// Cancel
|
@@ -2436,580 +3212,1196 @@ class PMProGateway_stripe extends PMProGateway {
|
|
2436 |
}
|
2437 |
|
2438 |
/**
|
2439 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2440 |
*
|
2441 |
-
* @
|
|
|
|
|
2442 |
*/
|
2443 |
-
|
2444 |
-
|
2445 |
-
if ( ! empty( $
|
2446 |
-
|
2447 |
-
|
2448 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2449 |
|
2450 |
-
|
2451 |
-
|
2452 |
-
|
2453 |
-
$subscription = $order->Gateway->getSubscription( $order );
|
2454 |
|
2455 |
-
|
2456 |
-
|
2457 |
-
|
2458 |
-
|
2459 |
-
|
2460 |
-
|
2461 |
-
|
2462 |
-
|
2463 |
-
|
2464 |
-
|
2465 |
-
|
2466 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2467 |
}
|
2468 |
}
|
|
|
|
|
2469 |
|
2470 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2471 |
}
|
2472 |
|
2473 |
/**
|
2474 |
-
*
|
2475 |
*
|
2476 |
-
* @
|
2477 |
-
* @
|
2478 |
*
|
2479 |
-
* @return
|
2480 |
*/
|
2481 |
-
function
|
2482 |
-
|
2483 |
-
return
|
|
|
|
|
2484 |
}
|
2485 |
|
2486 |
/**
|
2487 |
-
*
|
2488 |
*
|
2489 |
-
* @
|
2490 |
-
* @param string $transaction_id Payment or invoice id to void.
|
2491 |
*
|
2492 |
-
* @
|
|
|
2493 |
*/
|
2494 |
-
function
|
2495 |
-
|
2496 |
-
|
2497 |
-
$transaction_id = $order->payment_transaction_id;
|
2498 |
-
}
|
2499 |
|
2500 |
-
|
2501 |
-
|
2502 |
-
return false;
|
2503 |
}
|
2504 |
|
2505 |
-
|
2506 |
-
if ( strpos( $transaction_id, "in_" ) !== false ) {
|
2507 |
-
$invoice = Stripe_Invoice::retrieve( $transaction_id );
|
2508 |
|
2509 |
-
|
2510 |
-
|
2511 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2512 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2513 |
|
2514 |
-
|
2515 |
-
|
2516 |
-
|
2517 |
-
|
2518 |
-
|
2519 |
-
|
2520 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2521 |
}
|
2522 |
|
2523 |
-
|
2524 |
-
|
2525 |
-
|
2526 |
-
$order->errorcode = "";
|
2527 |
-
$order->error = "";
|
2528 |
-
$order->shorterror = "";
|
2529 |
|
|
|
2530 |
return false;
|
2531 |
}
|
2532 |
|
2533 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2534 |
try {
|
2535 |
-
$
|
|
|
|
|
|
|
2536 |
} catch ( \Throwable $e ) {
|
2537 |
-
$order->
|
2538 |
-
$order->error = __( "Error: ", 'paid-memberships-pro' ) . $e->getMessage();
|
2539 |
-
$order->shorterror = $order->error;
|
2540 |
-
|
2541 |
return false;
|
2542 |
} catch ( \Exception $e ) {
|
2543 |
-
$order->
|
2544 |
-
$order->error = __( "Error: ", 'paid-memberships-pro' ) . $e->getMessage();
|
2545 |
-
$order->shorterror = $order->error;
|
2546 |
-
|
2547 |
return false;
|
2548 |
}
|
2549 |
|
2550 |
-
|
2551 |
-
|
2552 |
-
$order->saveOrder();
|
2553 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2554 |
return true;
|
2555 |
-
}
|
2556 |
-
$order->status = "error";
|
2557 |
-
$order->errorcode = true;
|
2558 |
-
$order->error = sprintf( __( "Error: Unkown error while refunding charge #%s", 'paid-memberships-pro' ), $transaction_id );
|
2559 |
-
$order->shorterror = $order->error;
|
2560 |
|
2561 |
-
|
|
|
|
|
|
|
2562 |
}
|
2563 |
-
}
|
2564 |
|
2565 |
-
|
2566 |
-
if (
|
2567 |
-
|
|
|
|
|
2568 |
}
|
|
|
|
|
2569 |
|
2570 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2571 |
|
2572 |
-
if ( empty( $payment_method ) ) {
|
2573 |
return false;
|
2574 |
}
|
2575 |
|
2576 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2577 |
|
2578 |
return true;
|
2579 |
}
|
2580 |
|
2581 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2582 |
|
2583 |
-
|
2584 |
-
|
2585 |
-
|
2586 |
-
|
2587 |
-
|
2588 |
-
|
2589 |
-
|
2590 |
-
|
2591 |
-
|
2592 |
-
|
2593 |
-
|
|
|
|
|
|
|
2594 |
return false;
|
2595 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2596 |
}
|
2597 |
|
2598 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2599 |
return false;
|
2600 |
}
|
2601 |
|
2602 |
-
return
|
2603 |
}
|
2604 |
|
2605 |
-
|
2606 |
-
|
2607 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2608 |
}
|
2609 |
-
$this->getCustomer( $order );
|
2610 |
-
}
|
2611 |
|
2612 |
-
|
|
|
2613 |
|
2614 |
-
|
2615 |
-
|
2616 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2617 |
}
|
2618 |
|
|
|
2619 |
try {
|
2620 |
-
$
|
2621 |
-
|
2622 |
-
|
2623 |
-
|
2624 |
-
|
2625 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2626 |
} catch ( \Throwable $e ) {
|
2627 |
-
|
|
|
|
|
|
|
|
|
2628 |
return false;
|
2629 |
} catch ( \Exception $e ) {
|
2630 |
-
|
|
|
|
|
|
|
|
|
2631 |
return false;
|
2632 |
}
|
2633 |
|
2634 |
-
|
2635 |
-
|
2636 |
-
|
2637 |
-
|
|
|
2638 |
|
2639 |
-
if ( 0 == floatval( $order->InitialPayment ) ) {
|
2640 |
return true;
|
2641 |
-
}
|
2642 |
-
|
2643 |
-
|
2644 |
-
|
2645 |
-
|
2646 |
-
if ( ! empty( $order->error ) ) {
|
2647 |
-
$order->error = $order->error;
|
2648 |
|
2649 |
return false;
|
2650 |
}
|
|
|
2651 |
|
2652 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2653 |
}
|
2654 |
|
2655 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2656 |
|
2657 |
-
|
2658 |
-
|
|
|
2659 |
}
|
2660 |
|
2661 |
-
$
|
2662 |
|
2663 |
-
|
|
|
2664 |
return false;
|
2665 |
}
|
2666 |
|
2667 |
-
|
2668 |
-
|
2669 |
-
|
2670 |
-
|
2671 |
-
|
2672 |
-
function get_payment_intent( &$order ) {
|
2673 |
|
2674 |
-
|
|
|
2675 |
try {
|
2676 |
-
$
|
2677 |
-
} catch ( Stripe\Error\Base $e ) {
|
2678 |
-
$order->error = $e->getMessage();
|
2679 |
-
return false;
|
2680 |
} catch ( \Throwable $e ) {
|
2681 |
-
$order->error
|
|
|
|
|
2682 |
return false;
|
2683 |
} catch ( \Exception $e ) {
|
2684 |
-
$order->error
|
|
|
|
|
2685 |
return false;
|
2686 |
}
|
2687 |
-
}
|
2688 |
|
2689 |
-
|
2690 |
-
$payment_intent = $this->create_payment_intent( $order );
|
2691 |
}
|
2692 |
|
2693 |
-
|
|
|
|
|
|
|
|
|
2694 |
return false;
|
2695 |
}
|
2696 |
|
2697 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2698 |
}
|
2699 |
|
2700 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2701 |
|
2702 |
-
|
|
|
|
|
|
|
2703 |
|
2704 |
-
//
|
2705 |
-
$
|
2706 |
-
|
2707 |
-
|
|
|
|
|
|
|
|
|
|
|
2708 |
}
|
2709 |
|
2710 |
-
|
2711 |
-
$order->subtotal = $amount;
|
2712 |
-
$tax = $order->getTax( true );
|
2713 |
|
2714 |
-
$
|
|
|
|
|
|
|
|
|
2715 |
|
2716 |
-
|
2717 |
-
'customer' => $this->customer->id,
|
2718 |
-
'payment_method' => $this->payment_method->id,
|
2719 |
-
'amount' => $amount * $currency_unit_multiplier,
|
2720 |
-
'currency' => $pmpro_currency,
|
2721 |
-
'confirmation_method' => 'manual',
|
2722 |
-
'description' => apply_filters( 'pmpro_stripe_order_description', "Order #" . $order->code . ", " . trim( $order->FirstName . " " . $order->LastName ) . " (" . $order->Email . ")", $order ),
|
2723 |
-
'setup_future_usage' => 'off_session',
|
2724 |
-
);
|
2725 |
|
2726 |
-
|
2727 |
-
|
2728 |
-
|
2729 |
-
|
2730 |
-
|
2731 |
-
|
2732 |
-
|
2733 |
-
|
2734 |
-
|
|
|
|
|
2735 |
|
|
|
2736 |
try {
|
2737 |
-
$
|
2738 |
-
|
2739 |
-
|
2740 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2741 |
} catch ( \Throwable $e ) {
|
2742 |
-
$order->error
|
|
|
|
|
2743 |
return false;
|
2744 |
} catch ( \Exception $e ) {
|
2745 |
-
$order->error
|
2746 |
-
|
2747 |
-
}
|
2748 |
-
|
2749 |
-
return $payment_intent;
|
2750 |
-
}
|
2751 |
-
|
2752 |
-
function process_subscriptions( &$order ) {
|
2753 |
|
2754 |
-
|
2755 |
-
return true;
|
2756 |
}
|
2757 |
|
2758 |
-
//before subscribing, let's clear out the updates so we don't trigger any during sub
|
2759 |
if ( ! empty( $user_id ) ) {
|
2760 |
$old_user_updates = get_user_meta( $user_id, "pmpro_stripe_updates", true );
|
2761 |
update_user_meta( $user_id, "pmpro_stripe_updates", array() );
|
2762 |
}
|
2763 |
|
2764 |
-
$this->set_setup_intent( $order );
|
2765 |
-
$this->confirm_setup_intent( $order );
|
2766 |
|
2767 |
-
if ( ! empty( $order->
|
2768 |
-
$order->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2769 |
|
2770 |
//give the user any old updates back
|
2771 |
if ( ! empty( $user_id ) ) {
|
2772 |
update_user_meta( $user_id, "pmpro_stripe_updates", $old_user_updates );
|
2773 |
}
|
2774 |
|
|
|
|
|
|
|
|
|
2775 |
return false;
|
2776 |
-
}
|
|
|
|
|
2777 |
|
2778 |
-
|
2779 |
-
|
2780 |
-
|
2781 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2782 |
}
|
2783 |
|
2784 |
-
//
|
2785 |
-
|
2786 |
-
|
2787 |
-
|
2788 |
-
|
2789 |
-
|
2790 |
-
|
2791 |
-
|
2792 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2793 |
function pmpro_user_register_stripe_updates( $user_id ) {
|
2794 |
global $pmpro_stripe_updates;
|
2795 |
-
update_user_meta( $user_id,
|
2796 |
}
|
2797 |
-
|
|
|
2798 |
}
|
|
|
|
|
|
|
2799 |
}
|
2800 |
|
2801 |
return true;
|
2802 |
}
|
2803 |
|
2804 |
-
|
2805 |
-
|
2806 |
-
|
2807 |
-
|
2808 |
-
|
2809 |
-
|
2810 |
-
|
2811 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2812 |
|
2813 |
-
|
2814 |
-
|
2815 |
-
|
2816 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2817 |
}
|
2818 |
|
2819 |
-
|
2820 |
-
|
2821 |
-
|
2822 |
-
There are two parts to the trial. Part 1 is simply the delay until the first payment
|
2823 |
-
since we are doing the first payment as a separate transaction.
|
2824 |
-
The second part is the actual "trial" set by the admin.
|
2825 |
-
|
2826 |
-
Stripe only supports Year or Month for billing periods, but we account for Days and Weeks just in case.
|
2827 |
-
*/
|
2828 |
-
if ( $order->BillingPeriod == "Year" ) {
|
2829 |
-
$trial_period_days = $order->BillingFrequency * 365; //annual
|
2830 |
-
} elseif ( $order->BillingPeriod == "Day" ) {
|
2831 |
-
$trial_period_days = $order->BillingFrequency * 1; //daily
|
2832 |
-
} elseif ( $order->BillingPeriod == "Week" ) {
|
2833 |
-
$trial_period_days = $order->BillingFrequency * 7; //weekly
|
2834 |
-
} else {
|
2835 |
-
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
2836 |
}
|
2837 |
|
2838 |
-
//
|
2839 |
-
|
2840 |
-
|
2841 |
-
//filter the start date
|
2842 |
-
$order->ProfileStartDate = apply_filters( "pmpro_profile_start_date", $order->ProfileStartDate, $order );
|
2843 |
-
|
2844 |
-
//convert back to days
|
2845 |
-
$trial_period_days = ceil( abs( strtotime( date_i18n( "Y-m-d" ), current_time( "timestamp" ) ) - strtotime( $order->ProfileStartDate, current_time( "timestamp" ) ) ) / 86400 );
|
2846 |
|
2847 |
-
|
2848 |
-
|
2849 |
-
$trialOccurrences = (int) $order->TrialBillingCycles;
|
2850 |
-
if ( $order->BillingPeriod == "Year" ) {
|
2851 |
-
$trial_period_days = $trial_period_days + ( 365 * $order->BillingFrequency * $trialOccurrences ); //annual
|
2852 |
-
} elseif ( $order->BillingPeriod == "Day" ) {
|
2853 |
-
$trial_period_days = $trial_period_days + ( 1 * $order->BillingFrequency * $trialOccurrences ); //daily
|
2854 |
-
} elseif ( $order->BillingPeriod == "Week" ) {
|
2855 |
-
$trial_period_days = $trial_period_days + ( 7 * $order->BillingFrequency * $trialOccurrences ); //weekly
|
2856 |
-
} else {
|
2857 |
-
$trial_period_days = $trial_period_days + ( 30 * $order->BillingFrequency * $trialOccurrences ); //assume monthly
|
2858 |
}
|
2859 |
-
} elseif ( ! empty( $order->TrialBillingCycles ) ) {
|
2860 |
-
|
2861 |
}
|
2862 |
|
2863 |
-
//
|
2864 |
-
$order->TrialPeriodDays = $trial_period_days;
|
2865 |
-
|
2866 |
-
//create a plan
|
2867 |
try {
|
2868 |
-
$
|
2869 |
-
"amount" => $amount * $currency_unit_multiplier,
|
2870 |
-
"interval_count" => $order->BillingFrequency,
|
2871 |
-
"interval" => strtolower( $order->BillingPeriod ),
|
2872 |
-
"trial_period_days" => $trial_period_days,
|
2873 |
-
'product' => array( 'name' => $order->membership_name . " for order " . $order->code ),
|
2874 |
-
"currency" => strtolower( $pmpro_currency ),
|
2875 |
-
"id" => $order->code
|
2876 |
-
);
|
2877 |
-
$order->plan = Stripe_Plan::create( apply_filters( 'pmpro_stripe_create_plan_array', $plan ) );
|
2878 |
-
} catch ( Stripe\Error\Base $e ) {
|
2879 |
-
$order->error = $e->getMessage();
|
2880 |
-
|
2881 |
-
return false;
|
2882 |
} catch ( \Throwable $e ) {
|
2883 |
-
$
|
2884 |
-
|
2885 |
-
return false;
|
2886 |
} catch ( \Exception $e ) {
|
2887 |
-
$
|
2888 |
-
|
2889 |
-
return false;
|
2890 |
}
|
2891 |
|
2892 |
-
|
2893 |
-
|
2894 |
-
|
2895 |
-
|
|
|
|
|
2896 |
|
2897 |
-
//subscribe to the plan
|
2898 |
-
try {
|
2899 |
-
$params = array(
|
2900 |
-
'customer' => $this->customer->id,
|
2901 |
-
'default_payment_method' => $this->payment_method,
|
2902 |
-
'items' => array(
|
2903 |
-
array( 'plan' => $order->code ),
|
2904 |
-
),
|
2905 |
-
'trial_period_days' => $order->TrialPeriodDays,
|
2906 |
-
'expand' => array(
|
2907 |
-
'pending_setup_intent.payment_method',
|
2908 |
-
),
|
2909 |
-
);
|
2910 |
-
$order->subscription = Stripe_Subscription::create( $params );
|
2911 |
-
} catch ( Stripe\Error\Base $e ) {
|
2912 |
-
$order->error = $e->getMessage();
|
2913 |
-
return false;
|
2914 |
-
} catch ( \Throwable $e ) {
|
2915 |
-
$order->error = $e->getMessage();
|
2916 |
-
return false;
|
2917 |
-
} catch ( \Exception $e ) {
|
2918 |
-
$order->error = $e->getMessage();
|
2919 |
return false;
|
2920 |
}
|
2921 |
|
2922 |
-
|
2923 |
-
|
2924 |
-
}
|
2925 |
-
|
2926 |
-
function delete_plan( &$order ) {
|
2927 |
try {
|
2928 |
-
$
|
2929 |
-
} catch ( Stripe\Error\Base $e ) {
|
2930 |
-
$order->error = $e->getMessage();
|
2931 |
-
|
2932 |
-
return false;
|
2933 |
} catch ( \Throwable $e ) {
|
2934 |
-
$order->
|
|
|
|
|
2935 |
|
2936 |
return false;
|
2937 |
} catch ( \Exception $e ) {
|
2938 |
-
$order->
|
|
|
|
|
2939 |
|
2940 |
return false;
|
2941 |
}
|
2942 |
|
2943 |
-
|
2944 |
-
|
2945 |
-
|
2946 |
-
function get_setup_intent( &$order ) {
|
2947 |
-
|
2948 |
-
if ( ! empty( $order->setup_intent_id ) ) {
|
2949 |
-
try {
|
2950 |
-
$setup_intent = Stripe_SetupIntent::retrieve( $order->setup_intent_id );
|
2951 |
-
} catch ( Stripe\Error\Base $e ) {
|
2952 |
-
$order->error = $e->getMessage();
|
2953 |
-
return false;
|
2954 |
-
} catch ( \Throwable $e ) {
|
2955 |
-
$order->error = $e->getMessage();
|
2956 |
-
return false;
|
2957 |
-
} catch ( \Exception $e ) {
|
2958 |
-
$order->error = $e->getMessage();
|
2959 |
-
return false;
|
2960 |
-
}
|
2961 |
-
}
|
2962 |
|
2963 |
-
|
2964 |
-
|
2965 |
-
|
|
|
|
|
|
|
2966 |
|
2967 |
-
if ( empty( $setup_intent ) ) {
|
2968 |
return false;
|
2969 |
}
|
2970 |
-
|
2971 |
-
return $setup_intent;
|
2972 |
}
|
2973 |
|
2974 |
-
|
2975 |
-
|
2976 |
-
|
|
|
|
|
|
|
2977 |
return true;
|
2978 |
}
|
2979 |
|
2980 |
-
$
|
2981 |
|
2982 |
-
if ( empty( $
|
2983 |
return false;
|
2984 |
}
|
2985 |
|
2986 |
-
$this->
|
2987 |
|
2988 |
return true;
|
2989 |
}
|
2990 |
|
2991 |
-
|
2992 |
-
|
2993 |
-
|
2994 |
-
|
2995 |
-
|
2996 |
-
|
2997 |
-
|
2998 |
-
return false;
|
2999 |
}
|
3000 |
-
|
3001 |
-
|
|
|
3002 |
}
|
3003 |
|
3004 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3005 |
|
3006 |
try {
|
3007 |
-
$
|
3008 |
-
|
3009 |
-
|
3010 |
-
),
|
3011 |
-
);
|
3012 |
-
$this->payment_intent->confirm( $params );
|
3013 |
} catch ( Stripe\Error\Base $e ) {
|
3014 |
$order->error = $e->getMessage();
|
3015 |
return false;
|
@@ -3021,40 +4413,76 @@ class PMProGateway_stripe extends PMProGateway {
|
|
3021 |
return false;
|
3022 |
}
|
3023 |
|
3024 |
-
|
3025 |
-
|
3026 |
-
|
3027 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3028 |
|
|
|
3029 |
return false;
|
3030 |
}
|
3031 |
|
|
|
|
|
3032 |
return true;
|
3033 |
}
|
3034 |
|
3035 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3036 |
|
3037 |
-
|
3038 |
-
|
3039 |
-
|
|
|
3040 |
|
3041 |
-
|
3042 |
-
|
3043 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3044 |
|
3045 |
return false;
|
3046 |
-
}
|
|
|
3047 |
|
3048 |
-
|
|
|
|
|
3049 |
|
3050 |
-
|
3051 |
-
if ( ! empty( $this->payment_intent ) && 'succeeded' == $this->payment_intent->status ) {
|
3052 |
-
$order->payment_transaction_id = $this->payment_intent->charges->data[0]->id;
|
3053 |
}
|
3054 |
|
3055 |
-
|
3056 |
-
$order->subscription_transaction_id = $this->subscription->id;
|
3057 |
-
}
|
3058 |
}
|
|
|
3059 |
|
3060 |
}
|
3 |
use Stripe\Customer as Stripe_Customer;
|
4 |
use Stripe\Invoice as Stripe_Invoice;
|
5 |
use Stripe\Plan as Stripe_Plan;
|
6 |
+
use Stripe\Product as Stripe_Product;
|
7 |
+
use Stripe\Price as Stripe_Price;
|
8 |
use Stripe\Charge as Stripe_Charge;
|
9 |
use Stripe\PaymentIntent as Stripe_PaymentIntent;
|
10 |
use Stripe\SetupIntent as Stripe_SetupIntent;
|
|
|
11 |
use Stripe\PaymentMethod as Stripe_PaymentMethod;
|
12 |
use Stripe\Subscription as Stripe_Subscription;
|
13 |
+
use Stripe\ApplePayDomain as Stripe_ApplePayDomain;
|
14 |
use Stripe\WebhookEndpoint as Stripe_Webhook;
|
15 |
use Stripe\StripeClient as Stripe_Client; // Used for deleting webhook as of 2.4
|
16 |
+
use Stripe\Account as Stripe_Account;
|
17 |
|
18 |
define( "PMPRO_STRIPE_API_VERSION", "2020-03-02" );
|
19 |
|
51 |
|
52 |
if ( true === $this->dependencies() ) {
|
53 |
$this->loadStripeLibrary();
|
54 |
+
Stripe\Stripe::setApiKey( self::get_secretkey() );
|
55 |
Stripe\Stripe::setAPIVersion( PMPRO_STRIPE_API_VERSION );
|
56 |
+
Stripe\Stripe::setAppInfo(
|
57 |
+
'WordPress Paid Memberships Pro',
|
58 |
+
PMPRO_VERSION,
|
59 |
+
'https://www.paidmembershipspro.com',
|
60 |
+
'pp_partner_DKlIQ5DD7SFW3A'
|
61 |
+
);
|
62 |
self::$is_loaded = true;
|
63 |
}
|
64 |
|
65 |
return $this->gateway;
|
66 |
}
|
67 |
|
68 |
+
/****************************************
|
69 |
+
************ STATIC METHODS ************
|
70 |
+
****************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
/**
|
72 |
* Load the Stripe API library.
|
73 |
*
|
74 |
* @since 1.8
|
75 |
* Moved into a method in version 1.8 so we only load it when needed.
|
76 |
*/
|
77 |
+
public static function loadStripeLibrary() {
|
78 |
//load Stripe library if it hasn't been loaded already (usually by another plugin using Stripe)
|
79 |
if ( ! class_exists( "Stripe\Stripe" ) ) {
|
80 |
require_once( PMPRO_DIR . "/includes/lib/Stripe/init.php" );
|
86 |
*
|
87 |
* @since 1.8
|
88 |
*/
|
89 |
+
public static function init() {
|
90 |
//make sure Stripe is a gateway option
|
91 |
add_filter( 'pmpro_gateways', array( 'PMProGateway_stripe', 'pmpro_gateways' ) );
|
92 |
|
107 |
//old global RE showing billing address or not
|
108 |
global $pmpro_stripe_lite;
|
109 |
$pmpro_stripe_lite = apply_filters( "pmpro_stripe_lite", ! pmpro_getOption( "stripe_billingaddress" ) ); //default is oposite of the stripe_billingaddress setting
|
110 |
+
|
111 |
+
$gateway = pmpro_getGateway();
|
112 |
+
if($gateway == "stripe")
|
113 |
+
{
|
114 |
+
add_filter( 'pmpro_required_billing_fields', array( 'PMProGateway_stripe', 'pmpro_required_billing_fields' ) );
|
115 |
+
}
|
116 |
|
117 |
//updates cron
|
118 |
add_action( 'pmpro_cron_stripe_subscription_updates', array(
|
123 |
//AJAX services for creating/disabling webhooks
|
124 |
add_action( 'wp_ajax_pmpro_stripe_create_webhook', array( 'PMProGateway_stripe', 'wp_ajax_pmpro_stripe_create_webhook' ) );
|
125 |
add_action( 'wp_ajax_pmpro_stripe_delete_webhook', array( 'PMProGateway_stripe', 'wp_ajax_pmpro_stripe_delete_webhook' ) );
|
126 |
+
add_action( 'wp_ajax_pmpro_stripe_rebuild_webhook', array( 'PMProGateway_stripe', 'wp_ajax_pmpro_stripe_rebuild_webhook' ) );
|
127 |
|
128 |
/*
|
129 |
Filter pmpro_next_payment to get actual value
|
170 |
) );
|
171 |
}
|
172 |
|
173 |
+
add_action( 'pmpro_payment_option_fields', array( 'PMProGateway_stripe', 'pmpro_set_up_apple_pay' ), 10, 2 );
|
174 |
add_action( 'init', array( 'PMProGateway_stripe', 'clear_saved_subscriptions' ) );
|
175 |
+
|
176 |
+
// Stripe Connect functions.
|
177 |
+
add_action( 'admin_init', array( 'PMProGateway_stripe', 'stripe_connect_save_options' ) );
|
178 |
+
add_action( 'admin_notices', array( 'PMProGateway_stripe', 'stripe_connect_show_errors' ) );
|
179 |
+
add_action( 'admin_notices', array( 'PMProGateway_stripe', 'stripe_connect_deauthorize' ) );
|
180 |
}
|
181 |
|
182 |
/**
|
211 |
*
|
212 |
* @since 1.8
|
213 |
*/
|
214 |
+
public static function pmpro_gateways( $gateways ) {
|
215 |
if ( empty( $gateways['stripe'] ) ) {
|
216 |
$gateways['stripe'] = __( 'Stripe', 'paid-memberships-pro' );
|
217 |
}
|
224 |
*
|
225 |
* @since 1.8
|
226 |
*/
|
227 |
+
public static function getGatewayOptions() {
|
228 |
$options = array(
|
229 |
'sslseal',
|
230 |
'nuclear_HTTPS',
|
231 |
'gateway_environment',
|
232 |
'stripe_secretkey',
|
233 |
'stripe_publishablekey',
|
234 |
+
'live_stripe_connect_user_id',
|
235 |
+
'live_stripe_connect_secretkey',
|
236 |
+
'live_stripe_connect_publishablekey',
|
237 |
+
'sandbox_stripe_connect_user_id',
|
238 |
+
'sandbox_stripe_connect_secretkey',
|
239 |
+
'sandbox_stripe_connect_publishablekey',
|
240 |
'stripe_webhook',
|
241 |
'stripe_billingaddress',
|
242 |
'currency',
|
243 |
'use_ssl',
|
244 |
'tax_state',
|
245 |
'tax_rate',
|
246 |
+
'accepted_credit_cards',
|
247 |
+
'stripe_payment_request_button',
|
248 |
);
|
249 |
|
250 |
return $options;
|
255 |
*
|
256 |
* @since 1.8
|
257 |
*/
|
258 |
+
public static function pmpro_payment_options( $options ) {
|
259 |
//get stripe options
|
260 |
$stripe_options = self::getGatewayOptions();
|
261 |
|
270 |
*
|
271 |
* @since 1.8
|
272 |
*/
|
273 |
+
public static function pmpro_payment_option_fields( $values, $gateway ) {
|
274 |
+
$stripe = new PMProGateway_stripe();
|
|
|
|
|
|
|
|
|
275 |
|
276 |
+
// Show connect fields.
|
277 |
+
$stripe->show_connect_payment_option_fields( true, $values, $gateway ); // Show live connect fields.
|
278 |
+
$stripe->show_connect_payment_option_fields( false, $values, $gateway ); // Show sandbox connect fields.
|
|
|
|
|
|
|
|
|
|
|
279 |
|
280 |
+
if ( self::using_legacy_keys() ) {
|
281 |
+
// Check if webhook is enabled or not.
|
282 |
+
$webhook = self::does_webhook_exist();
|
283 |
|
284 |
+
// Check to see if events are missing.
|
285 |
+
if ( is_array( $webhook ) && isset( $webhook['enabled_events'] ) ) {
|
286 |
$events = self::check_missing_webhook_events( $webhook['enabled_events'] );
|
|
|
287 |
if ( $events ) {
|
288 |
+
self::update_webhook_events();
|
|
|
|
|
|
|
|
|
|
|
289 |
}
|
290 |
}
|
291 |
|
292 |
+
// Break the country cache in case new credentials were saved.
|
293 |
+
delete_transient( 'pmpro_stripe_account_country' );
|
|
|
|
|
|
|
294 |
}
|
295 |
|
|
|
|
|
296 |
?>
|
297 |
+
<tr class="pmpro_settings_divider gateway gateway_stripe" <?php if ( $gateway != "stripe" ) { ?>style="display: none;"<?php } ?>>
|
298 |
+
<td colspan="2">
|
|
|
|
|
|
|
|
|
|
|
299 |
<hr />
|
300 |
+
<h2 class="pmpro_stripe_legacy_keys" <?php if( ! self::show_legacy_keys_settings() ) {?>style="display: none;"<?php }?>><?php esc_html_e( 'Stripe API Settings (Legacy)', 'paid-memberships-pro' ); ?></h2>
|
301 |
+
<?php if( ! self::show_legacy_keys_settings() ) {?>
|
302 |
+
<p>
|
303 |
+
<?php esc_html_e( 'Having trouble connecting through the button above or otherwise need to use your own API keys?', 'paid-memberships-pro' );?>
|
304 |
+
<a id="pmpro_stripe_legacy_keys_toggle" href="javascript:void(0);"><?php esc_html_e( 'Click here to use the legacy API settings.', 'paid-memberships-pro' );?></a>
|
305 |
+
</p>
|
306 |
+
<script>
|
307 |
+
// Toggle to show the Stripe legacy keys settings.
|
308 |
+
jQuery(document).ready(function(){
|
309 |
+
jQuery('#pmpro_stripe_legacy_keys_toggle').click(function(e){
|
310 |
+
var btn = jQuery('#pmpro_stripe_legacy_keys_toggle');
|
311 |
+
var div = btn.closest('.pmpro_settings_divider');
|
312 |
+
btn.parent().remove();
|
313 |
+
jQuery('.pmpro_stripe_legacy_keys').show();
|
314 |
+
jQuery('.pmpro_stripe_legacy_keys').addClass('gateway_stripe');
|
315 |
+
jQuery('#stripe_publishablekey').focus();
|
316 |
+
});
|
317 |
+
});
|
318 |
+
</script>
|
319 |
+
<?php } ?>
|
320 |
+
</td>
|
321 |
+
</tr>
|
322 |
+
<tr class="gateway pmpro_stripe_legacy_keys <?php if ( self::show_legacy_keys_settings() ) { echo 'gateway_stripe'; } ?>" <?php if ( $gateway != "stripe" || ! self::show_legacy_keys_settings() ) { ?>style="display: none;"<?php } ?>>
|
323 |
+
<th scope="row" valign="top">
|
324 |
+
<label for="stripe_publishablekey"><?php _e( 'Publishable Key', 'paid-memberships-pro' ); ?>:</label>
|
325 |
+
</th>
|
326 |
+
<td>
|
327 |
+
<input type="text" id="stripe_publishablekey" name="stripe_publishablekey" value="<?php echo esc_attr( $values['stripe_publishablekey'] ) ?>" class="regular-text code" />
|
328 |
<?php
|
329 |
$public_key_prefix = substr( $values['stripe_publishablekey'], 0, 3 );
|
330 |
if ( ! empty( $values['stripe_publishablekey'] ) && $public_key_prefix != 'pk_' ) {
|
331 |
?>
|
332 |
+
<p class="pmpro_red"><strong><?php _e( 'Your Publishable Key appears incorrect.', 'paid-memberships-pro' ); ?></strong></p>
|
333 |
<?php
|
334 |
}
|
335 |
?>
|
336 |
+
</td>
|
337 |
+
</tr>
|
338 |
+
<tr class="gateway pmpro_stripe_legacy_keys <?php if ( self::show_legacy_keys_settings() ) { echo 'gateway_stripe'; } ?>" <?php if ( $gateway != "stripe" || ! self::show_legacy_keys_settings() ) { ?>style="display: none;"<?php } ?>>
|
339 |
+
<th scope="row" valign="top">
|
340 |
+
<label for="stripe_secretkey"><?php _e( 'Secret Key', 'paid-memberships-pro' ); ?>:</label>
|
341 |
+
</th>
|
342 |
+
<td>
|
343 |
+
<input type="text" id="stripe_secretkey" name="stripe_secretkey" value="<?php echo esc_attr( $values['stripe_secretkey'] ) ?>" autocomplete="off" class="regular-text code pmpro-admin-secure-key" />
|
344 |
+
</td>
|
345 |
+
</tr>
|
346 |
+
<tr class="gateway pmpro_stripe_legacy_keys <?php if ( self::show_legacy_keys_settings() ) { echo 'gateway_stripe'; } ?>" <?php if ( $gateway != "stripe" || ! self::show_legacy_keys_settings() ) { ?>style="display: none;"<?php } ?>>
|
347 |
+
<th scope="row" valign="top">
|
348 |
+
<label><?php esc_html_e( 'Webhook', 'paid-memberships-pro' ); ?>:</label>
|
349 |
+
</th>
|
350 |
+
<td>
|
351 |
+
<?php if ( ! empty( $webhook ) && is_array( $webhook ) && self::show_legacy_keys_settings()) { ?>
|
352 |
<button type="button" id="pmpro_stripe_create_webhook" class="button button-secondary" style="display: none;"><span class="dashicons dashicons-update-alt"></span> <?php _e( 'Create Webhook' ,'paid-memberships-pro' ); ?></button>
|
353 |
+
<?php
|
354 |
+
if ( 'disabled' === $webhook['status'] ) {
|
355 |
+
// Check webhook status.
|
356 |
+
?>
|
357 |
+
<div class="notice error inline">
|
358 |
+
<p id="pmpro_stripe_webhook_notice" class="pmpro_stripe_webhook_notice"><?php _e( 'A webhook is set up in Stripe, but it is disabled.', 'paid-memberships-pro' ); ?> <a id="pmpro_stripe_rebuild_webhook" href="#">Rebuild Webhook</a></p>
|
359 |
+
</div>
|
360 |
+
<?php
|
361 |
+
} elseif ( $webhook['api_version'] < PMPRO_STRIPE_API_VERSION ) {
|
362 |
+
// Check webhook API version.
|
363 |
+
?>
|
364 |
+
<div class="notice error inline">
|
365 |
+
<p id="pmpro_stripe_webhook_notice" class="pmpro_stripe_webhook_notice"><?php _e( 'A webhook is set up in Stripe, but it is using an old API version.', 'paid-memberships-pro' ); ?> <a id="pmpro_stripe_rebuild_webhook" href="#"><?php _e( 'Rebuild Webhook', 'paid-memberships-pro' ); ?></a></p>
|
366 |
+
</div>
|
367 |
+
<?php
|
368 |
+
} else {
|
369 |
+
?>
|
370 |
+
<div class="notice notice-success inline">
|
371 |
+
<p id="pmpro_stripe_webhook_notice" class="pmpro_stripe_webhook_notice"><?php _e( 'Your webhook is enabled.', 'paid-memberships-pro' ); ?> <a id="pmpro_stripe_delete_webhook" href="#"><?php _e( 'Disable Webhook', 'paid-memberships-pro' ); ?></a></p>
|
372 |
+
</div>
|
373 |
+
<?php
|
374 |
+
}
|
375 |
+
} elseif ( self::show_legacy_keys_settings() ) { ?>
|
376 |
+
<button type="button" id="pmpro_stripe_create_webhook" class="button button-secondary"><span class="dashicons dashicons-update-alt"></span> <?php _e( 'Create Webhook' ,'paid-memberships-pro' ); ?></button>
|
377 |
+
<div class="notice error inline">
|
378 |
+
<p id="pmpro_stripe_webhook_notice" class="pmpro_stripe_webhook_notice"><?php _e('A webhook in Stripe is required to process recurring payments, manage failed payments, and synchronize cancellations.', 'paid-memberships-pro' );?></p>
|
379 |
+
</div>
|
380 |
+
<?php
|
381 |
+
}
|
382 |
+
?>
|
383 |
+
<p class="description"><?php esc_html_e( 'Webhook URL', 'paid-memberships-pro' ); ?>:
|
384 |
+
<code><?php echo self::get_site_webhook_url(); ?></code></p>
|
385 |
+
</td>
|
386 |
+
</tr>
|
387 |
+
<tr class="pmpro_settings_divider gateway gateway_stripe" <?php if ( $gateway != "stripe" ) { ?>style="display: none;"<?php } ?>>
|
388 |
+
<td colspan="2">
|
389 |
+
<hr />
|
390 |
+
<h2><?php esc_html_e( 'Other Stripe Settings', 'paid-memberships-pro' ); ?></h2>
|
391 |
+
</td>
|
392 |
+
</tr>
|
393 |
<tr class="gateway gateway_stripe" <?php if ( $gateway != "stripe" ) { ?>style="display: none;"<?php } ?>>
|
394 |
+
<th><?php _e( 'Stripe API Version', 'paid-memberships-pro' ); ?>:</th>
|
395 |
+
<td><code><?php echo PMPRO_STRIPE_API_VERSION; ?></code></td>
|
396 |
+
</tr>
|
397 |
+
<tr class="gateway gateway_stripe" <?php if ( $gateway != "stripe" ) { ?>style="display: none;"<?php } ?>>
|
398 |
+
<th scope="row" valign="top">
|
399 |
+
<label for="stripe_billingaddress"><?php _e( 'Show Billing Address Fields', 'paid-memberships-pro' ); ?>:</label>
|
400 |
+
</th>
|
401 |
+
<td>
|
402 |
+
<select id="stripe_billingaddress" name="stripe_billingaddress">
|
403 |
+
<option value="0"
|
404 |
+
<?php if ( empty( $values['stripe_billingaddress'] ) ) { ?>selected="selected"<?php } ?>><?php _e( 'No', 'paid-memberships-pro' ); ?></option>
|
405 |
+
<option value="1"
|
406 |
+
<?php if ( ! empty( $values['stripe_billingaddress'] ) ) { ?>selected="selected"<?php } ?>><?php _e( 'Yes', 'paid-memberships-pro' ); ?></option>
|
407 |
+
</select>
|
408 |
<p class="description"><?php _e( "Stripe doesn't require billing address fields. Choose 'No' to hide them on the checkout page.<br /><strong>If No, make sure you disable address verification in the Stripe dashboard settings.</strong>", 'paid-memberships-pro' ); ?></p>
|
409 |
+
</td>
|
410 |
+
</tr>
|
411 |
+
<tr class="gateway gateway_stripe" <?php if ( $gateway != "stripe" ) { ?>style="display: none;"<?php } ?>>
|
412 |
+
<th scope="row" valign="top">
|
413 |
+
<label for="stripe_payment_request_button"><?php _e( 'Enable Payment Request Button', 'paid-memberships-pro' ); ?>:</label>
|
414 |
+
</th>
|
415 |
+
<td>
|
416 |
+
<select id="stripe_payment_request_button" name="stripe_payment_request_button">
|
417 |
+
<option value="0"
|
418 |
+
<?php if ( empty( $values['stripe_payment_request_button'] ) ) { ?>selected="selected"<?php } ?>><?php _e( 'No', 'paid-memberships-pro' ); ?></option>
|
419 |
+
<option value="1"
|
420 |
+
<?php if ( ! empty( $values['stripe_payment_request_button'] ) ) { ?>selected="selected"<?php } ?>><?php _e( 'Yes', 'paid-memberships-pro' ); ?></option>
|
421 |
+
</select>
|
422 |
+
<?php
|
423 |
+
$allowed_stripe_payment_button_html = array (
|
424 |
+
'a' => array (
|
425 |
+
'href' => array(),
|
426 |
+
'target' => array(),
|
427 |
+
'title' => array(),
|
428 |
+
),
|
429 |
+
);
|
430 |
+
?>
|
431 |
+
<p class="description"><?php echo sprintf( wp_kses( __( 'Allow users to pay using Apple Pay, Google Pay, or Microsoft Pay depending on their browser. When enabled, your domain will automatically be registered with Apple and a domain association file will be hosted on your site. <a target="_blank" href="%s" title="More Information about the domain association file for Apple Pay">More Information »</a>', 'paid-memberships-pro' ), $allowed_stripe_payment_button_html ), 'https://stripe.com/docs/stripe-js/elements/payment-request-button#verifying-your-domain-with-apple-pay' ); ?></p>
|
432 |
+
<?php
|
433 |
+
if ( ! empty( $values['stripe_payment_request_button'] ) ) {
|
434 |
+
// Are there any issues with how the payment request button is set up?
|
435 |
+
$payment_request_error = null;
|
436 |
+
$allowed_payment_request_error_html = array (
|
437 |
+
'a' => array (
|
438 |
+
'href' => array(),
|
439 |
+
'target' => array(),
|
440 |
+
'title' => array(),
|
441 |
+
),
|
442 |
+
);
|
443 |
+
if ( empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === "off" ) {
|
444 |
+
$payment_request_error = sprintf( wp_kses( __( 'This webpage is being served over HTTP, but the Stripe Payment Request Button will only work on pages being served over HTTPS. To resolve this, you must <a target="_blank" href="%s" title="Configuring WordPress to Always Use HTTPS/SSL">set up WordPress to always use HTTPS</a>.', 'paid-memberships-pro' ), $allowed_payment_request_error_html ), 'https://www.paidmembershipspro.com/configuring-wordpress-always-use-httpsssl/?utm_source=plugin&utm_medium=pmpro-paymentsettings&utm_campaign=blog&utm_content=configure-https' );
|
445 |
+
} elseif ( self::using_legacy_keys() && substr( $values['stripe_publishablekey'], 0, 8 ) !== "pk_live_" && substr( $values['stripe_publishablekey'], 0, 8 ) !== "pk_test_" ) {
|
446 |
+
$payment_request_error = sprintf( wp_kses( __( 'It looks like you are using an older Stripe publishable key. In order to use the Payment Request Button feature, you will need to update your API key, which will be prefixed with "pk_live_" or "pk_test_". <a target="_blank" href="%s" title="Stripe Dashboard API Key Settings">Log in to your Stripe Dashboard to roll your publishable key</a>.', 'paid-memberships-pro' ), $allowed_payment_request_error_html ), 'https://dashboard.stripe.com/account/apikeys' );
|
447 |
+
} elseif ( self::using_legacy_keys() && substr( $values['stripe_secretkey'], 0, 8 ) !== "sk_live_" && substr( $values['stripe_secretkey'], 0, 8 ) !== "sk_test_" ) {
|
448 |
+
$payment_request_error = sprintf( wp_kses( __( 'It looks like you are using an older Stripe secret key. In order to use the Payment Request Button feature, you will need to update your API key, which will be prefixed with "sk_live_" or "sk_test_". <a target="_blank" href="%s" title="Stripe Dashboard API Key Settings">Log in to your Stripe Dashboard to roll your secret key</a>.', 'paid-memberships-pro' ), $allowed_payment_request_error_html ), 'https://dashboard.stripe.com/account/apikeys' );
|
449 |
+
} elseif ( ! $stripe->pmpro_does_apple_pay_domain_exist() ) {
|
450 |
+
$payment_request_error = sprintf( wp_kses( __( 'Your domain could not be registered with Apple to enable Apple Pay. Please try <a target="_blank" href="%s" title="Apple Pay Settings Page in Stripe">registering your domain manually from the Apple Pay settings page in Stripe</a>.', 'paid-memberships-pro' ), $allowed_payment_request_error_html ), 'https://dashboard.stripe.com/settings/payments/apple_pay' );
|
451 |
+
}
|
452 |
+
if ( ! empty( $payment_request_error ) ) {
|
453 |
+
?>
|
454 |
+
<div class="notice error inline">
|
455 |
+
<p id="pmpro_stripe_payment_request_button_notice"><?php echo( $payment_request_error ); ?></p>
|
456 |
+
</div>
|
457 |
+
<?php
|
458 |
+
}
|
459 |
+
}
|
460 |
+
?>
|
461 |
+
</td>
|
462 |
+
</tr>
|
463 |
+
<?php if ( ! function_exists( 'pmproappe_pmpro_valid_gateways' ) ) {
|
464 |
$allowed_appe_html = array (
|
465 |
'a' => array (
|
466 |
'href' => array(),
|
480 |
/**
|
481 |
* AJAX callback to create webhooks.
|
482 |
*/
|
483 |
+
public static function wp_ajax_pmpro_stripe_create_webhook( $silent = false ) {
|
484 |
$secretkey = sanitize_text_field( $_REQUEST['secretkey'] );
|
485 |
|
486 |
$stripe = new PMProGateway_stripe();
|
487 |
Stripe\Stripe::setApiKey( $secretkey );
|
488 |
|
489 |
+
$update_webhook_response = $stripe::update_webhook_events();
|
490 |
+
|
491 |
+
if ( empty( $update_webhook_response ) || is_wp_error( $update_webhook_response ) ) {
|
492 |
+
$message = empty( $update_webhook_response ) ? __( 'Webhook creation failed. You might already have a webhook set up.', 'paid-memberships-pro' ) : $update_webhook_response->get_error_message();
|
493 |
$r = array(
|
494 |
'success' => false,
|
495 |
'notice' => 'error',
|
496 |
+
'message' => $message,
|
497 |
+
'response' => $update_webhook_response
|
498 |
);
|
499 |
} else {
|
500 |
+
$r = array(
|
501 |
+
'success' => true,
|
502 |
+
'notice' => 'notice-success',
|
503 |
+
'message' => __( 'Your webhook is enabled.', 'paid-memberships-pro' ),
|
504 |
+
'response' => $update_webhook_response
|
505 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
506 |
}
|
507 |
|
508 |
+
if ( $silent ) {
|
509 |
+
return $r;
|
510 |
+
} else {
|
511 |
+
echo json_encode( $r );
|
512 |
+
exit;
|
513 |
+
}
|
514 |
}
|
515 |
|
516 |
/**
|
517 |
* AJAX callback to disable webhooks.
|
518 |
*/
|
519 |
+
public static function wp_ajax_pmpro_stripe_delete_webhook( $silent = false ) {
|
520 |
$secretkey = sanitize_text_field( $_REQUEST['secretkey'] );
|
521 |
|
522 |
$stripe = new PMProGateway_stripe();
|
524 |
|
525 |
$webhook = self::does_webhook_exist();
|
526 |
|
527 |
+
$r = array(
|
528 |
+
'success' => true,
|
529 |
+
'notice' => 'error',
|
530 |
+
'message' => __( 'A webhook in Stripe is required to process recurring payments, manage failed payments, and synchronize cancellations.', 'paid-memberships-pro' )
|
531 |
+
);
|
532 |
+
if ( ! empty( $webhook ) ) {
|
533 |
+
$delete_webhook_response = $stripe::delete_webhook( $webhook, $secretkey );
|
534 |
+
|
535 |
+
if ( is_wp_error( $delete_webhook_response ) || empty( $delete_webhook_response['deleted'] ) || $delete_webhook_response['deleted'] != true ) {
|
536 |
+
$message = is_wp_error( $delete_webhook_response ) ? $delete_webhook_response->get_error_message() : __( 'There was an error deleting the webhook.', 'paid-memberships-pro' );
|
537 |
$r = array(
|
538 |
'success' => false,
|
539 |
'notice' => 'error',
|
540 |
+
'message' => $message,
|
|
|
541 |
);
|
542 |
+
}
|
543 |
+
$r['response'] = $delete_webhook_response;
|
544 |
+
}
|
545 |
+
|
546 |
+
if ( $silent ) {
|
547 |
+
return $r;
|
548 |
+
} else {
|
549 |
+
echo json_encode( $r );
|
550 |
+
exit;
|
551 |
+
}
|
552 |
+
}
|
553 |
+
|
554 |
+
/**
|
555 |
+
* AJAX callback to rebuild webhook.
|
556 |
+
*/
|
557 |
+
public static function wp_ajax_pmpro_stripe_rebuild_webhook() {
|
558 |
+
// First try to delete the webhook.
|
559 |
+
$r = self::wp_ajax_pmpro_stripe_delete_webhook( true ) ;
|
560 |
+
if ( $r['success'] ) {
|
561 |
+
// Webhook was successfully deleted. Now make a new one.
|
562 |
+
$r = self::wp_ajax_pmpro_stripe_create_webhook( true );
|
563 |
+
if ( ! $r['success'] ) {
|
564 |
+
$r['message'] = __( 'Webhook creation failed. Please refresh and try again.', 'paid-memberships-pro' );
|
565 |
}
|
566 |
}
|
567 |
|
568 |
echo json_encode( $r );
|
|
|
569 |
exit;
|
570 |
}
|
571 |
|
574 |
*
|
575 |
* @since 1.8
|
576 |
*/
|
577 |
+
public static function pmpro_checkout_after_preheader( $order ) {
|
578 |
+
global $gateway, $pmpro_level, $current_user, $pmpro_requirebilling, $pmpro_pages, $pmpro_currency;
|
|
|
579 |
|
580 |
$default_gateway = pmpro_getOption( "gateway" );
|
581 |
|
584 |
wp_enqueue_script( "stripe", "https://js.stripe.com/v3/", array(), null );
|
585 |
|
586 |
if ( ! function_exists( 'pmpro_stripe_javascript' ) ) {
|
|
|
587 |
$localize_vars = array(
|
588 |
+
'publishableKey' => self::get_publishablekey(),
|
589 |
+
'user_id' => self::get_connect_user_id(),
|
590 |
'verifyAddress' => apply_filters( 'pmpro_stripe_verify_address', pmpro_getOption( 'stripe_billingaddress' ) ),
|
591 |
'ajaxUrl' => admin_url( "admin-ajax.php" ),
|
592 |
'msgAuthenticationValidated' => __( 'Verification steps confirmed. Your payment is processing.', 'paid-memberships-pro' ),
|
593 |
'pmpro_require_billing' => $pmpro_requirebilling,
|
594 |
+
'restUrl' => get_rest_url(),
|
595 |
+
'siteName' => get_bloginfo( 'name' ),
|
596 |
+
'updatePaymentRequestButton' => apply_filters( 'pmpro_stripe_update_payment_request_button', true ),
|
597 |
+
'currency' => strtolower( $pmpro_currency ),
|
598 |
+
'accountCountry' => self::get_account_country(),
|
599 |
);
|
600 |
|
601 |
if ( ! empty( $order ) ) {
|
602 |
+
if ( ! empty( $order->stripe_payment_intent ) ) {
|
603 |
+
$localize_vars['paymentIntent'] = $order->stripe_payment_intent;
|
604 |
}
|
605 |
+
if ( ! empty( $order->stripe_setup_intent ) ) {
|
606 |
+
$localize_vars['setupIntent'] = $order->stripe_setup_intent;
|
|
|
607 |
}
|
608 |
}
|
609 |
|
621 |
* Don't require the CVV.
|
622 |
* Don't require address fields if they are set to hide.
|
623 |
*/
|
624 |
+
public static function pmpro_required_billing_fields( $fields ) {
|
625 |
global $pmpro_stripe_lite, $current_user, $bemail, $bconfirmemail;
|
626 |
|
627 |
//CVV is not required if set that way at Stripe. The Stripe JS will require it if it is required.
|
655 |
|
656 |
return $fields;
|
657 |
}
|
658 |
+
|
659 |
/**
|
660 |
+
* Filtering orders at checkout.
|
661 |
*
|
662 |
+
* @since 1.8
|
663 |
*/
|
664 |
+
public static function pmpro_checkout_order( $morder ) {
|
665 |
+
|
666 |
+
// Create a code for the order.
|
667 |
+
if ( empty( $morder->code ) ) {
|
668 |
+
$morder->code = $morder->getRandomCode();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
669 |
}
|
670 |
+
|
671 |
+
// Add the PaymentIntent ID to the order.
|
672 |
+
if ( ! empty ( $_REQUEST['payment_intent_id'] ) ) {
|
673 |
+
$morder->payment_intent_id = sanitize_text_field( $_REQUEST['payment_intent_id'] );
|
|
|
|
|
|
|
|
|
|
|
674 |
}
|
675 |
+
|
676 |
+
// Add the SetupIntent ID to the order.
|
677 |
+
if ( ! empty ( $_REQUEST['setup_intent_id'] ) ) {
|
678 |
+
$morder->setup_intent_id = sanitize_text_field( $_REQUEST['setup_intent_id'] );
|
|
|
|
|
|
|
|
|
|
|
679 |
}
|
680 |
+
|
681 |
+
// Add the PaymentMethod ID to the order.
|
682 |
+
if ( ! empty ( $_REQUEST['payment_method_id'] ) ) {
|
683 |
+
$morder->payment_method_id = sanitize_text_field( $_REQUEST['payment_method_id'] );
|
684 |
}
|
685 |
+
|
686 |
+
//stripe lite code to get name from other sources if available
|
687 |
+
global $pmpro_stripe_lite, $current_user;
|
688 |
+
if ( ! empty( $pmpro_stripe_lite ) && empty( $morder->FirstName ) && empty( $morder->LastName ) ) {
|
689 |
+
if ( ! empty( $current_user->ID ) ) {
|
690 |
+
$morder->FirstName = get_user_meta( $current_user->ID, "first_name", true );
|
691 |
+
$morder->LastName = get_user_meta( $current_user->ID, "last_name", true );
|
692 |
+
} elseif ( ! empty( $_REQUEST['first_name'] ) && ! empty( $_REQUEST['last_name'] ) ) {
|
693 |
+
$morder->FirstName = sanitize_text_field( $_REQUEST['first_name'] );
|
694 |
+
$morder->LastName = sanitize_text_field( $_REQUEST['last_name'] );
|
695 |
+
}
|
696 |
+
}
|
697 |
+
|
698 |
+
return $morder;
|
699 |
}
|
700 |
+
|
701 |
/**
|
702 |
+
* Code to run after checkout
|
703 |
*
|
704 |
+
* @since 1.8
|
705 |
*/
|
706 |
+
public static function pmpro_after_checkout( $user_id, $morder ) {
|
707 |
+
global $gateway;
|
708 |
+
|
709 |
+
if ( $gateway == "stripe" ) {
|
710 |
+
if ( self::$is_loaded && ! empty( $morder ) && ! empty( $morder->Gateway ) && ! empty( $morder->Gateway->customer ) && ! empty( $morder->Gateway->customer->id ) ) {
|
711 |
+
update_user_meta( $user_id, "pmpro_stripe_customerid", $morder->Gateway->customer->id );
|
712 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
713 |
}
|
|
|
|
|
|
|
714 |
}
|
715 |
|
716 |
/**
|
717 |
+
* Check settings if billing address should be shown.
|
718 |
+
* @since 1.8
|
|
|
719 |
*/
|
720 |
+
public static function pmpro_include_billing_address_fields( $include ) {
|
721 |
+
//check settings RE showing billing address
|
722 |
+
if ( ! pmpro_getOption( "stripe_billingaddress" ) ) {
|
723 |
+
$include = false;
|
724 |
}
|
725 |
|
726 |
+
return $include;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
727 |
}
|
728 |
|
729 |
/**
|
730 |
+
* Use our own payment fields at checkout. (Remove the name attributes.)
|
731 |
+
* @since 1.8
|
|
|
732 |
*/
|
733 |
+
public static function pmpro_include_payment_information_fields( $include ) {
|
734 |
+
//global vars
|
735 |
+
global $pmpro_requirebilling, $pmpro_show_discount_code, $discount_code, $CardType, $AccountNumber, $ExpirationMonth, $ExpirationYear;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
736 |
|
737 |
//get accepted credit cards
|
738 |
$pmpro_accepted_credit_cards = pmpro_getOption( "accepted_credit_cards" );
|
751 |
<?php if ( ! empty( $sslseal ) ) { ?>
|
752 |
<div class="<?php echo pmpro_get_element_class( 'pmpro_checkout-fields-display-seal' ); ?>">
|
753 |
<?php } ?>
|
754 |
+
<?php
|
755 |
+
if ( pmpro_getOption( 'stripe_payment_request_button' ) ) { ?>
|
756 |
+
<div class="<?php echo pmpro_get_element_class( 'pmpro_checkout-field pmpro_checkout-field-payment-request-button', 'pmpro_checkout-field-payment-request-button' ); ?>">
|
757 |
+
<div id="payment-request-button"><!-- Alternate payment method will be inserted here. --></div>
|
758 |
+
<h4 class="<?php echo pmpro_get_element_class( 'pmpro_checkout-field pmpro_payment-credit-card', 'pmpro_payment-credit-card' ); ?>"><?php esc_html_e( 'Pay with Credit Card', 'paid-memberships-pro' ); ?></h4>
|
759 |
+
</div>
|
760 |
+
<?php
|
761 |
+
}
|
762 |
+
?>
|
763 |
<div class="pmpro_checkout-fields<?php if ( ! empty( $sslseal ) ) { ?> pmpro_checkout-fields-leftcol<?php } ?>">
|
764 |
<?php
|
765 |
$pmpro_include_cardtype_field = apply_filters( 'pmpro_include_cardtype_field', false );
|
796 |
<?php if ( $pmpro_show_discount_code ) { ?>
|
797 |
<div class="<?php echo pmpro_get_element_class( 'pmpro_checkout-field pmpro_payment-discount-code', 'pmpro_payment-discount-code' ); ?>">
|
798 |
<label for="discount_code"><?php _e( 'Discount Code', 'paid-memberships-pro' ); ?></label>
|
799 |
+
<input class="<?php echo pmpro_get_element_class( 'input pmpro_alter_price', 'discount_code' ); ?>"
|
800 |
id="discount_code" name="discount_code" type="text" size="10"
|
801 |
value="<?php echo esc_attr( $discount_code ) ?>"/>
|
802 |
<input type="button" id="discount_code_button" name="discount_code_button"
|
821 |
*
|
822 |
* @since 1.8
|
823 |
*/
|
824 |
+
public static function user_profile_fields( $user ) {
|
825 |
global $wpdb, $current_user, $pmpro_currency_symbol;
|
826 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
827 |
//make sure the current user has privileges
|
828 |
$membership_level_capability = apply_filters( "pmpro_edit_member_capability", "manage_options" );
|
829 |
if ( ! current_user_can( $membership_level_capability ) ) {
|
836 |
return false;
|
837 |
}
|
838 |
|
839 |
+
// Get the user's Stripe Customer if they have one.
|
840 |
+
$stripe = new PMProGateway_Stripe();
|
841 |
+
$customer = $stripe->get_customer_for_user( $user->ID );
|
|
|
|
|
|
|
842 |
|
843 |
+
// Check whether we have a Stripe Customer.
|
844 |
+
if ( ! empty( $customer ) ) {
|
845 |
+
// Get the link to edit the customer.
|
846 |
+
echo '<hr>';
|
847 |
+
echo '<a target="_blank" href="' . esc_url( 'https://dashboard.stripe.com/' . ( pmpro_getOption( 'gateway_environment' ) == 'sandbox' ? 'test/' : '' ) . 'customers/' . $customer->id ) . '">' . esc_html__( 'Edit customer in Stripe', 'paid-memberships-pro' ) . '</a>';
|
848 |
+
if ( ! empty( $user->pmpro_stripe_updates ) && is_array( $user->pmpro_stripe_updates ) ) {
|
849 |
+
$stripe->user_profile_fields_subscription_updates( $user, $customer );
|
850 |
+
}
|
851 |
}
|
852 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
853 |
|
854 |
/**
|
855 |
+
* Temporary function to allow users to delete subscription updates.
|
856 |
+
* Will be removed once subscription updates are completely deprecated.
|
857 |
*
|
858 |
+
* @since 2.7.0.
|
859 |
*/
|
860 |
static function user_profile_fields_save( $user_id ) {
|
861 |
global $wpdb;
|
|
|
862 |
//check capabilities
|
863 |
$membership_level_capability = apply_filters( "pmpro_edit_member_capability", "manage_options" );
|
864 |
if ( ! current_user_can( $membership_level_capability ) ) {
|
865 |
return false;
|
866 |
}
|
867 |
|
868 |
+
//make sure subscription updates were shown.
|
869 |
+
if ( ! isset( $_POST['pmpro_subscription_updates_visible'] ) ) {
|
870 |
+
return;
|
871 |
+
}
|
872 |
+
|
873 |
+
// Check whether all updates were deleted.
|
874 |
if ( ! isset( $_POST['updates_when'] ) || ! is_array( $_POST['updates_when'] ) ) {
|
875 |
+
delete_user_meta( $user_id, 'pmpro_stripe_updates' );
|
876 |
+
delete_user_meta( $user_id, 'pmpro_stripe_next_on_date_update' );
|
877 |
return;
|
878 |
}
|
879 |
|
881 |
$updates = array();
|
882 |
$next_on_date_update = "";
|
883 |
|
884 |
+
//build array of updates
|
885 |
+
for ( $i = 0; $i < count( $_POST['updates_when'] ); $i ++ ) {
|
886 |
$update = array();
|
887 |
|
888 |
//all updates have these values
|
909 |
|
910 |
//if when is now, update the subscription
|
911 |
if ( $update['when'] == "now" ) {
|
912 |
+
self::updateSubscription( $update, $user_id );
|
913 |
|
914 |
continue;
|
915 |
} elseif ( $update['when'] == 'date' ) {
|
934 |
/**
|
935 |
* Cron activation for subscription updates.
|
936 |
*
|
937 |
+
* The subscription updates menu is no longer accessible as of v2.6.
|
938 |
+
* This function is staying to process subscription updates that were already queued.
|
939 |
+
*
|
940 |
* @since 1.8
|
941 |
*/
|
942 |
+
public static function pmpro_activation() {
|
943 |
pmpro_maybe_schedule_event( time(), 'daily', 'pmpro_cron_stripe_subscription_updates' );
|
944 |
}
|
945 |
|
946 |
/**
|
947 |
* Cron deactivation for subscription updates.
|
948 |
*
|
949 |
+
* The subscription updates menu is no longer accessible as of v2.6.
|
950 |
+
* This function is staying to process subscription updates that were already queued.
|
951 |
+
*
|
952 |
* @since 1.8
|
953 |
*/
|
954 |
+
public static function pmpro_deactivation() {
|
955 |
wp_clear_scheduled_hook( 'pmpro_cron_stripe_subscription_updates' );
|
956 |
}
|
957 |
|
958 |
/**
|
959 |
* Cron job for subscription updates.
|
960 |
*
|
961 |
+
* The subscription updates menu is no longer accessible as of v2.6.
|
962 |
+
* This function is staying to process subscription updates that were already queued.
|
963 |
+
*
|
964 |
* @since 1.8
|
965 |
*/
|
966 |
+
public static function pmpro_cron_stripe_subscription_updates() {
|
967 |
global $wpdb;
|
968 |
|
969 |
//get all updates for today (or before today)
|
1000 |
if ( $ud['when'] == 'date' &&
|
1001 |
$ud['date_year'] . "-" . $ud['date_month'] . "-" . $ud['date_day'] <= date_i18n( "Y-m-d", current_time( 'timestamp' ) )
|
1002 |
) {
|
1003 |
+
self::updateSubscription( $ud, $user_id );
|
1004 |
|
1005 |
//remove update from list
|
1006 |
unset( $user_updates[ $key ] );
|
1030 |
* because of an expired credit card/etc and a user checks out to renew their subscription
|
1031 |
* instead of updating their billing information via the billing info page.
|
1032 |
*/
|
1033 |
+
public static function pmpro_checkout_before_processing() {
|
1034 |
global $wpdb, $current_user;
|
1035 |
|
1036 |
// we're only worried about cases where the user is logged in
|
1074 |
|
1075 |
//so let's cancel the user's susbcription
|
1076 |
if ( ! empty( $last_order ) && ! empty( $last_order->subscription_transaction_id ) ) {
|
1077 |
+
$subscription = $last_order->Gateway->get_subscription( $last_order->subscription_transaction_id );
|
1078 |
if ( ! empty( $subscription ) ) {
|
1079 |
$last_order->Gateway->cancelSubscriptionAtGateway( $subscription, true );
|
1080 |
|
1105 |
}
|
1106 |
|
1107 |
/**
|
1108 |
+
* Filter pmpro_next_payment to get date via API if possible
|
1109 |
+
*
|
1110 |
+
* @since 1.8.6
|
1111 |
*/
|
1112 |
+
public static function pmpro_next_payment( $timestamp, $user_id, $order_status ) {
|
1113 |
+
//find the last order for this user
|
1114 |
+
if ( ! empty( $user_id ) ) {
|
1115 |
+
//get last order
|
1116 |
+
$order = new MemberOrder();
|
1117 |
+
$order->getLastMemberOrder( $user_id, $order_status );
|
|
|
|
|
1118 |
|
1119 |
+
//check if this is a Stripe order with a subscription transaction id
|
1120 |
+
if ( ! empty( $order->id ) && ! empty( $order->subscription_transaction_id ) && $order->gateway == "stripe" ) {
|
1121 |
+
//get the subscription and return the current_period end or false
|
1122 |
+
$subscription = $order->Gateway->get_subscription( $order->subscription_transaction_id );
|
1123 |
+
|
1124 |
+
if ( ! empty( $subscription ) ) {
|
1125 |
+
$customer = $order->Gateway->get_customer_for_user( $user_id );
|
1126 |
+
if ( ! $customer->delinquent && ! empty ( $subscription->current_period_end ) ) {
|
1127 |
+
$offset = get_option( 'gmt_offset' );
|
1128 |
+
$timestamp = $subscription->current_period_end + ( $offset * 3600 );
|
1129 |
+
} elseif ( $customer->delinquent && ! empty( $subscription->current_period_start ) ) {
|
1130 |
+
$offset = get_option( 'gmt_offset' );
|
1131 |
+
$timestamp = $subscription->current_period_start + ( $offset * 3600 );
|
1132 |
+
} else {
|
1133 |
+
$timestamp = null; // shouldn't really get here
|
1134 |
+
}
|
1135 |
+
}
|
1136 |
}
|
1137 |
}
|
1138 |
|
1139 |
+
return $timestamp;
|
|
|
|
|
|
|
|
|
1140 |
}
|
1141 |
|
1142 |
+
public static function pmpro_set_up_apple_pay( $payment_option_values, $gateway ) {
|
1143 |
+
// Check that we just saved Stripe settings.
|
1144 |
+
if ( $gateway != 'stripe' || empty( $_REQUEST['savesettings'] ) ) {
|
1145 |
+
return;
|
1146 |
+
}
|
1147 |
+
|
1148 |
+
// Check that payment request button is enabled.
|
1149 |
+
if ( empty( $payment_option_values['stripe_payment_request_button'] ) ) {
|
1150 |
+
// We don't want to unregister domain or remove file in case
|
1151 |
+
// other plugins are using it.
|
1152 |
+
return;
|
1153 |
+
}
|
1154 |
+
|
1155 |
+
// Make sure that Apple Pay is set up.
|
1156 |
+
// TODO: Apple Pay API functions don't seem to work with
|
1157 |
+
// test API keys. Need to figure this out.
|
1158 |
+
$stripe = new PMProGateway_stripe();
|
1159 |
+
if ( ! $stripe->pmpro_does_apple_pay_domain_exist() ) {
|
1160 |
+
// 1. Make sure domain association file available.
|
1161 |
+
flush_rewrite_rules();
|
1162 |
+
// 2. Register Domain with Apple.
|
1163 |
+
$stripe->pmpro_create_apple_pay_domain();
|
1164 |
+
}
|
1165 |
+
}
|
1166 |
+
|
1167 |
+
/**
|
1168 |
+
* This function is used to save the parameters returned after successfull connection of Stripe account.
|
1169 |
*
|
1170 |
+
* @return void
|
1171 |
*/
|
1172 |
+
public static function stripe_connect_save_options() {
|
1173 |
+
// Is user have permission to edit give setting.
|
1174 |
+
if ( ! current_user_can( 'manage_options' ) ) {
|
1175 |
+
return;
|
1176 |
+
}
|
1177 |
|
1178 |
+
// Be sure only to connect when param present.
|
1179 |
+
if ( ! isset( $_REQUEST['pmpro_stripe_connected'] ) || ! isset( $_REQUEST['pmpro_stripe_connected_environment'] ) ) {
|
1180 |
+
return false;
|
1181 |
}
|
1182 |
+
|
1183 |
+
// Change current gateway to Stripe
|
1184 |
+
pmpro_setOption( 'gateway', 'stripe' );
|
1185 |
+
pmpro_setOption( 'gateway_environment', $_REQUEST['pmpro_stripe_connected_environment'] );
|
1186 |
+
|
1187 |
+
$error = '';
|
1188 |
+
if (
|
1189 |
+
'false' === $_REQUEST['pmpro_stripe_connected']
|
1190 |
+
&& isset( $_REQUEST['error_message'] )
|
1191 |
+
) {
|
1192 |
+
$error = $_REQUEST['error_message'];
|
1193 |
+
} elseif (
|
1194 |
+
'false' === $_REQUEST['pmpro_stripe_connected']
|
1195 |
+
|| ! isset( $_REQUEST['pmpro_stripe_publishable_key'] )
|
1196 |
+
|| ! isset( $_REQUEST['pmpro_stripe_user_id'] )
|
1197 |
+
|| ! isset( $_REQUEST['pmpro_stripe_access_token'] )
|
1198 |
+
) {
|
1199 |
+
$error = __( 'Invalid response from the Stripe Connect server.', 'paid-memberships-pro' );
|
1200 |
+
} else {
|
1201 |
+
// Update keys.
|
1202 |
+
if ( $_REQUEST['pmpro_stripe_connected_environment'] === 'live' ) {
|
1203 |
+
// Update live keys.
|
1204 |
+
pmpro_setOption( 'live_stripe_connect_user_id', $_REQUEST['pmpro_stripe_user_id'] );
|
1205 |
+
pmpro_setOption( 'live_stripe_connect_secretkey', $_REQUEST['pmpro_stripe_access_token'] );
|
1206 |
+
pmpro_setOption( 'live_stripe_connect_publishablekey', $_REQUEST['pmpro_stripe_publishable_key'] );
|
1207 |
+
} else {
|
1208 |
+
// Update sandbox keys.
|
1209 |
+
pmpro_setOption( 'sandbox_stripe_connect_user_id', $_REQUEST['pmpro_stripe_user_id'] );
|
1210 |
+
pmpro_setOption( 'sandbox_stripe_connect_secretkey', $_REQUEST['pmpro_stripe_access_token'] );
|
1211 |
+
pmpro_setOption( 'sandbox_stripe_connect_publishablekey', $_REQUEST['pmpro_stripe_publishable_key'] );
|
1212 |
+
}
|
1213 |
+
|
1214 |
|
1215 |
+
// Delete option for user API key.
|
1216 |
+
delete_option( 'pmpro_stripe_secretkey' );
|
1217 |
+
delete_option( 'pmpro_stripe_publishablekey' );
|
1218 |
+
|
1219 |
+
wp_redirect( admin_url( 'admin.php?page=pmpro-paymentsettings' ) );
|
1220 |
+
exit;
|
1221 |
}
|
1222 |
|
1223 |
+
if ( ! empty( $error ) ) {
|
1224 |
+
global $pmpro_stripe_error;
|
1225 |
+
$pmpro_stripe_error = sprintf(
|
1226 |
+
/* translators: %s Error Message */
|
1227 |
+
__( '<strong>Error:</strong> PMPro could not connect to the Stripe API. Reason: %s', 'paid-memberships-pro' ),
|
1228 |
+
esc_html( $error )
|
1229 |
+
);
|
1230 |
+
}
|
1231 |
+
}
|
1232 |
|
1233 |
+
public static function stripe_connect_show_errors() {
|
1234 |
+
global $pmpro_stripe_error;
|
1235 |
+
if ( ! empty( $pmpro_stripe_error ) ) {
|
1236 |
+
$class = 'notice notice-error pmpro-stripe-connect-message';
|
1237 |
+
printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), $pmpro_stripe_error );
|
1238 |
+
}
|
1239 |
+
}
|
1240 |
|
1241 |
+
/**
|
1242 |
+
* Disconnects user from the Stripe Connected App.
|
1243 |
+
*/
|
1244 |
+
public static function stripe_connect_deauthorize() {
|
1245 |
+
if ( ! current_user_can( 'manage_options' ) ) {
|
1246 |
+
return;
|
1247 |
+
}
|
1248 |
|
1249 |
+
// Be sure only to deauthorize when param present.
|
1250 |
+
if ( ! isset( $_REQUEST['pmpro_stripe_disconnected'] ) || ! isset( $_REQUEST['pmpro_stripe_disconnected_environment'] ) ) {
|
1251 |
return false;
|
1252 |
}
|
1253 |
|
1254 |
+
// Show message if NOT disconnected.
|
1255 |
+
if (
|
1256 |
+
'false' === $_REQUEST['pmpro_stripe_disconnected']
|
1257 |
+
&& isset( $_REQUEST['error_code'] )
|
1258 |
+
) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1259 |
|
1260 |
+
$class = 'notice notice-warning pmpro-stripe-disconnect-message';
|
1261 |
+
$message = sprintf(
|
1262 |
+
/* translators: %s Error Message */
|
1263 |
+
__( '<strong>Error:</strong> PMPro could not disconnect from the Stripe API. Reason: %s', 'paid-memberships-pro' ),
|
1264 |
+
esc_html( $_REQUEST['error_message'] )
|
1265 |
+
);
|
1266 |
|
1267 |
+
printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), $message );
|
|
|
1268 |
|
1269 |
+
}
|
|
|
|
|
|
|
|
|
1270 |
|
1271 |
+
if ( $_REQUEST['pmpro_stripe_disconnected_environment'] === 'live' ) {
|
1272 |
+
// Delete live keys.
|
1273 |
+
delete_option( 'pmpro_live_stripe_connect_user_id' );
|
1274 |
+
delete_option( 'pmpro_live_stripe_connect_secretkey' );
|
1275 |
+
delete_option( 'pmpro_live_stripe_connect_publishablekey' );
|
1276 |
} else {
|
1277 |
+
// Delete sandbox keys.
|
1278 |
+
delete_option( 'pmpro_sandbox_stripe_connect_user_id' );
|
1279 |
+
delete_option( 'pmpro_sandbox_stripe_connect_secretkey' );
|
1280 |
+
delete_option( 'pmpro_sandbox_stripe_connect_publishablekey' );
|
|
|
|
|
1281 |
}
|
1282 |
}
|
1283 |
|
1284 |
/**
|
1285 |
+
* Determine whether the site is using legacy Stripe keys.
|
1286 |
*
|
1287 |
+
* @return bool Whether the site is using legacy Stripe keys.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1288 |
*/
|
1289 |
+
public static function using_legacy_keys() {
|
1290 |
+
$r = ! empty( pmpro_getOption( 'stripe_secretkey' ) ) && ! empty( pmpro_getOption( 'stripe_publishablekey' ) );
|
1291 |
+
return $r;
|
1292 |
+
}
|
1293 |
|
1294 |
+
/**
|
1295 |
+
* Determine whether the site has Stripe Connect credentials set based on gateway environment.
|
1296 |
+
*
|
1297 |
+
* @param null|string $gateway_environment The gateway environment to use, default uses the current saved setting.
|
1298 |
+
*
|
1299 |
+
* @return bool Whether the site has Stripe Connect credentials set.
|
1300 |
+
*/
|
1301 |
+
public static function has_connect_credentials( $gateway_environment = null ) {
|
1302 |
+
if ( empty( $gateway_environment ) ) {
|
1303 |
+
$gateway_engvironemnt = pmpro_getOption( 'pmpro_gateway_environment' );
|
1304 |
}
|
1305 |
|
1306 |
+
if ( $gateway_environment === 'live' ) {
|
1307 |
+
// Return whether Stripe is connected for live gateway environment.
|
1308 |
+
return (
|
1309 |
+
pmpro_getOption( 'live_stripe_connect_user_id' ) &&
|
1310 |
+
pmpro_getOption( 'live_stripe_connect_secretkey' ) &&
|
1311 |
+
pmpro_getOption( 'live_stripe_connect_publishablekey' )
|
1312 |
+
);
|
1313 |
+
} else {
|
1314 |
+
// Return whether Stripe is connected for sandbox gateway environment.
|
1315 |
+
return (
|
1316 |
+
pmpro_getOption( 'sandbox_stripe_connect_user_id' ) &&
|
1317 |
+
pmpro_getOption( 'sandbox_stripe_connect_secretkey' ) &&
|
1318 |
+
pmpro_getOption( 'sandbox_stripe_connect_publishablekey' )
|
1319 |
+
);
|
1320 |
}
|
1321 |
+
}
|
1322 |
|
1323 |
+
/**
|
1324 |
+
* Warn if required extensions aren't loaded.
|
1325 |
+
*
|
1326 |
+
* @return bool
|
1327 |
+
* @since 1.8.6.8.1
|
1328 |
+
* @since 1.8.13.6 - Add json dependency
|
1329 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
1330 |
+
*/
|
1331 |
+
public static function dependencies() {
|
1332 |
+
global $msg, $msgt, $pmpro_stripe_error;
|
1333 |
|
1334 |
+
if ( version_compare( PHP_VERSION, '5.3.29', '<' ) ) {
|
|
|
|
|
|
|
1335 |
|
1336 |
+
$pmpro_stripe_error = true;
|
1337 |
+
$msg = - 1;
|
1338 |
+
$msgt = sprintf( __( "The Stripe Gateway requires PHP 5.3.29 or greater. We recommend upgrading to PHP %s or greater. Ask your host to upgrade.", "paid-memberships-pro" ), PMPRO_PHP_MIN_VERSION );
|
|
|
|
|
1339 |
|
1340 |
+
if ( ! is_admin() ) {
|
1341 |
+
pmpro_setMessage( $msgt, "pmpro_error" );
|
|
|
|
|
|
|
|
|
|
|
1342 |
}
|
1343 |
|
1344 |
+
return false;
|
1345 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1346 |
|
1347 |
+
$modules = array( 'curl', 'mbstring', 'json' );
|
|
|
1348 |
|
1349 |
+
foreach ( $modules as $module ) {
|
1350 |
+
if ( ! extension_loaded( $module ) ) {
|
1351 |
+
$pmpro_stripe_error = true;
|
1352 |
+
$msg = - 1;
|
1353 |
+
$msgt = sprintf( __( "The %s gateway depends on the %s PHP extension. Please enable it, or ask your hosting provider to enable it.", 'paid-memberships-pro' ), 'Stripe', $module );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1354 |
|
1355 |
+
//throw error on checkout page
|
1356 |
+
if ( ! is_admin() ) {
|
1357 |
+
pmpro_setMessage( $msgt, 'pmpro_error' );
|
|
|
1358 |
}
|
1359 |
|
1360 |
+
return false;
|
|
|
|
|
|
|
1361 |
}
|
1362 |
}
|
1363 |
|
1364 |
+
self::$is_loaded = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1365 |
|
1366 |
+
return true;
|
1367 |
+
}
|
1368 |
|
1369 |
+
/****************************************
|
1370 |
+
************ PUBLIC METHODS ************
|
1371 |
+
****************************************/
|
1372 |
+
/**
|
1373 |
+
* Process checkout and decide if a charge and or subscribe is needed
|
1374 |
+
* Updated in v2.1 to work with Stripe v3 payment intents.
|
1375 |
+
* @since 1.4
|
1376 |
+
*/
|
1377 |
+
public function process( &$order ) {
|
1378 |
+
$payment_transaction_id = '';
|
1379 |
+
$subscription_transaction_id = '';
|
1380 |
+
|
1381 |
+
if ( ! empty( $order->setup_intent_id ) ){
|
1382 |
+
// The user tried to confirm a setup intent. This means that there was no initial
|
1383 |
+
// payment needed for this chekout (otherwise there would be a payment intent instead),
|
1384 |
+
// and that the subscription needed authorization before being created.
|
1385 |
+
$setup_intent = $this->process_setup_intent( $order->setup_intent_id );
|
1386 |
+
if ( is_string( $setup_intent ) ) {
|
1387 |
+
$order->error = __( 'Error processing setup intent.', 'paid-memberships-pro' ) . ' ' . $setup_intent;
|
1388 |
+
$order->shorterror = $order->error;
|
1389 |
+
return false;
|
1390 |
}
|
1391 |
+
// Subscription should now be active. Let's get its ID to save to the MemberOrder.
|
1392 |
+
$subscription_transaction_id = $setup_intent->metadata->subscription_id;
|
|
|
|
|
|
|
|
|
1393 |
} else {
|
1394 |
+
// User has either just submitted the checkout form or tried to confirm their
|
1395 |
+
// payment intent.
|
1396 |
+
$customer = null; // This will be used to create the subscription later.
|
1397 |
+
if ( ! empty( $order->payment_intent_id ) ) {
|
1398 |
+
// User has just tried to confirm their payment intent. We need to make sure that it was
|
1399 |
+
// confirmed successfully, and then try to create their subscription if needed.
|
1400 |
+
$payment_intent = $this->process_payment_intent( $order->payment_intent_id );
|
1401 |
+
if ( is_string( $payment_intent ) ) {
|
1402 |
+
$order->error = __( 'Error processing payment intent.', 'paid-memberships-pro' ) . ' ' . $payment_intent;
|
1403 |
+
$order->shorterror = $order->error;
|
1404 |
+
return false;
|
1405 |
+
}
|
1406 |
+
// Payment should now be processed.
|
1407 |
+
$payment_transaction_id = $payment_intent->charges->data[0]->id;
|
1408 |
|
1409 |
+
// Note the customer so that we can create a subscription if needed..
|
1410 |
+
$customer = $payment_intent->customer;
|
1411 |
+
} else {
|
1412 |
+
// We have not yet tried to process this checkout.
|
1413 |
+
// Make sure we have a customer with a payment method.
|
1414 |
+
$customer = $this->update_customer_at_checkout( $order );
|
1415 |
+
if ( empty( $customer ) ) {
|
1416 |
+
// There was an issue creating/updating the Stripe customer.
|
1417 |
+
// $order will have an error message, so we don't need to add one.
|
1418 |
+
return false;
|
1419 |
+
}
|
1420 |
|
1421 |
+
$payment_method = $this->get_payment_method( $order );
|
1422 |
+
if ( empty( $payment_method ) ) {
|
1423 |
+
// There was an issue getting the payment method.
|
1424 |
+
$order->error = __( 'Error retrieving payment method.', 'paid-memberships-pro' );
|
1425 |
+
$order->shorterror = $order->error;
|
1426 |
+
return false;
|
|
|
|
|
|
|
1427 |
}
|
1428 |
|
1429 |
+
$customer = $this->set_default_payment_method_for_customer( $customer, $payment_method );
|
1430 |
+
if ( is_string( $customer ) ) {
|
1431 |
+
// There was an issue updating the default payment method.
|
1432 |
+
$order->error = __( 'Error updating default payment method.', 'paid-memberships-pro' ) . ' ' . $customer;
|
1433 |
+
$order->shorterror = $order->error;
|
1434 |
+
return false;
|
1435 |
+
}
|
|
|
|
|
|
|
|
|
|
|
1436 |
|
1437 |
+
// Save customer in $order for create_payment_intent().
|
1438 |
+
// This will likely be removed as we rework payment processing.
|
1439 |
+
$order->stripe_customer = $customer;
|
1440 |
+
|
1441 |
+
// Process the charges.
|
1442 |
+
$charges_processed = $this->process_charges( $order );
|
1443 |
+
if ( ! empty( $order->error ) ) {
|
1444 |
+
// There was an error processing charges.
|
1445 |
+
// $order has an error message, so we don't need to add one.
|
1446 |
+
return false;
|
1447 |
}
|
1448 |
|
1449 |
+
// If we needed to charge an initial payment, it was successful.
|
1450 |
+
if ( ! empty( $order->stripe_payment_intent->charges->data[0]->id ) ) {
|
1451 |
+
$payment_transaction_id = $order->stripe_payment_intent->charges->data[0]->id;
|
1452 |
+
}
|
|
|
1453 |
}
|
|
|
1454 |
|
1455 |
+
// Create a subscription if we need to.
|
1456 |
+
if ( pmpro_isLevelRecurring( $order->membership_level ) ) {
|
1457 |
+
$subscription = $this->create_subscription_for_customer_from_order( $customer->id, $order );
|
1458 |
+
if ( empty( $subscription ) ) {
|
1459 |
+
// There was an issue creating the subscription.
|
1460 |
+
$order->error = __( 'Error creating subscription for customer.', 'paid-memberships-pro' );
|
1461 |
+
$order->shorterror = $order->error;
|
1462 |
+
return false;
|
1463 |
+
}
|
1464 |
+
$order->stripe_subscription = $subscription;
|
1465 |
+
$setup_intent = $subscription->pending_setup_intent;
|
1466 |
+
|
1467 |
+
if ( ! empty( $setup_intent->status ) && 'requires_action' === $setup_intent->status ) {
|
1468 |
+
// We will need to reload the page to authenticate, so save the subscription ID in the setup intent
|
1469 |
+
// so that we don't lose it.
|
1470 |
+
$setup_intent = $this->add_subscription_id_to_setup_intent( $setup_intent, $subscription->id );
|
1471 |
+
if ( is_string( $setup_intent ) ) {
|
1472 |
+
$order->error = $setup_intent;
|
1473 |
+
$order->shorterror = $order->error;
|
1474 |
+
return false;
|
1475 |
+
}
|
1476 |
+
$order->stripe_setup_intent = $setup_intent;
|
1477 |
+
$order->errorcode = true;
|
1478 |
+
$order->error = __( 'Customer authentication is required to finish setting up your subscription. Please complete the verification steps issued by your payment provider.', 'paid-memberships-pro' );
|
1479 |
+
|
1480 |
+
return false;
|
1481 |
+
}
|
1482 |
|
1483 |
+
// Successfully created a subscription.
|
1484 |
+
$subscription_transaction_id = $subscription->id;
|
1485 |
+
}
|
1486 |
+
}
|
1487 |
+
// All charges have been processed and all subscriptions have been created.
|
1488 |
+
$order->payment_transaction_id = $payment_transaction_id;
|
1489 |
+
$order->subscription_transaction_id = $subscription_transaction_id;
|
1490 |
+
$order->status = 'success';
|
1491 |
+
$order->saveOrder();
|
1492 |
+
return true;
|
1493 |
+
}
|
1494 |
|
1495 |
+
/**
|
1496 |
+
* Retrieve a Stripe_Customer for a given user.
|
1497 |
+
*
|
1498 |
+
* @since 2.7.0
|
1499 |
+
*
|
1500 |
+
* @param int $user_id to get Stripe_Customer for.
|
1501 |
+
* @return Stripe_Customer|null
|
1502 |
+
*/
|
1503 |
+
public function get_customer_for_user( $user_id ) {
|
1504 |
+
// Pull Stripe customer ID from user meta.
|
1505 |
+
$customer_id = get_user_meta( $user_id, 'pmpro_stripe_customerid', true );
|
1506 |
+
|
1507 |
+
if ( empty( $customer_id ) ) {
|
1508 |
+
// Try to figure out the cuseromer ID from their last order.
|
1509 |
+
if ( empty ( $order ) ) {
|
1510 |
+
$order = new MemberOrder();
|
1511 |
+
$order->getLastMemberOrder(
|
1512 |
+
$user_id,
|
1513 |
+
array(
|
1514 |
+
'success',
|
1515 |
+
'cancelled'
|
1516 |
+
),
|
1517 |
+
null,
|
1518 |
+
'stripe',
|
1519 |
+
$order->Gateway->gateway_environment
|
1520 |
+
);
|
1521 |
+
}
|
1522 |
|
1523 |
+
// If we don't have a customer ID yet, get the Customer ID from their subscription.
|
1524 |
+
if ( empty( $customer_id ) && ! empty( $order->subscription_transaction_id ) && strpos( $order->subscription_transaction_id, "sub_" ) !== false ) {
|
1525 |
+
try {
|
1526 |
+
$subscription = Stripe_Subscription::retrieve( $order->subscription_transaction_id );
|
1527 |
+
} catch ( \Throwable $e ) {
|
1528 |
+
// Assume no customer found.
|
1529 |
+
} catch ( \Exception $e ) {
|
1530 |
+
// Assume no customer found.
|
1531 |
+
}
|
1532 |
+
if ( ! empty( $subscription ) && ! empty( $subscription->customer ) ) {
|
1533 |
+
$customer_id = $subscription->customer;
|
1534 |
+
}
|
1535 |
}
|
1536 |
|
1537 |
+
// If we don't have a customer ID yet, get the Customer ID from their charge.
|
1538 |
+
if ( empty( $customer_id ) && ! empty( $order->payment_transaction_id ) && strpos( $order->payment_transaction_id, "ch_" ) !== false ) {
|
1539 |
+
try {
|
1540 |
+
$charge = Stripe_Charge::retrieve( $order->payment_transaction_id );
|
1541 |
+
} catch ( \Throwable $e ) {
|
1542 |
+
// Assume no customer found.
|
1543 |
+
} catch ( \Exception $e ) {
|
1544 |
+
// Assume no customer found.
|
1545 |
+
}
|
1546 |
+
if ( ! empty( $charge ) && ! empty( $charge->customer ) ) {
|
1547 |
+
$customer_id = $charge->customer;
|
1548 |
+
}
|
1549 |
+
}
|
1550 |
|
1551 |
+
// If we don't have a customer ID yet, get the Customer ID from their invoice.
|
1552 |
+
if ( empty( $customer_id ) && ! empty( $order->payment_transaction_id ) && strpos( $order->payment_transaction_id, "in_" ) !== false ) {
|
1553 |
+
try {
|
1554 |
+
$invoice = Stripe_Invoice::retrieve( $order->payment_transaction_id );
|
1555 |
+
} catch ( \Throwable $e ) {
|
1556 |
+
// Assume no customer found.
|
1557 |
+
} catch ( \Exception $e ) {
|
1558 |
+
// Assume no customer found.
|
1559 |
+
}
|
1560 |
+
if ( ! empty( $invoice ) && ! empty( $invoice->customer ) ) {
|
1561 |
+
$customer_id = $invoice->customer;
|
1562 |
}
|
1563 |
}
|
1564 |
|
1565 |
+
if ( ! empty( $customer_id ) ) {
|
1566 |
+
update_user_meta( $user_id, "pmpro_stripe_customerid", $customer_id );
|
1567 |
+
}
|
1568 |
}
|
1569 |
|
1570 |
+
return empty( $customer_id ) ? null : $this->get_customer( $customer_id );
|
1571 |
}
|
1572 |
|
1573 |
/**
|
1574 |
+
* Create/Update Stripe customer for a user.
|
1575 |
*
|
1576 |
+
* @since 2.7.0
|
1577 |
+
*
|
1578 |
+
* @param int $user_id to create/update Stripe customer for.
|
1579 |
+
* @return Stripe_Customer|false
|
1580 |
*/
|
1581 |
+
public function update_customer_from_user( $user_id ) {
|
1582 |
+
$user = get_userdata( $user_id );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1583 |
|
1584 |
+
if ( empty( $user->ID ) ) {
|
1585 |
+
// User does not exist.
|
1586 |
return false;
|
1587 |
}
|
1588 |
|
1589 |
+
// Get the existing customer from Stripe.
|
1590 |
+
$customer = $this->get_customer_for_user( $user_id );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1591 |
|
1592 |
+
// Get the name for the customer.
|
1593 |
+
$name = trim( $user->first_name . " " . $user->last_name );
|
1594 |
+
if ( empty( $name ) ) {
|
1595 |
+
// In case first and last names aren't set.
|
1596 |
+
$name = $user->user_login;
|
1597 |
}
|
1598 |
|
1599 |
+
// Get data to update customer with.
|
1600 |
+
$customer_args = array(
|
1601 |
+
'email' => $user->user_email,
|
1602 |
+
'description' => $name . ' (' . $email . ')',
|
1603 |
+
);
|
1604 |
|
1605 |
+
// Maybe update billing address for customer.
|
1606 |
+
if (
|
1607 |
+
! $this->customer_has_billing_address( $customer ) &&
|
1608 |
+
! empty( $user->pmpro_baddress1 ) &&
|
1609 |
+
! empty( $user->pmpro_bcity ) &&
|
1610 |
+
! empty( $user->pmpro_bstate ) &&
|
1611 |
+
! empty( $user->pmpro_bzipcode ) &&
|
1612 |
+
! empty( $user->pmpro_bcountry )
|
1613 |
+
) {
|
1614 |
+
// We have an address in user meta and there is
|
1615 |
+
// no address in Stripe. May as well send it.
|
1616 |
+
$customer_args['address'] = array(
|
1617 |
+
'city' => $user->pmpro_bcity,
|
1618 |
+
'country' => $user->pmpro_bcountry,
|
1619 |
+
'line1' => $user->pmpro_baddress1,
|
1620 |
+
'line2' => $user->pmpro_baddress2,
|
1621 |
+
'postal_code' => $user->pmpro_bzipcode,
|
1622 |
+
'state' => $user->pmpro_bstate,
|
1623 |
+
);
|
1624 |
}
|
1625 |
|
1626 |
+
/**
|
1627 |
+
* Change the information that is sent when updating/creating
|
1628 |
+
* a Stripe_Customer from a user.
|
1629 |
+
*
|
1630 |
+
* @since 2.7.0
|
1631 |
+
*
|
1632 |
+
* @param array $customer_args to be sent.
|
1633 |
+
* @param WP_User $user being used to create/update customer.
|
1634 |
+
*/
|
1635 |
+
$customer_args = apply_filters( 'pmpro_stripe_update_customer_from_user', $customer_args, $user );
|
1636 |
|
1637 |
+
// Update the customer.
|
1638 |
+
if ( empty( $customer ) ) {
|
1639 |
+
// We need to build a new customer.
|
1640 |
+
$customer = $this->create_customer( $customer_args );
|
1641 |
+
} else {
|
1642 |
+
// Update the existing customer.
|
1643 |
+
$customer = $this->update_customer( $customer->ID, $customer_args );
|
1644 |
}
|
1645 |
+
return is_string( $customer ) ? false : $customer;
|
|
|
|
|
1646 |
}
|
1647 |
|
1648 |
/**
|
1650 |
*
|
1651 |
* @since 2.3
|
1652 |
*/
|
1653 |
+
public function getSubscriptionStatus( &$order ) {
|
1654 |
+
$subscription = $this->get_subscription( $order->subscription_transaction_id );
|
1655 |
|
1656 |
if ( ! empty( $subscription ) ) {
|
1657 |
return $subscription->status;
|
1661 |
}
|
1662 |
|
1663 |
/**
|
1664 |
+
* Helper method to update the customer info via update_customer_at_checkout
|
1665 |
*
|
1666 |
* @since 1.4
|
1667 |
*/
|
1668 |
+
public function update( &$order ) {
|
1669 |
+
$customer = $this->update_customer_at_checkout( $order );
|
1670 |
+
if ( empty( $customer ) ) {
|
1671 |
+
// There was an issue creating/updating the Stripe customer.
|
1672 |
+
// $order will have an error message, so we don't need to add one.
|
1673 |
+
return false;
|
|
|
|
|
1674 |
}
|
1675 |
|
1676 |
+
$payment_method = $this->get_payment_method( $order );
|
1677 |
+
if ( empty( $payment_method ) ) {
|
1678 |
+
// There was an issue getting the payment method.
|
1679 |
+
$order->error = __( "Error retrieving payment method.", 'paid-memberships-pro' );
|
1680 |
+
$order->shorterror = $order->error;
|
1681 |
+
return false;
|
1682 |
}
|
1683 |
|
1684 |
+
$customer = $this->set_default_payment_method_for_customer( $customer, $payment_method );
|
1685 |
+
if ( is_string( $customer ) ) {
|
1686 |
+
// There was an issue updating the default payment method.
|
1687 |
+
$order->error = __( "Error updating default payment method.", 'paid-memberships-pro' ) . " " . $customer;
|
1688 |
+
$order->shorterror = $order->error;
|
1689 |
+
return false;
|
|
|
|
|
|
|
1690 |
}
|
1691 |
|
1692 |
+
if ( ! $this->update_payment_method_for_subscriptions( $order ) ) {
|
1693 |
+
$order->error = __( "Error updating payment method for subscription.", 'paid-memberships-pro' );
|
1694 |
+
$order->shorterror = $order->error;
|
1695 |
+
return false;
|
|
|
1696 |
}
|
1697 |
|
1698 |
+
return true;
|
1699 |
+
}
|
|
|
1700 |
|
1701 |
+
/**
|
1702 |
+
* Cancel a subscription at Stripe
|
1703 |
+
*
|
1704 |
+
* @since 1.4
|
1705 |
+
*/
|
1706 |
+
public function cancel( &$order, $update_status = true ) {
|
1707 |
+
global $pmpro_stripe_event;
|
1708 |
|
1709 |
+
//no matter what happens below, we're going to cancel the order in our system
|
1710 |
+
if ( $update_status ) {
|
1711 |
+
$order->updateStatus( "cancelled" );
|
1712 |
+
}
|
1713 |
|
1714 |
+
//require a subscription id
|
1715 |
+
if ( empty( $order->subscription_transaction_id ) ) {
|
1716 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1717 |
}
|
1718 |
|
1719 |
+
//find the customer
|
1720 |
+
$result = $this->update_customer_at_checkout( $order );
|
1721 |
|
1722 |
+
if ( ! empty( $result ) ) {
|
1723 |
+
//find subscription with this order code
|
1724 |
+
$subscription = $this->get_subscription( $order->subscription_transaction_id );
|
1725 |
|
1726 |
+
if ( ! empty( $subscription )
|
1727 |
+
&& ( empty( $pmpro_stripe_event ) || empty( $pmpro_stripe_event->type ) || $pmpro_stripe_event->type != 'customer.subscription.deleted' ) ) {
|
1728 |
+
if ( $this->cancelSubscriptionAtGateway( $subscription ) ) {
|
1729 |
+
//we're okay, going to return true later
|
1730 |
+
} else {
|
1731 |
+
$order->error = __( "Could not cancel old subscription.", 'paid-memberships-pro' );
|
1732 |
+
$order->shorterror = $order->error;
|
1733 |
|
1734 |
+
return false;
|
1735 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1736 |
}
|
|
|
|
|
|
|
1737 |
|
1738 |
+
/*
|
1739 |
+
Clear updates for this user. (But not if checking out, we would have already done that.)
|
1740 |
*/
|
1741 |
+
if ( empty( $_REQUEST['submit-checkout'] ) ) {
|
1742 |
+
update_user_meta( $order->user_id, "pmpro_stripe_updates", array() );
|
1743 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1744 |
|
1745 |
+
return true;
|
1746 |
+
} else {
|
1747 |
+
$order->error = __( "Could not find the customer.", 'paid-memberships-pro' );
|
1748 |
$order->shorterror = $order->error;
|
1749 |
|
1750 |
+
return false; //no customer found
|
1751 |
}
|
1752 |
+
}
|
1753 |
|
|
|
|
|
|
|
|
|
|
|
1754 |
|
1755 |
+
/****************************************
|
1756 |
+
*********** PRIVATE METHODS ************
|
1757 |
+
****************************************/
|
1758 |
+
/**
|
1759 |
+
* Shows settings for connecting to Stripe.
|
1760 |
+
*
|
1761 |
+
* @since 2.7.0.
|
1762 |
+
*
|
1763 |
+
* @param bool $livemode True if live credentials, false if sandbox.
|
1764 |
+
* @param array $values Current settings.
|
1765 |
+
* @param string $gateway currently being shown.
|
1766 |
+
*/
|
1767 |
+
private function show_connect_payment_option_fields( $livemode = true, $values, $gateway ) {
|
1768 |
+
$gateway_environment = $this->gateway_environment;
|
1769 |
+
|
1770 |
+
$stripe_legacy_key = $values['stripe_publishablekey'];
|
1771 |
+
$stripe_legacy_secret = $values['stripe_secretkey'];
|
1772 |
+
$stripe_is_legacy_setup = ( self::using_legacy_keys() && ! empty( $stripe_legacy_key ) && ! empty( $stripe_legacy_secret ) );
|
1773 |
|
1774 |
+
$environment = $livemode ? 'live' : 'sandbox';
|
1775 |
+
$environment2 = $livemode ? 'live' : 'test'; // For when 'test' is used instead of 'sandbox'.
|
1776 |
+
|
1777 |
+
// Determine if the gateway is connected in live mode and set var.
|
1778 |
+
if ( self::has_connect_credentials( $environment ) || $stripe_is_legacy_setup ) {
|
1779 |
+
$connection_selector = 'pmpro_gateway-mode-connected';
|
1780 |
+
} else {
|
1781 |
+
$connection_selector = 'pmpro_gateway-mode-not-connected';
|
1782 |
}
|
1783 |
|
1784 |
+
?>
|
1785 |
+
<tr class="pmpro_settings_divider gateway gateway_stripe_<?php echo $environment; ?>"
|
1786 |
+
<?php if ( $gateway != "stripe" || $gateway_environment != $environment ) { ?>style="display: none;"<?php } ?>>
|
1787 |
+
<td colspan="2">
|
1788 |
+
<hr />
|
1789 |
+
<h2>
|
1790 |
+
<?php esc_html_e( 'Stripe Connect Settings', 'paid-memberships-pro' ); ?>
|
1791 |
+
<span class="pmpro_gateway-mode pmpro_gateway-mode-<?php echo $environment2; ?> <?php esc_attr_e( $connection_selector ); ?>">
|
1792 |
+
<?php
|
1793 |
+
echo ( $livemode ? esc_html__( 'Live Mode:', 'paid-memberships-pro' ) : esc_html__( 'Test Mode:', 'paid-memberships-pro' ) ) . ' ';
|
1794 |
+
if ( self::has_connect_credentials( $environment ) ) {
|
1795 |
+
esc_html_e( 'Connected', 'paid-memberships-pro' );
|
1796 |
+
} elseif( $stripe_is_legacy_setup ) {
|
1797 |
+
esc_html_e( 'Connected with Legacy Keys', 'paid-memberships-pro' );
|
1798 |
+
} else {
|
1799 |
+
esc_html_e( 'Not Connected', 'paid-memberships-pro' );
|
1800 |
+
}
|
1801 |
+
?>
|
1802 |
+
</span>
|
1803 |
+
</h2>
|
1804 |
+
<?php if ( self::using_legacy_keys() ) { ?>
|
1805 |
+
<div class="notice notice-large notice-warning inline">
|
1806 |
+
<p class="pmpro_stripe_webhook_notice">
|
1807 |
+
<strong><?php esc_html_e( 'Your site is using legacy API keys to authenticate with Stripe.', 'paid-memberships-pro' ); ?></strong><br />
|
1808 |
+
<?php esc_html_e( 'You can continue to use the legacy API keys or choose to upgrade to our new Stripe Connect solution below.', 'paid-memberships-pro' ); ?><br />
|
1809 |
+
<?php
|
1810 |
+
if ( $livemode ) {
|
1811 |
+
esc_html_e( 'Use the "Connect with Stripe" button below to securely authenticate with your Stripe account using Stripe Connect. Log in with the current Stripe account used for this site so that existing subscriptions are not affected by the update.', 'paid-memberships-pro' );
|
1812 |
+
} else {
|
1813 |
+
esc_html_e( 'Use the "Connect with Stripe" button below to securely authenticate with your Stripe account using Stripe Connect in test mode.', 'paid-memberships-pro' );
|
1814 |
+
}
|
1815 |
+
?>
|
1816 |
+
<a href="https://www.paidmembershipspro.com/gateway/stripe/switch-legacy-to-connect/?utm_source=plugin&utm_medium=pmpro-paymentsettings&utm_campaign=documentation&utm_content=switch-to-connect" target="_blank"><?php esc_html_e( 'Read the documentation on switching to Stripe Connect »', 'paid-memberships-pro' ); ?></a>
|
1817 |
+
</p>
|
1818 |
+
</div>
|
1819 |
+
<?php } ?>
|
1820 |
+
</td>
|
1821 |
+
</tr>
|
1822 |
+
<tr class="gateway gateway_stripe_<?php echo $environment; ?>" <?php if ( $gateway != "stripe" || $gateway_environment != $environment ) { ?>style="display: none;"<?php } ?>>
|
1823 |
+
<th scope="row" valign="top">
|
1824 |
+
<label><?php esc_html_e( 'Stripe Connection:', 'paid-memberships-pro' ); ?></label>
|
1825 |
+
</th>
|
1826 |
+
<td>
|
1827 |
+
<?php
|
1828 |
+
$connect_url_base = apply_filters( 'pmpro_stripe_connect_url', 'https://connect.paidmembershipspro.com' );
|
1829 |
+
if ( self::has_connect_credentials( $environment ) ) {
|
1830 |
+
$connect_url = add_query_arg(
|
1831 |
+
array(
|
1832 |
+
'action' => 'disconnect',
|
1833 |
+
'gateway_environment' => $environment2,
|
1834 |
+
'stripe_user_id' => $values[ $environment . '_stripe_connect_user_id'],
|
1835 |
+
'return_url' => rawurlencode( admin_url( 'admin.php?page=pmpro-paymentsettings' ) ),
|
1836 |
+
),
|
1837 |
+
$connect_url_base
|
1838 |
+
);
|
1839 |
+
?>
|
1840 |
+
<a href="<?php echo esc_url_raw( $connect_url ); ?>" class="pmpro-stripe-connect"><span><?php esc_html_e( 'Disconnect From Stripe', 'paid-memberships-pro' ); ?></span></a>
|
1841 |
+
<p class="description">
|
1842 |
+
<?php
|
1843 |
+
if ( $livemode ) {
|
1844 |
+
esc_html_e( 'This will disconnect your site from Stripe. Users will not be able to complete membership checkout or update their billing information. Existing subscriptions will not be affected at the gateway, but new recurring orders will not be created in this site.', 'paid-memberships-pro' );
|
1845 |
+
} else {
|
1846 |
+
esc_html_e( 'This will disconnect your site from Stripe in test mode only.', 'paid-memberships-pro' );
|
1847 |
+
}
|
1848 |
+
?>
|
1849 |
+
</p>
|
1850 |
+
<?php
|
1851 |
+
} else {
|
1852 |
+
$connect_url = add_query_arg(
|
1853 |
+
array(
|
1854 |
+
'action' => 'authorize',
|
1855 |
+
'gateway_environment' => $environment2,
|
1856 |
+
'return_url' => rawurlencode( admin_url( 'admin.php?page=pmpro-paymentsettings' ) ),
|
1857 |
+
),
|
1858 |
+
$connect_url_base
|
1859 |
+
);
|
1860 |
+
?>
|
1861 |
+
<a href="<?php echo esc_url_raw( $connect_url ); ?>" class="pmpro-stripe-connect"><span><?php esc_html_e( 'Connect with Stripe', 'paid-memberships-pro' ); ?></span></a>
|
1862 |
+
<?php
|
1863 |
+
}
|
1864 |
+
?>
|
1865 |
+
<p class="description">
|
1866 |
+
<?php
|
1867 |
+
if ( pmpro_license_isValid( null, 'plus' ) ) {
|
1868 |
+
esc_html_e( 'Note: You have a valid license and are not charged additional platform fees for payment processing.', 'paid-memberships-pro');
|
1869 |
+
} else {
|
1870 |
+
esc_html_e( 'Note: You are using the free Stripe payment gateway integration. This includes an additional 1% fee for payment processing. This fee is removed by activating a Plus license.', 'paid-memberships-pro');
|
1871 |
+
}
|
1872 |
+
echo ' <a href="https://www.paidmembershipspro.com/gateway/stripe/?utm_source=plugin&utm_medium=pmpro-paymentsettings&utm_campaign=gateways&utm_content=stripe-fees#tab-fees" target="_blank">' . esc_html( 'Learn More »', 'paid-memberships-pro' ) . '</a>';
|
1873 |
+
?>
|
1874 |
+
</p>
|
1875 |
+
<input type='hidden' name='<?php echo $environment; ?>_stripe_connect_user_id' id='<?php echo $environment; ?>_stripe_connect_user_id' value='<?php echo esc_attr( $values[ $environment . '_stripe_connect_user_id'] ) ?>'/>
|
1876 |
+
<input type='hidden' name='<?php echo $environment; ?>_stripe_connect_secretkey' id='<?php echo $environment; ?>_stripe_connect_secretkey' value='<?php echo esc_attr( $values[ $environment . '_stripe_connect_secretkey'] ) ?>'/>
|
1877 |
+
<input type='hidden' name='<?php echo $environment; ?>_stripe_connect_publishablekey' id='<?php echo $environment; ?>_stripe_connect_publishablekey' value='<?php echo esc_attr( $values[ $environment . '_stripe_connect_publishablekey'] ) ?>'/>
|
1878 |
+
</td>
|
1879 |
+
</tr>
|
1880 |
+
<tr class="gateway gateway_stripe_<?php echo $environment; ?>" <?php if ( $gateway != "stripe" || $gateway_environment != $environment ) { ?>style="display: none;"<?php } ?>>
|
1881 |
+
<th scope="row" valign="top">
|
1882 |
+
<label><?php esc_html_e( 'Webhook', 'paid-memberships-pro' ); ?>:</label>
|
1883 |
+
</th>
|
1884 |
+
<td>
|
1885 |
+
<?php self::get_last_webhook_date( $environment ); ?>
|
1886 |
+
<p class="description"><?php esc_html_e( 'Webhook URL', 'paid-memberships-pro' ); ?>:
|
1887 |
+
<code><?php echo esc_html( self::get_site_webhook_url() ); ?></code></p>
|
1888 |
+
</td>
|
1889 |
+
</tr>
|
1890 |
+
<?php
|
1891 |
+
}
|
1892 |
+
|
1893 |
+
/**
|
1894 |
+
* Retrieve a Stripe_Customer.
|
1895 |
+
*
|
1896 |
+
* @since 2.7.0
|
1897 |
+
*
|
1898 |
+
* @param string $customer_id to retrieve.
|
1899 |
+
* @return Stripe_Customer|null
|
1900 |
+
*/
|
1901 |
+
private function get_customer( $customer_id ) {
|
1902 |
+
try {
|
1903 |
+
$customer = Stripe_Customer::retrieve( $customer_id );
|
1904 |
+
return $customer;
|
1905 |
} catch ( \Throwable $e ) {
|
1906 |
+
// Assume no customer found.
|
1907 |
+
} catch ( \Exception $e ) {
|
1908 |
+
// Assume no customer found.
|
1909 |
+
}
|
1910 |
+
}
|
1911 |
+
|
1912 |
+
/**
|
1913 |
+
* Check whether a given Stripe customer has a billing address set.
|
1914 |
+
*
|
1915 |
+
* @since 2.7.0
|
1916 |
+
*
|
1917 |
+
* @param Stripe_Customer $customer to check.
|
1918 |
+
* @return bool
|
1919 |
+
*/
|
1920 |
+
private function customer_has_billing_address( $customer ) {
|
1921 |
+
return (
|
1922 |
+
! empty( $customer ) &&
|
1923 |
+
! empty( $customer->address->line1 ) &&
|
1924 |
+
! empty( $customer->address->city ) &&
|
1925 |
+
! empty( $customer->address->state ) &&
|
1926 |
+
! empty( $customer->address->postal_code ) &&
|
1927 |
+
! empty( $customer->address->country )
|
1928 |
+
);
|
1929 |
+
}
|
1930 |
+
|
1931 |
+
/**
|
1932 |
+
* Update a customer in Stripe.
|
1933 |
+
*
|
1934 |
+
* @since 2.7.0
|
1935 |
+
*
|
1936 |
+
* @param string $customer_id to update.
|
1937 |
+
* @param array $args to update with.
|
1938 |
+
* @return Stripe_Customer|string error message.
|
1939 |
+
*/
|
1940 |
+
private function update_customer( $customer_id, $args ) {
|
1941 |
+
try {
|
1942 |
+
$customer = Stripe_Customer::update( $customer_id, $args );
|
1943 |
+
} catch ( \Stripe\Error $e ) {
|
1944 |
+
return $e->getMessage();
|
1945 |
+
} catch ( \Throwable $e ) {
|
1946 |
+
return $e->getMessage();
|
1947 |
+
} catch ( \Exception $e ) {
|
1948 |
+
return $e->getMessage();
|
1949 |
+
}
|
1950 |
+
return $customer;
|
1951 |
+
}
|
1952 |
+
|
1953 |
+
/**
|
1954 |
+
* Create a new customer in Stripe.
|
1955 |
+
*
|
1956 |
+
* @since 2.7.0
|
1957 |
+
*
|
1958 |
+
* @param array $args to update with.
|
1959 |
+
* @return Stripe_Customer|string error message.
|
1960 |
+
*/
|
1961 |
+
private function create_customer( $args ) {
|
1962 |
+
try {
|
1963 |
+
$customer = Stripe_Customer::create( $args );
|
1964 |
+
} catch ( \Stripe\Error $e ) {
|
1965 |
+
return $e->getMessage();
|
1966 |
+
} catch ( \Throwable $e ) {
|
1967 |
+
return $e->getMessage();
|
1968 |
+
} catch ( \Exception $e ) {
|
1969 |
+
return $e->getMessage();
|
1970 |
+
}
|
1971 |
+
return $customer;
|
1972 |
+
}
|
1973 |
+
|
1974 |
+
/**
|
1975 |
+
* Create/Update Stripe customer from MemberOrder.
|
1976 |
+
*
|
1977 |
+
* Falls back on information in User object if insufficient
|
1978 |
+
* information in MemberOrder.
|
1979 |
+
*
|
1980 |
+
* Should only be called when checkout is being proceesed. Otherwise,
|
1981 |
+
* use update_customer_from_user() method.
|
1982 |
+
*
|
1983 |
+
* @since 2.7.0
|
1984 |
+
*
|
1985 |
+
* @param MemberOrder $order to create/update Stripe customer for.
|
1986 |
+
* @return Stripe_Customer|false
|
1987 |
+
*/
|
1988 |
+
private function update_customer_at_checkout( $order ) {
|
1989 |
+
global $current_user;
|
1990 |
+
|
1991 |
+
// Get user's ID.
|
1992 |
+
if ( ! empty( $order->user_id ) ) {
|
1993 |
+
$user_id = $order->user_id;
|
1994 |
+
}
|
1995 |
+
if ( empty( $user_id ) && ! empty( $current_user->ID ) ) {
|
1996 |
+
$user_id = $current_user->ID;
|
1997 |
+
}
|
1998 |
+
$user = empty( $user_id ) ? null : get_userdata( $user_id );
|
1999 |
+
$customer = empty( $user_id ) ? null : $this->get_customer_for_user( $user_id );
|
2000 |
+
|
2001 |
+
// Get customer name.
|
2002 |
+
if ( ! empty( $order->FirstName ) && ! empty( $order->LastName ) ) {
|
2003 |
+
$name = trim( $order->FirstName . " " . $order->LastName );
|
2004 |
+
} elseif ( ! empty( $order->FirstName ) ) {
|
2005 |
+
$name = $order->FirstName;
|
2006 |
+
} elseif ( ! empty( $order->LastName ) ) {
|
2007 |
+
$name = $order->LastName;
|
2008 |
+
} elseif ( ! empty( $user->ID ) ) {
|
2009 |
+
$name = trim( $user->first_name . " " . $user->last_name );
|
2010 |
+
if ( empty( $name ) ) {
|
2011 |
+
// In case first and last names aren't set.
|
2012 |
+
$name = $user->user_login;
|
2013 |
+
}
|
2014 |
+
} else {
|
2015 |
+
$name = 'No Name';
|
2016 |
+
}
|
2017 |
+
|
2018 |
+
// Get user's email.
|
2019 |
+
if ( ! empty( $order->Email ) ) {
|
2020 |
+
$email = $order->Email;
|
2021 |
+
} elseif ( ! empty( $user->user_email ) ) {
|
2022 |
+
$email = $user->user_email;
|
2023 |
+
} else {
|
2024 |
+
$email = "No Email";
|
2025 |
+
}
|
2026 |
+
|
2027 |
+
// Build data to update customer with.
|
2028 |
+
$customer_args = array(
|
2029 |
+
'email' => $email,
|
2030 |
+
'description' => $name . ' (' . $email . ')',
|
2031 |
+
);
|
2032 |
+
|
2033 |
+
// Maybe update billing address for customer.
|
2034 |
+
if (
|
2035 |
+
! empty( $order->billing->street ) &&
|
2036 |
+
! empty( $order->billing->city ) &&
|
2037 |
+
! empty( $order->billing->state ) &&
|
2038 |
+
! empty( $order->billing->postal_code ) &&
|
2039 |
+
! empty( $order->billing->country )
|
2040 |
+
) {
|
2041 |
+
// We collected a billing address at checkout.
|
2042 |
+
// Send it to Stripe.
|
2043 |
+
$customer_args['address'] = array(
|
2044 |
+
'city' => $order->billing->city,
|
2045 |
+
'country' => $order->billing->country,
|
2046 |
+
'line1' => $order->billing->street,
|
2047 |
+
'line2' => '',
|
2048 |
+
'postal_code' => $order->billing->zip,
|
2049 |
+
'state' => $order->billing->state,
|
2050 |
+
);
|
2051 |
+
} elseif (
|
2052 |
+
! $this->customer_has_billing_address( $customer ) &&
|
2053 |
+
! empty( $user->pmpro_baddress1 ) &&
|
2054 |
+
! empty( $user->pmpro_bcity ) &&
|
2055 |
+
! empty( $user->pmpro_bstate ) &&
|
2056 |
+
! empty( $user->pmpro_bzipcode ) &&
|
2057 |
+
! empty( $user->pmpro_bcountry )
|
2058 |
+
) {
|
2059 |
+
// We have an address in user meta and there is
|
2060 |
+
// no address in Stripe. May as well send it.
|
2061 |
+
$customer_args['address'] = array(
|
2062 |
+
'city' => $user->pmpro_bcity,
|
2063 |
+
'country' => $user->pmpro_bcountry,
|
2064 |
+
'line1' => $user->pmpro_baddress1,
|
2065 |
+
'line2' => $user->pmpro_baddress2,
|
2066 |
+
'postal_code' => $user->pmpro_bzipcode,
|
2067 |
+
'state' => $user->pmpro_bstate,
|
2068 |
+
);
|
2069 |
+
}
|
2070 |
+
|
2071 |
+
/**
|
2072 |
+
* Change the information that is sent when updating/creating
|
2073 |
+
* a Stripe_Customer from a MemberOrder.
|
2074 |
+
*
|
2075 |
+
* @since 2.7.0
|
2076 |
+
*
|
2077 |
+
* @param array $customer_args to be sent.
|
2078 |
+
* @param MemberOrder $order being used to create/update customer.
|
2079 |
+
*/
|
2080 |
+
$customer_args = apply_filters( 'pmpro_stripe_update_customer_at_checkout', $customer_args, $order );
|
2081 |
+
|
2082 |
+
// Check if we have an existing user.
|
2083 |
+
if ( ! empty( $customer ) ) {
|
2084 |
+
// User is already a customer in Stripe. Update.
|
2085 |
+
$customer = $this->update_customer( $customer->id, $customer_args );
|
2086 |
+
if ( is_string( $customer ) ) {
|
2087 |
+
// We were not able to create a new user in Stripe.
|
2088 |
+
$order->error = __( "Error updating customer record with Stripe.", 'paid-memberships-pro' ) . " " . $customer;
|
2089 |
+
$order->shorterror = $order->error;
|
2090 |
+
return false;
|
2091 |
+
}
|
2092 |
+
return $customer;
|
2093 |
+
}
|
2094 |
+
|
2095 |
+
// No customer yet. Need to create one.
|
2096 |
+
$customer = $this->create_customer( $customer_args );
|
2097 |
+
if ( is_string( $customer ) ) {
|
2098 |
+
// We were not able to create a new user in Stripe.
|
2099 |
+
$order->error = __( "Error creating customer record with Stripe.", 'paid-memberships-pro' ) . " " . $customer;
|
2100 |
+
$order->shorterror = $order->error;
|
2101 |
+
return false;
|
2102 |
+
}
|
2103 |
+
|
2104 |
+
// If we don't have a user yet, we need to update their user meta after registration.
|
2105 |
+
if ( empty( $user_id ) ) {
|
2106 |
+
global $pmpro_stripe_customer_id;
|
2107 |
+
$pmpro_stripe_customer_id = $customer->id;
|
2108 |
+
if ( ! function_exists( 'pmpro_user_register_stripe_customerid' ) ) {
|
2109 |
+
function pmpro_user_register_stripe_customerid( $user_id ) {
|
2110 |
+
global $pmpro_stripe_customer_id;
|
2111 |
+
update_user_meta( $user_id, "pmpro_stripe_customerid", $pmpro_stripe_customer_id );
|
2112 |
+
}
|
2113 |
+
add_action( "user_register", "pmpro_user_register_stripe_customerid" );
|
2114 |
+
}
|
2115 |
+
}
|
2116 |
+
|
2117 |
+
/**
|
2118 |
+
* Fires after a Stripe_Customer is created at checkout.
|
2119 |
+
*
|
2120 |
+
* @since Unknown
|
2121 |
+
* @deprecated 2.7.0. Use pmpro_stripe_update_customer_from_user or pmpro_stripe_update_customer_at_checkout.
|
2122 |
+
*
|
2123 |
+
* @param array $customer_args to be sent.
|
2124 |
+
* @param MemberOrder $order being used to create/update customer.
|
2125 |
+
*/
|
2126 |
+
do_action( 'pmpro_stripe_create_customer', $customer );
|
2127 |
+
return $customer;
|
2128 |
+
}
|
2129 |
+
|
2130 |
+
/**
|
2131 |
+
* Sets the default Payment Method for a Customer in Stripe.
|
2132 |
+
*
|
2133 |
+
* @param Stripe_Customer $customer to update default payment method for.
|
2134 |
+
* @param Stripe_PaymentMethod $payment_method to set as default.
|
2135 |
+
* @return Stripe_Customer|string error message.
|
2136 |
+
*/
|
2137 |
+
private function set_default_payment_method_for_customer( $customer, $payment_method ) {
|
2138 |
+
if ( ! empty( $customer->invoice_settings->default_payment_method ) && $customer->invoice_settings->default_payment_method === $payment_method->id ) {
|
2139 |
+
// Payment method already correct, no need to update.
|
2140 |
+
return $customer;
|
2141 |
+
}
|
2142 |
+
|
2143 |
+
try {
|
2144 |
+
$payment_method->attach( [ 'customer' => $customer->id ] );
|
2145 |
+
$customer->invoice_settings->default_payment_method = $payment_method->id;
|
2146 |
+
$customer->save();
|
2147 |
+
} catch ( Stripe\Error\Base $e ) {
|
2148 |
+
$order->error = $e->getMessage();
|
2149 |
+
return $e->getMessage();
|
2150 |
+
} catch ( \Throwable $e ) {
|
2151 |
+
$order->error = $e->getMessage();
|
2152 |
+
return $e->getMessage();
|
2153 |
+
} catch ( \Exception $e ) {
|
2154 |
+
$order->error = $e->getMessage();
|
2155 |
+
return $e->getMessage();
|
2156 |
+
}
|
2157 |
+
|
2158 |
+
return $customer;
|
2159 |
+
}
|
2160 |
+
|
2161 |
+
/**
|
2162 |
+
* Convert a price to a positive integer in cents (or 0 for a free price)
|
2163 |
+
* representing how much to charge. This is how Stripe wants us to send price amounts.
|
2164 |
+
*
|
2165 |
+
* @param float $price to be converted into cents.
|
2166 |
+
* @return integer
|
2167 |
+
*/
|
2168 |
+
private function convert_price_to_unit_amount( $price ) {
|
2169 |
+
global $pmpro_currencies, $pmpro_currency;
|
2170 |
+
$currency_unit_multiplier = 100; // ie 100 cents per USD.
|
2171 |
+
|
2172 |
+
// Account for zero-decimal currencies like the Japanese Yen.
|
2173 |
+
if (
|
2174 |
+
is_array( $pmpro_currencies[ $pmpro_currency ] ) &&
|
2175 |
+
isset( $pmpro_currencies[ $pmpro_currency ]['decimals'] ) &&
|
2176 |
+
$pmpro_currencies[ $pmpro_currency ]['decimals'] == 0
|
2177 |
+
) {
|
2178 |
+
$currency_unit_multiplier = 1;
|
2179 |
+
}
|
2180 |
+
|
2181 |
+
return intval( $price * $currency_unit_multiplier );
|
2182 |
+
}
|
2183 |
+
|
2184 |
+
/**
|
2185 |
+
* Retrieve a Stripe_Subscription.
|
2186 |
+
*
|
2187 |
+
* @since 2.7.0
|
2188 |
+
*
|
2189 |
+
* @param string $subscription_id to retrieve.
|
2190 |
+
* @return Stripe_Subscription|null
|
2191 |
+
*/
|
2192 |
+
private function get_subscription( $subscription_id ) {
|
2193 |
+
try {
|
2194 |
+
$customer = Stripe_Subscription::retrieve( $subscription_id );
|
2195 |
+
return $customer;
|
2196 |
+
} catch ( \Throwable $e ) {
|
2197 |
+
// Assume no subscription found.
|
2198 |
+
} catch ( \Exception $e ) {
|
2199 |
+
// Assume no subscription found.
|
2200 |
+
}
|
2201 |
+
}
|
2202 |
+
|
2203 |
+
/**
|
2204 |
+
* Get the Stripe product ID for a given membership level.
|
2205 |
+
*
|
2206 |
+
* @since 2.7.0
|
2207 |
+
*
|
2208 |
+
* @param PMPro_Membership_Leve|int $level to get product ID for.
|
2209 |
+
* @return string|null
|
2210 |
+
*/
|
2211 |
+
private function get_product_id_for_level( $level ) {
|
2212 |
+
if ( ! is_a( $level, 'PMPro_Membership_Level' ) ) {
|
2213 |
+
if ( is_numeric( $level ) ) {
|
2214 |
+
$level = new PMPro_Membership_Level( $level );
|
2215 |
+
}
|
2216 |
+
}
|
2217 |
+
|
2218 |
+
if ( empty( $level->ID ) ) {
|
2219 |
+
// We do not have a valid level.
|
2220 |
+
return;
|
2221 |
+
}
|
2222 |
+
|
2223 |
+
$gateway_environment = pmpro_getOption( 'gateway_environment' );
|
2224 |
+
if ( $gateway_environment === 'sandbox' ) {
|
2225 |
+
$stripe_product_id = $level->stripe_product_id_sandbox;
|
2226 |
+
} else {
|
2227 |
+
$stripe_product_id = $level->stripe_product_id;
|
2228 |
+
}
|
2229 |
+
if ( empty( $stripe_product_id ) ) {
|
2230 |
+
$stripe_product_id = $this->create_product_for_level( $level, $gateway_environment );
|
2231 |
+
}
|
2232 |
+
|
2233 |
+
if ( ! empty( $stripe_product_id ) ) {
|
2234 |
+
return $stripe_product_id;
|
2235 |
+
}
|
2236 |
+
}
|
2237 |
+
|
2238 |
+
/**
|
2239 |
+
* Create a new Stripe product for a given membership level.
|
2240 |
+
*
|
2241 |
+
* WARNING: Will overwrite old Stripe product set for level if
|
2242 |
+
* there is already one set.
|
2243 |
+
*
|
2244 |
+
* @since 2.7.0
|
2245 |
+
*
|
2246 |
+
* @param PMPro_Membership_Level|int $level to create product ID for.
|
2247 |
+
* @param string $gateway_environment to create product for.
|
2248 |
+
* @return string|null ID of new product
|
2249 |
+
*/
|
2250 |
+
private function create_product_for_level( $level, $gateway_environment ) {
|
2251 |
+
if ( ! is_a( $level, 'PMPro_Membership_Level' ) ) {
|
2252 |
+
if ( is_numeric( $level ) ) {
|
2253 |
+
$level = new PMPro_Membership_Level( $level );
|
2254 |
+
}
|
2255 |
+
}
|
2256 |
+
|
2257 |
+
if ( empty( $level->ID ) ) {
|
2258 |
+
// We do not have a valid level.
|
2259 |
+
return;
|
2260 |
+
}
|
2261 |
+
|
2262 |
+
$product_args = array(
|
2263 |
+
'name' => $level->name,
|
2264 |
+
);
|
2265 |
+
/**
|
2266 |
+
* Filter the data sent to Stripe when creating a new product for a membership level.
|
2267 |
+
*
|
2268 |
+
* @since 2.7.0
|
2269 |
+
*
|
2270 |
+
* @param array $product_args being sent to Stripe.
|
2271 |
+
* @param PMPro_Membership_Level $level that product is being created for.
|
2272 |
+
* @param string $gateway_environment being used.
|
2273 |
+
*/
|
2274 |
+
$product_args = apply_filters( 'pmpro_stripe_create_product_for_level', $product_args, $level, $gateway_environment );
|
2275 |
+
|
2276 |
+
try {
|
2277 |
+
$product = Stripe_Product::create( $product_args );
|
2278 |
+
if ( ! empty( $product->id ) ) {
|
2279 |
+
$meta_name = 'sandbox' === $gateway_environment ? 'stripe_product_id_sandbox' : 'stripe_product_id';
|
2280 |
+
update_pmpro_membership_level_meta( $level->ID, $meta_name, $product->id );
|
2281 |
+
return $product->id;
|
2282 |
+
}
|
2283 |
+
} catch (\Throwable $th) {
|
2284 |
+
// Could not create product.
|
2285 |
+
} catch (\Exception $e) {
|
2286 |
+
// Could not create product.
|
2287 |
+
}
|
2288 |
+
}
|
2289 |
+
|
2290 |
+
/**
|
2291 |
+
* Get a Price for a given product, or create one if it doesn't exist.
|
2292 |
+
*
|
2293 |
+
* TODO: Add pagination.
|
2294 |
+
*
|
2295 |
+
* @since 2.7.0
|
2296 |
+
*
|
2297 |
+
* @param string $product_id to get Price for.
|
2298 |
+
* @param float $amount that the Price will charge.
|
2299 |
+
* @param string|null $cycle_period for subscription payments.
|
2300 |
+
* @param string|null $cycle_number of cycle periods between each subscription payment.
|
2301 |
+
*
|
2302 |
+
* @return string|null Price ID.
|
2303 |
+
*/
|
2304 |
+
private function get_price_for_product( $product_id, $amount, $cycle_period = null, $cycle_number = null ) {
|
2305 |
+
global $pmpro_currency;
|
2306 |
+
$currency = pmpro_get_currency();
|
2307 |
+
|
2308 |
+
$is_recurring = ! empty( $cycle_period ) && ! empty( $cycle_number );
|
2309 |
+
$unit_amount = intval( $amount * pow( 10, intval( $currency['decimals'] ) ) );
|
2310 |
+
$cycle_period = strtolower( $cycle_period );
|
2311 |
+
|
2312 |
+
$price_search_args = array(
|
2313 |
+
'product' => $product_id,
|
2314 |
+
'type' => $is_recurring ? 'recurring' : 'one_time',
|
2315 |
+
'currency' => strtolower( $pmpro_currency ),
|
2316 |
+
);
|
2317 |
+
if ( $is_recurring ) {
|
2318 |
+
$price_search_args['recurring'] = array( 'interval' => $cycle_period );
|
2319 |
+
}
|
2320 |
+
|
2321 |
+
try {
|
2322 |
+
$prices = Stripe_Price::all( $price_search_args );
|
2323 |
+
|
2324 |
+
foreach ( $prices as $price ) {
|
2325 |
+
// Check whether price is the same. If not, continue.
|
2326 |
+
if ( intval( $price->unit_amount ) !== intval( $unit_amount ) ) {
|
2327 |
+
continue;
|
2328 |
+
}
|
2329 |
+
// Check if recurring structure is the same. If not, continue.
|
2330 |
+
if ( $is_recurring && ( empty( $price->recurring->interval_count ) || intval( $price->recurring->interval_count ) !== intval( $cycle_number ) ) ) {
|
2331 |
+
continue;
|
2332 |
+
}
|
2333 |
+
return $price->id;
|
2334 |
+
}
|
2335 |
+
} catch (\Throwable $th) {
|
2336 |
+
// There was an error listing prices.
|
2337 |
+
return;
|
2338 |
+
} catch (\Exception $e) {
|
2339 |
+
// There was an error listing prices.
|
2340 |
+
return;
|
2341 |
+
}
|
2342 |
+
|
2343 |
+
// Create a new Price.
|
2344 |
+
$price_args = array(
|
2345 |
+
'product' => $product_id,
|
2346 |
+
'currency' => strtolower( $pmpro_currency ),
|
2347 |
+
'unit_amount' => $unit_amount
|
2348 |
+
);
|
2349 |
+
if ( $is_recurring ) {
|
2350 |
+
$price_args['recurring'] = array(
|
2351 |
+
'interval' => $cycle_period,
|
2352 |
+
'interval_count' => $cycle_number
|
2353 |
+
);
|
2354 |
+
}
|
2355 |
+
|
2356 |
+
try {
|
2357 |
+
$price = Stripe_Price::create( $price_args );
|
2358 |
+
if ( ! empty( $price->id ) ) {
|
2359 |
+
return $price->id;
|
2360 |
+
}
|
2361 |
+
} catch (\Throwable $th) {
|
2362 |
+
// Could not create product.
|
2363 |
+
} catch (\Exception $e) {
|
2364 |
+
// Could not create product.
|
2365 |
+
}
|
2366 |
+
}
|
2367 |
+
|
2368 |
+
/**
|
2369 |
+
* Calculate the number of days until the first recurring payment
|
2370 |
+
* for a subscription should be charged.
|
2371 |
+
*
|
2372 |
+
* @since 2.7.0.
|
2373 |
+
*
|
2374 |
+
* @param MemberOrder $order to calculate trial period days for.
|
2375 |
+
* @return int trial period days.
|
2376 |
+
*/
|
2377 |
+
private function calculate_trial_period_days( $order ) {
|
2378 |
+
// Use a trial period to set the first recurring payment date.
|
2379 |
+
if ( $order->BillingPeriod == "Year" ) {
|
2380 |
+
$days_in_billing_period = $order->BillingFrequency * 365; //annual
|
2381 |
+
} elseif ( $order->BillingPeriod == "Day" ) {
|
2382 |
+
$days_in_billing_period = $order->BillingFrequency * 1; //daily
|
2383 |
+
} elseif ( $order->BillingPeriod == "Week" ) {
|
2384 |
+
$days_in_billing_period = $order->BillingFrequency * 7; //weekly
|
2385 |
+
} else {
|
2386 |
+
$days_in_billing_period = $order->BillingFrequency * 30; //assume monthly
|
2387 |
+
}
|
2388 |
+
$trial_period_days = $order->BillingFrequency * $days_in_billing_period;
|
2389 |
+
|
2390 |
+
// For free trials, multiply the trial period for each additional free period.
|
2391 |
+
if ( ! empty( $order->TrialBillingCycles ) && $order->TrialAmount == 0 ) {
|
2392 |
+
$trialOccurrences = (int) $order->TrialBillingCycles;
|
2393 |
+
$trial_period_days = $trial_period_days * ( $order->TrialBillingCycles + 1 );
|
2394 |
+
}
|
2395 |
+
|
2396 |
+
//convert to a profile start date
|
2397 |
+
$order->ProfileStartDate = date_i18n( "Y-m-d\TH:i:s", strtotime( "+ " . $trial_period_days . " Day", current_time( "timestamp" ) ) );
|
2398 |
+
|
2399 |
+
//filter the start date
|
2400 |
+
$order->ProfileStartDate = apply_filters( "pmpro_profile_start_date", $order->ProfileStartDate, $order );
|
2401 |
+
|
2402 |
+
//convert back to days
|
2403 |
+
$trial_period_days = ceil( abs( strtotime( date_i18n( "Y-m-d\TH:i:s" ), current_time( "timestamp" ) ) - strtotime( $order->ProfileStartDate, current_time( "timestamp" ) ) ) / 86400 );
|
2404 |
+
return $trial_period_days;
|
2405 |
+
}
|
2406 |
+
|
2407 |
+
/**
|
2408 |
+
* Create a subscription for a customer from an order using a Stripe Price.
|
2409 |
+
*
|
2410 |
+
* @since 2.7.0.
|
2411 |
+
*
|
2412 |
+
* @param string $customer_id to create subscription for.
|
2413 |
+
* @param MemberOrder $order to pull subscription details from.
|
2414 |
+
* @return Stripe_Subscription|bool false if error.
|
2415 |
+
*/
|
2416 |
+
private function create_subscription_for_customer_from_order( $customer_id, $order ) {
|
2417 |
+
$subtotal = $order->PaymentAmount;
|
2418 |
+
$tax = $order->getTaxForPrice( $subtotal );
|
2419 |
+
$amount = pmpro_round_price( (float) $subtotal + (float) $tax );
|
2420 |
+
|
2421 |
+
// Set up the subscription.
|
2422 |
+
$product_id = $this->get_product_id_for_level( $order->membership_id );
|
2423 |
+
if ( empty( $product_id ) ) {
|
2424 |
+
$order->error = esc_html__( 'Cannot find product for membership level.', 'paid-memberships-pro' );
|
2425 |
+
return false;
|
2426 |
+
}
|
2427 |
+
|
2428 |
+
$price = $this->get_price_for_product( $product_id, $amount, $order->BillingPeriod, $order->BillingFrequency );
|
2429 |
+
if ( empty( $price ) ) {
|
2430 |
+
$order->error = esc_html__( 'Cannot get price.', 'paid-memberships-pro' );
|
2431 |
+
return false;
|
2432 |
+
}
|
2433 |
+
|
2434 |
+
$trial_period_days = $this->calculate_trial_period_days( $order );
|
2435 |
+
|
2436 |
+
try {
|
2437 |
+
$subscription_params = array(
|
2438 |
+
'customer' => $customer_id,
|
2439 |
+
'items' => array(
|
2440 |
+
array( 'price' => $price ),
|
2441 |
+
),
|
2442 |
+
'trial_period_days' => $trial_period_days,
|
2443 |
+
'expand' => array(
|
2444 |
+
'pending_setup_intent.payment_method',
|
2445 |
+
),
|
2446 |
+
);
|
2447 |
+
if ( ! self::using_legacy_keys() ) {
|
2448 |
+
$params['application_fee_percent'] = self::get_application_fee_percentage();
|
2449 |
+
}
|
2450 |
+
$subscription_params = apply_filters( 'pmpro_stripe_create_subscription_array', $subscription_params );
|
2451 |
+
$subscription = Stripe_Subscription::create( $subscription_params );
|
2452 |
+
} catch ( Stripe\Error\Base $e ) {
|
2453 |
+
$order->error = $e->getMessage();
|
2454 |
+
return false;
|
2455 |
+
} catch ( \Throwable $e ) {
|
2456 |
+
$order->error = $e->getMessage();
|
2457 |
+
return false;
|
2458 |
+
} catch ( \Exception $e ) {
|
2459 |
+
$order->error = $e->getMessage();
|
2460 |
+
return false;
|
2461 |
+
}
|
2462 |
+
return $subscription;
|
2463 |
+
}
|
2464 |
+
|
2465 |
+
/**
|
2466 |
+
* Retrieve a payment intent.
|
2467 |
+
*
|
2468 |
+
* @since 2.7.0.
|
2469 |
+
*
|
2470 |
+
* @param string $payment_intent_id to retrieve.
|
2471 |
+
* @return Stripe_PaymentIntent|string error.
|
2472 |
+
*/
|
2473 |
+
private function retrieve_payment_intent( $payment_intent_id ) {
|
2474 |
+
try {
|
2475 |
+
$payment_intent = Stripe_PaymentIntent::retrieve( $payment_intent_id );
|
2476 |
+
} catch ( Stripe\Error\Base $e ) {
|
2477 |
+
return $e->getMessage();
|
2478 |
+
} catch ( \Throwable $e ) {
|
2479 |
+
return $e->getMessage();
|
2480 |
+
} catch ( \Exception $e ) {
|
2481 |
+
return $e->getMessage();
|
2482 |
+
}
|
2483 |
+
return $payment_intent;
|
2484 |
+
}
|
2485 |
+
|
2486 |
+
/**
|
2487 |
+
* Retrieve a setup intent.
|
2488 |
+
*
|
2489 |
+
* @since 2.7.0.
|
2490 |
+
*
|
2491 |
+
* @param string $setup_intent_id to retrieve.
|
2492 |
+
* @return Stripe_SetupIntent|string error.
|
2493 |
+
*/
|
2494 |
+
private function retrieve_setup_intent( $setup_intent_id ) {
|
2495 |
+
try {
|
2496 |
+
$setup_intent_args = array(
|
2497 |
+
'id' => $setup_intent_id,
|
2498 |
+
'expand' => array(
|
2499 |
+
'latest_attempt',
|
2500 |
+
),
|
2501 |
+
);
|
2502 |
+
$setup_intent = Stripe_SetupIntent::retrieve( $setup_intent_args );
|
2503 |
+
} catch ( Stripe\Error\Base $e ) {
|
2504 |
+
return $e->getMessage();
|
2505 |
+
} catch ( \Throwable $e ) {
|
2506 |
+
return $e->getMessage();
|
2507 |
+
} catch ( \Exception $e ) {
|
2508 |
+
return $e->getMessage();
|
2509 |
+
}
|
2510 |
+
return $setup_intent;
|
2511 |
+
}
|
2512 |
+
|
2513 |
+
/**
|
2514 |
+
* Confirm the payment intent after authentication.
|
2515 |
+
*
|
2516 |
+
* @since 2.7.0.
|
2517 |
+
*
|
2518 |
+
* @param string $payment_intent_id to confirm.
|
2519 |
+
* @return Stripe_PaymentIntent|string error.
|
2520 |
+
*/
|
2521 |
+
private function process_payment_intent( $payment_intent_id ) {
|
2522 |
+
// Get the payment intent.
|
2523 |
+
$payment_intent = $this->retrieve_payment_intent( $payment_intent_id );
|
2524 |
+
if ( is_string( $payment_intent ) ) {
|
2525 |
+
// There was an issue retrieving the payment intent.
|
2526 |
+
return $payment_intent;
|
2527 |
+
}
|
2528 |
+
|
2529 |
+
// Confirm the payment.
|
2530 |
+
try {
|
2531 |
+
$params = array(
|
2532 |
+
'expand' => array(
|
2533 |
+
'payment_method',
|
2534 |
+
'customer'
|
2535 |
+
),
|
2536 |
+
);
|
2537 |
+
$payment_intent->confirm( $params );
|
2538 |
+
} catch ( Stripe\Error\Base $e ) {
|
2539 |
+
return $e->getMessage();
|
2540 |
+
} catch ( \Throwable $e ) {
|
2541 |
+
return $e->getMessage();
|
2542 |
+
} catch ( \Exception $e ) {
|
2543 |
+
return $e->getMessage();
|
2544 |
+
}
|
2545 |
+
|
2546 |
+
// Check that the confirmation was successful.
|
2547 |
+
if ( 'requires_action' == $payment_intent->status ) {
|
2548 |
+
return __( 'Customer authentication is required to finish setting up your subscription. Please complete the verification steps issued by your payment provider.', 'paid-memberships-pro' );
|
2549 |
+
}
|
2550 |
+
|
2551 |
+
return $payment_intent;
|
2552 |
+
}
|
2553 |
+
|
2554 |
+
/**
|
2555 |
+
* Confirm the setup intent after authentication.
|
2556 |
+
*
|
2557 |
+
* @since 2.7.0.
|
2558 |
+
*
|
2559 |
+
* @param string $setup_intent_id to confirm.
|
2560 |
+
* @return Stripe_SetupIntent|string error.
|
2561 |
+
*/
|
2562 |
+
private function process_setup_intent( $setup_intent_id ) {
|
2563 |
+
// Get the setup intent.
|
2564 |
+
$setup_intent = $this->retrieve_setup_intent( $setup_intent_id );
|
2565 |
+
if ( is_string( $setup_intent ) ) {
|
2566 |
+
return $setup_intent;
|
2567 |
+
}
|
2568 |
+
|
2569 |
+
// Make sure that the setup intent was recently confirmed.
|
2570 |
+
/**
|
2571 |
+
* The time in seconds that a setup intent must be confirmed within.
|
2572 |
+
*
|
2573 |
+
* @since 2.7.0
|
2574 |
+
*
|
2575 |
+
* @param int $seconds_to_confirm_setup_intent The time in seconds that a setup intent must be confirmed within.
|
2576 |
+
*/
|
2577 |
+
$setup_intent_timeout = apply_filters( 'pmpro_stripe_setup_intent_timeout', 60 * 10 );
|
2578 |
+
$last_setup_attempt_created = $setup_intent->latest_attempt->created;
|
2579 |
+
if ( $last_setup_attempt_created < time() - $setup_intent_timeout ) {
|
2580 |
+
return __( 'Cannot reuse an old setup intent.', 'paid-memberships-pro' );
|
2581 |
+
}
|
2582 |
+
|
2583 |
+
// Make sure that the confirmation was successful.
|
2584 |
+
if ( 'requires_action' === $setup_intent->status ) {
|
2585 |
+
return __( 'Customer authentication is required to finish setting up your subscription. Please complete the verification steps issued by your payment provider.', 'paid-memberships-pro' );
|
2586 |
+
}
|
2587 |
+
return $setup_intent;
|
2588 |
+
}
|
2589 |
+
|
2590 |
+
/**
|
2591 |
+
* Add a subscription ID to the metadata of a setup intent.
|
2592 |
+
*
|
2593 |
+
* @since 2.7.0.
|
2594 |
+
*
|
2595 |
+
* @param Stripe_SetupIntent $setup_intent The setup intent to add metadata to.
|
2596 |
+
* @param string $subscription_id The subscription ID that created this setup intent.
|
2597 |
+
*
|
2598 |
+
* @return Stripe_SetupIntent|string The setup intent object or an error message string.
|
2599 |
+
*/
|
2600 |
+
private function add_subscription_id_to_setup_intent( $setup_intent, $subscription_id ) {
|
2601 |
+
try {
|
2602 |
+
$setup_intent = Stripe_SetupIntent::update(
|
2603 |
+
$setup_intent->id,
|
2604 |
+
array(
|
2605 |
+
'metadata' => array(
|
2606 |
+
'subscription_id' => $subscription_id,
|
2607 |
+
),
|
2608 |
+
'expand' => array(
|
2609 |
+
'payment_method',
|
2610 |
+
),
|
2611 |
+
)
|
2612 |
+
);
|
2613 |
+
} catch ( \Throwable $e ) {
|
2614 |
+
return __( "Error adding metadata to setup intent.", 'paid-memberships-pro' );
|
2615 |
+
} catch ( \Exception $e ) {
|
2616 |
+
return __( "Error adding metadata to setup intent.", 'paid-memberships-pro' );
|
2617 |
+
}
|
2618 |
+
return $setup_intent;
|
2619 |
+
}
|
2620 |
+
|
2621 |
+
/**
|
2622 |
+
* Temporary function to allow users to view and delete subscription updates.
|
2623 |
+
* Will be removed once subscription updates are completely deprecated.
|
2624 |
+
*
|
2625 |
+
* @since 2.7.0.
|
2626 |
+
*
|
2627 |
+
* @param WP_User $user whose profile is being shown.
|
2628 |
+
* @param Stripe_Customer $customer associated with that user.
|
2629 |
+
*/
|
2630 |
+
private function user_profile_fields_subscription_updates( $user, $customer ) {
|
2631 |
+
global $pmpro_currency_symbol;
|
2632 |
+
|
2633 |
+
$subscriptions = $customer->subscriptions->all();
|
2634 |
+
if ( empty( $subscriptions ) ) {
|
2635 |
+
// User does not have any subscriptions to udpate. Delete all updates.
|
2636 |
+
delete_user_meta( $user->ID, 'pmpro_stripe_updates' );
|
2637 |
+
return;
|
2638 |
+
}
|
2639 |
+
|
2640 |
+
$cycles = array(
|
2641 |
+
__( 'Day(s)', 'paid-memberships-pro' ) => 'Day',
|
2642 |
+
__( 'Week(s)', 'paid-memberships-pro' ) => 'Week',
|
2643 |
+
__( 'Month(s)', 'paid-memberships-pro' ) => 'Month',
|
2644 |
+
__( 'Year(s)', 'paid-memberships-pro' ) => 'Year',
|
2645 |
+
);
|
2646 |
+
|
2647 |
+
$current_year = date_i18n( 'Y' );
|
2648 |
+
$current_month = date_i18n( 'm' );
|
2649 |
+
?>
|
2650 |
+
<h3><?php esc_html_e( 'Subscription Updates', 'paid-memberships-pro' ); ?></h3>
|
2651 |
+
<p><?php esc_html_e( 'Subscription updates will be deprecated in a future version of PMPro, though your existing subscription updates will still trigger as expected. We now instead reccomend updating the subscription directly in Stripe.', 'paid-memberships-pro' ); ?></p>
|
2652 |
+
<table class="form-table">
|
2653 |
+
<input type='hidden' name='pmpro_subscription_updates_visible' value='1' />
|
2654 |
+
<tr>
|
2655 |
+
<th><label><?php esc_html_e( 'Update', 'paid-memberships-pro' ); ?></label></th>
|
2656 |
+
<td id="updates_td">
|
2657 |
+
<?php
|
2658 |
+
$updates = $user->pmpro_stripe_updates;
|
2659 |
+
|
2660 |
+
foreach ( $updates as $update ) {
|
2661 |
+
?>
|
2662 |
+
<div class="updates_update">
|
2663 |
+
<select class="updates_when" name="updates_when[]" disabled>
|
2664 |
+
<option value="now" <?php selected( $update['when'], 'now' ); ?>>Now</option>
|
2665 |
+
<option value="payment" <?php selected( $update['when'], 'payment' ); ?>>After
|
2666 |
+
Next Payment
|
2667 |
+
</option>
|
2668 |
+
<option value="date" <?php selected( $update['when'], 'date' ); ?>>On Date
|
2669 |
+
</option>
|
2670 |
+
</select>
|
2671 |
+
<span class="updates_date"
|
2672 |
+
<?php if ( $update['when'] != 'date' ) { ?>style="display: none;"<?php } ?>>
|
2673 |
+
<select name="updates_date_month[]" disabled>
|
2674 |
+
<?php
|
2675 |
+
for ( $i = 1; $i < 13; $i ++ ) {
|
2676 |
+
?>
|
2677 |
+
<option value="<?php echo str_pad( $i, 2, '0', STR_PAD_LEFT ); ?>"
|
2678 |
+
<?php if ( ! empty( $update['date_month'] ) && $update['date_month'] == $i ) { ?>selected="selected"<?php } ?>>
|
2679 |
+
<?php echo date_i18n( 'M', strtotime( $i . '/15/' . $current_year ) ); ?>
|
2680 |
+
</option>
|
2681 |
+
<?php
|
2682 |
+
}
|
2683 |
+
?>
|
2684 |
+
</select>
|
2685 |
+
<input name="updates_date_day[]" type="text" size="2"
|
2686 |
+
value="<?php if ( ! empty( $update['date_day'] ) ) {
|
2687 |
+
echo esc_attr( $update['date_day'] );
|
2688 |
+
} ?>" readonly/>
|
2689 |
+
<input name="updates_date_year[]" type="text" size="4"
|
2690 |
+
value="<?php if ( ! empty( $update['date_year'] ) ) {
|
2691 |
+
echo esc_attr( $update['date_year'] );
|
2692 |
+
} ?>" readonly/>
|
2693 |
+
</span>
|
2694 |
+
<span class="updates_billing"
|
2695 |
+
<?php if ( $update['when'] == "now" ) { ?>style="display: none;"<?php } ?>>
|
2696 |
+
<?php echo $pmpro_currency_symbol; ?><input name="updates_billing_amount[]" type="text"
|
2697 |
+
size="10"
|
2698 |
+
value="<?php echo esc_attr( $update['billing_amount'] ); ?>"
|
2699 |
+
readonly/>
|
2700 |
+
<small><?php esc_html_e( 'per', 'paid-memberships-pro' ); ?></small>
|
2701 |
+
<input name="updates_cycle_number[]" type="text" size="5"
|
2702 |
+
value="<?php echo esc_attr( $update['cycle_number'] ); ?>" readonly/>
|
2703 |
+
<select name="updates_cycle_period[]" disabled>
|
2704 |
+
<?php
|
2705 |
+
foreach ( $cycles as $name => $value ) {
|
2706 |
+
echo "<option value='" . esc_attr( $value ) . "'";
|
2707 |
+
if ( ! empty( $update['cycle_period'] ) && $update['cycle_period'] == $value ) {
|
2708 |
+
echo " selected='selected'";
|
2709 |
+
}
|
2710 |
+
echo ">" . esc_html( $name ) . "</option>";
|
2711 |
+
}
|
2712 |
+
?>
|
2713 |
+
</select>
|
2714 |
+
</span>
|
2715 |
+
<span>
|
2716 |
+
<a class="updates_remove" href="javascript:void(0);"><?php esc_html_e( 'Remove', 'paid-memberships-pro' ); ?></a>
|
2717 |
+
</span>
|
2718 |
+
</div>
|
2719 |
+
<script>
|
2720 |
+
jQuery(function () {
|
2721 |
+
//remove updates when clicking
|
2722 |
+
jQuery('.updates_remove').on('click', function () {
|
2723 |
+
jQuery(this).parent().parent().remove();
|
2724 |
+
});
|
2725 |
+
jQuery('form').on('submit', function () {
|
2726 |
+
// Makes sure that disabled select fields are still submitted.
|
2727 |
+
jQuery(this).find(':input').prop('disabled', false);
|
2728 |
+
});
|
2729 |
+
});
|
2730 |
+
</script>
|
2731 |
+
<?php
|
2732 |
+
}
|
2733 |
+
?>
|
2734 |
+
</td>
|
2735 |
+
</tr>
|
2736 |
+
</table>
|
2737 |
+
<?php
|
2738 |
+
}
|
2739 |
+
|
2740 |
+
|
2741 |
+
|
2742 |
+
/****************************************
|
2743 |
+
******* METHODS BECOMING PRIVATE *******
|
2744 |
+
****************************************/
|
2745 |
+
/**
|
2746 |
+
* Get available webhooks
|
2747 |
+
*
|
2748 |
+
* @since 2.4
|
2749 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
2750 |
+
*/
|
2751 |
+
public static function get_webhooks( $limit = 10 ) {
|
2752 |
+
// Show deprecation warning if called publically.
|
2753 |
+
pmpro_method_should_be_private( '2.7.0' );
|
2754 |
+
|
2755 |
+
if ( ! class_exists( 'Stripe\WebhookEndpoint' ) ) {
|
2756 |
+
// Load Stripe library.
|
2757 |
+
new PMProGateway_stripe();
|
2758 |
+
if ( ! class_exists( 'Stripe\WebhookEndpoint' ) ) {
|
2759 |
+
// Couldn't load library.
|
2760 |
+
return false;
|
2761 |
+
}
|
2762 |
+
}
|
2763 |
+
|
2764 |
+
try {
|
2765 |
+
$webhooks = Stripe_Webhook::all( [ 'limit' => apply_filters( 'pmpro_stripe_webhook_retrieve_limit', $limit ) ] );
|
2766 |
+
} catch (\Throwable $th) {
|
2767 |
+
$webhooks = $th->getMessage();
|
2768 |
+
} catch (\Exception $e) {
|
2769 |
+
$webhooks = $e->getMessage();
|
2770 |
+
}
|
2771 |
+
|
2772 |
+
return $webhooks;
|
2773 |
+
}
|
2774 |
+
|
2775 |
+
/**
|
2776 |
+
* Get current webhook URL for website to compare.
|
2777 |
+
*
|
2778 |
+
* @since 2.4
|
2779 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
2780 |
+
*/
|
2781 |
+
public static function get_site_webhook_url() {
|
2782 |
+
// Show deprecation warning if called publically.
|
2783 |
+
pmpro_method_should_be_private( '2.7.0' );
|
2784 |
+
return admin_url( 'admin-ajax.php' ) . '?action=stripe_webhook';
|
2785 |
+
}
|
2786 |
+
|
2787 |
+
/**
|
2788 |
+
* List of current enabled events required for PMPro to work.
|
2789 |
+
*
|
2790 |
+
* @since 2.4
|
2791 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
2792 |
+
*/
|
2793 |
+
public static function webhook_events() {
|
2794 |
+
// Show deprecation warning if called publically.
|
2795 |
+
pmpro_method_should_be_private( '2.7.0' );
|
2796 |
+
return apply_filters( 'pmpro_stripe_webhook_events', array(
|
2797 |
+
'invoice.payment_succeeded',
|
2798 |
+
'invoice.payment_action_required',
|
2799 |
+
'customer.subscription.deleted',
|
2800 |
+
'charge.failed'
|
2801 |
+
) );
|
2802 |
+
}
|
2803 |
|
2804 |
+
/**
|
2805 |
+
* Create webhook with relevant events
|
2806 |
+
*
|
2807 |
+
* @since 2.4
|
2808 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
2809 |
+
*/
|
2810 |
+
public static function create_webhook() {
|
2811 |
+
// Show deprecation warning if called publically.
|
2812 |
+
pmpro_method_should_be_private( '2.7.0' );
|
2813 |
+
|
2814 |
+
try {
|
2815 |
+
$create = Stripe_Webhook::create([
|
2816 |
+
'url' => self::get_site_webhook_url(),
|
2817 |
+
'enabled_events' => self::webhook_events(),
|
2818 |
+
'api_version' => PMPRO_STRIPE_API_VERSION,
|
2819 |
+
]);
|
2820 |
+
|
2821 |
+
if ( $create ) {
|
2822 |
+
return $create->id;
|
2823 |
}
|
2824 |
+
} catch (\Throwable $th) {
|
2825 |
+
//throw $th;
|
2826 |
+
return new WP_Error( 'error', $th->getMessage() );
|
2827 |
+
} catch (\Exception $e) {
|
2828 |
+
//throw $th;
|
2829 |
+
return new WP_Error( 'error', $e->getMessage() );
|
2830 |
+
}
|
2831 |
+
|
2832 |
+
}
|
2833 |
|
2834 |
+
/**
|
2835 |
+
* See if a webhook is registered with Stripe.
|
2836 |
+
*
|
2837 |
+
* @since 2.4
|
2838 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
2839 |
+
*/
|
2840 |
+
public static function does_webhook_exist( $force = false ) {
|
2841 |
+
// Show deprecation warning if called publically.
|
2842 |
+
pmpro_method_should_be_private( '2.7.0' );
|
2843 |
|
2844 |
+
static $cached_webhook = null;
|
2845 |
+
if ( ! empty( $cached_webhook ) && ! $force ) {
|
2846 |
+
return $cached_webhook;
|
2847 |
+
}
|
2848 |
|
2849 |
+
$webhooks = self::get_webhooks();
|
2850 |
+
|
2851 |
+
$webhook_id = false;
|
2852 |
+
if ( ! empty( $webhooks ) && ! empty( $webhooks['data'] ) ) {
|
2853 |
+
|
2854 |
+
$pmpro_webhook_url = self::get_site_webhook_url();
|
2855 |
+
|
2856 |
+
foreach( $webhooks as $webhook ) {
|
2857 |
+
if ( $webhook->url == $pmpro_webhook_url ) {
|
2858 |
+
$webhook_id = $webhook->id;
|
2859 |
+
$webhook_events = $webhook->enabled_events;
|
2860 |
+
$webhook_api_version = $webhook->api_version;
|
2861 |
+
$webhook_status = $webhook->status;
|
2862 |
+
continue;
|
2863 |
+
}
|
2864 |
}
|
2865 |
+
} else {
|
2866 |
+
$webhook_id = false; // make sure it's false if none are found.
|
2867 |
+
}
|
2868 |
|
2869 |
+
if ( $webhook_id ) {
|
2870 |
+
$webhook_data = array();
|
2871 |
+
$webhook_data['webhook_id'] = $webhook_id;
|
2872 |
+
$webhook_data['enabled_events'] = $webhook_events;
|
2873 |
+
$webhook_data['api_version'] = $webhook_api_version;
|
2874 |
+
$webhook_data['status'] = $webhook_status;
|
2875 |
+
$cached_webhook = $webhook_data;
|
2876 |
+
} else {
|
2877 |
+
$cached_webhook = false;
|
2878 |
+
}
|
2879 |
+
return $cached_webhook;
|
2880 |
+
}
|
2881 |
+
|
2882 |
+
/**
|
2883 |
+
* Get a list of events that are missing between the created existing webhook and required webhook events for Paid Memberships Pro.
|
2884 |
+
*
|
2885 |
+
* @since 2.4
|
2886 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
2887 |
+
*/
|
2888 |
+
public static function check_missing_webhook_events( $webhook_events ) {
|
2889 |
+
// Show deprecation warning if called publically.
|
2890 |
+
pmpro_method_should_be_private( '2.7.0' );
|
2891 |
+
|
2892 |
+
// Get required events
|
2893 |
+
$pmpro_webhook_events = self::webhook_events();
|
2894 |
|
2895 |
+
// No missing events if webhook event is "All Events" selected.
|
2896 |
+
if ( is_array( $webhook_events ) && $webhook_events[0] === '*' ) {
|
2897 |
return false;
|
2898 |
+
}
|
2899 |
+
|
2900 |
+
if ( count( array_diff( $pmpro_webhook_events, $webhook_events ) ) ) {
|
2901 |
+
$events = array_unique( array_merge( $pmpro_webhook_events, $webhook_events ) );
|
2902 |
+
// Force reset of indexes for Stripe.
|
2903 |
+
$events = array_values( $events );
|
2904 |
+
} else {
|
2905 |
+
$events = false;
|
2906 |
}
|
2907 |
|
2908 |
+
return $events;
|
2909 |
+
}
|
|
|
2910 |
|
2911 |
+
/**
|
2912 |
+
* Update required webhook enabled events.
|
2913 |
+
*
|
2914 |
+
* @since 2.4
|
2915 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
2916 |
+
*/
|
2917 |
+
public static function update_webhook_events() {
|
2918 |
+
// Show deprecation warning if called publically.
|
2919 |
+
pmpro_method_should_be_private( '2.7.0' );
|
2920 |
|
2921 |
+
// Also checks database to see if it's been saved.
|
2922 |
+
$webhook = self::does_webhook_exist();
|
|
|
|
|
|
|
|
|
2923 |
|
2924 |
+
if ( empty( $webhook ) ) {
|
2925 |
+
$create = self::create_webhook();
|
2926 |
+
return $create;
|
2927 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2928 |
|
2929 |
+
// Bail if no enabled events for a webhook are passed through.
|
2930 |
+
if ( ! isset( $webhook['enabled_events'] ) ) {
|
2931 |
+
return;
|
2932 |
+
}
|
2933 |
+
|
2934 |
+
$events = self::check_missing_webhook_events( $webhook['enabled_events'] );
|
2935 |
+
|
2936 |
+
if ( $events ) {
|
2937 |
+
|
2938 |
+
try {
|
2939 |
+
$update = Stripe_Webhook::update(
|
2940 |
+
$webhook['webhook_id'],
|
2941 |
+
['enabled_events' => $events ]
|
2942 |
+
);
|
2943 |
+
|
2944 |
+
if ( $update ) {
|
2945 |
+
return $update;
|
2946 |
+
}
|
2947 |
+
} catch (\Throwable $th) {
|
2948 |
+
//throw $th;
|
2949 |
+
return new WP_Error( 'error', $th->getMessage() );
|
2950 |
+
} catch (\Exception $e) {
|
2951 |
+
//throw $th;
|
2952 |
+
return new WP_Error( 'error', $e->getMessage() );
|
2953 |
}
|
2954 |
+
|
|
|
|
|
2955 |
}
|
2956 |
+
|
2957 |
+
}
|
2958 |
|
2959 |
+
/**
|
2960 |
+
* Delete an existing webhook.
|
2961 |
+
*
|
2962 |
+
* @since 2.4
|
2963 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
2964 |
+
*/
|
2965 |
+
public static function delete_webhook( $webhook_id, $secretkey = false ) {
|
2966 |
+
// Show deprecation warning if called publically.
|
2967 |
+
pmpro_method_should_be_private( '2.7.0' );
|
2968 |
+
|
2969 |
+
if ( empty( $secretkey ) ) {
|
2970 |
+
$secretkey = self::get_secretkey();
|
2971 |
+
}
|
2972 |
+
if ( is_array( $webhook_id ) ) {
|
2973 |
+
$webhook_id = $webhook_id['webhook_id'];
|
2974 |
+
}
|
2975 |
+
|
2976 |
+
try {
|
2977 |
+
$stripe = new Stripe_Client( $secretkey );
|
2978 |
+
$delete = $stripe->webhookEndpoints->delete( $webhook_id, [] );
|
2979 |
+
} catch (\Throwable $th) {
|
2980 |
+
return new WP_Error( 'error', $th->getMessage() );
|
2981 |
+
} catch (\Exception $e) {
|
2982 |
+
return new WP_Error( 'error', $e->getMessage() );
|
2983 |
+
}
|
2984 |
+
|
2985 |
+
return $delete;
|
2986 |
}
|
2987 |
|
2988 |
/**
|
2989 |
* Helper method to save the subscription ID to make sure the membership doesn't get cancelled by the webhook
|
2990 |
+
*
|
2991 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
2992 |
*/
|
2993 |
+
public static function ignoreCancelWebhookForThisSubscription( $subscription_id, $user_id = null ) {
|
2994 |
+
pmpro_method_should_be_private( '2.7.0' );
|
2995 |
+
|
2996 |
if ( empty( $user_id ) ) {
|
2997 |
global $current_user;
|
2998 |
$user_id = $current_user->ID;
|
3012 |
}
|
3013 |
|
3014 |
/**
|
3015 |
+
* Helper method to process a Stripe subscription update.
|
3016 |
+
*
|
3017 |
+
* Only called during subscription updates. Should be completely deprecated once that functionality is removed.
|
3018 |
+
*
|
3019 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3020 |
*/
|
3021 |
static function updateSubscription( $update, $user_id ) {
|
3022 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3023 |
global $wpdb;
|
3024 |
|
3025 |
//get level for user
|
3029 |
$last_order = new MemberOrder();
|
3030 |
$last_order->getLastMemberOrder( $user_id );
|
3031 |
$last_order->setGateway( 'stripe' );
|
3032 |
+
$last_order->Gateway->update_customer_at_checkout( $last_order );
|
3033 |
|
3034 |
+
$subscription = $last_order->Gateway->get_subscription( $last_order->subscription_transaction_id );
|
3035 |
|
3036 |
if ( ! empty( $subscription ) ) {
|
3037 |
$end_timestamp = $subscription->current_period_end;
|
3079 |
}, 10, 2 );
|
3080 |
|
3081 |
//update subscription
|
3082 |
+
$customer = $update_order->Gateway->update_customer_at_checkout( $update_order, true );
|
3083 |
+
$order->stripe_customer = $customer;
|
3084 |
$update_order->Gateway->process_subscriptions( $update_order );
|
3085 |
|
3086 |
//update membership
|
3104 |
}
|
3105 |
|
3106 |
/**
|
3107 |
+
* Update the payment method for a subscription.
|
3108 |
*
|
3109 |
+
* Only called on update billing page. Should be completely deprecated if we switch to using Stripe Customer Portal.
|
3110 |
+
*
|
3111 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3112 |
+
*
|
3113 |
+
* @param MemberOrder $order The MemberOrder object.
|
3114 |
*/
|
3115 |
+
public function update_payment_method_for_subscriptions( &$order ) {
|
3116 |
+
pmpro_method_should_be_private( '2.7.0' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3117 |
|
|
|
|
|
|
|
|
|
|
|
|
|
3118 |
// get customer
|
3119 |
+
$customer = $this->update_customer_at_checkout( $order );
|
3120 |
|
3121 |
+
if ( empty( $customer ) ) {
|
3122 |
return false;
|
3123 |
}
|
3124 |
|
3125 |
// get all subscriptions
|
3126 |
+
if ( ! empty( $customer->subscriptions ) ) {
|
3127 |
+
$subscriptions = $customer->subscriptions->all();
|
3128 |
}
|
3129 |
|
3130 |
foreach( $subscriptions as $subscription ) {
|
3134 |
}
|
3135 |
|
3136 |
// check if we have a related order for it
|
3137 |
+
$one_order = new MemberOrder();
|
3138 |
+
$one_order->getLastMemberOrderBySubscriptionTransactionID( $subscription->id );
|
3139 |
+
if ( empty( $one_order ) || empty( $one_order->id ) ) {
|
3140 |
+
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3141 |
}
|
3142 |
+
|
3143 |
+
// update the payment method
|
3144 |
+
$subscription->default_payment_method = $customer->invoice_settings->default_payment_method;
|
3145 |
+
$subscription->save();
|
|
|
|
|
|
|
3146 |
}
|
3147 |
+
return true;
|
3148 |
}
|
3149 |
|
3150 |
/**
|
3151 |
* Helper method to cancel a subscription at Stripe and also clear up any upaid invoices.
|
3152 |
*
|
3153 |
* @since 1.8
|
3154 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3155 |
*/
|
3156 |
+
public function cancelSubscriptionAtGateway( $subscription, $preserve_local_membership = false ) {
|
3157 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3158 |
+
|
3159 |
// Check if a valid sub.
|
3160 |
if ( empty( $subscription ) || empty( $subscription->id ) ) {
|
3161 |
return false;
|
3179 |
}
|
3180 |
|
3181 |
// Okay have an order, so get customer so we can cancel invoices too
|
3182 |
+
$customer = $this->update_customer_at_checkout( $order );
|
3183 |
|
3184 |
// Get open invoices.
|
3185 |
+
$invoices = Stripe_Invoice::all(['customer' => $customer->id, 'status' => 'open']);
|
3186 |
|
3187 |
// Found it, cancel it.
|
3188 |
try {
|
3197 |
|
3198 |
// Sometimes we don't want to cancel the local membership when Stripe sends its webhook.
|
3199 |
if ( $preserve_local_membership ) {
|
3200 |
+
self::ignoreCancelWebhookForThisSubscription( $subscription->id, $order->user_id );
|
3201 |
}
|
3202 |
|
3203 |
// Cancel
|
3212 |
}
|
3213 |
|
3214 |
/**
|
3215 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3216 |
+
*/
|
3217 |
+
public function get_payment_method( &$order ) {
|
3218 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3219 |
+
if ( ! empty( $order->payment_method_id ) ) {
|
3220 |
+
try {
|
3221 |
+
$payment_method = Stripe_PaymentMethod::retrieve( $order->payment_method_id );
|
3222 |
+
} catch ( Stripe\Error\Base $e ) {
|
3223 |
+
$order->error = $e->getMessage();
|
3224 |
+
return false;
|
3225 |
+
} catch ( \Throwable $e ) {
|
3226 |
+
$order->error = $e->getMessage();
|
3227 |
+
return false;
|
3228 |
+
} catch ( \Exception $e ) {
|
3229 |
+
$order->error = $e->getMessage();
|
3230 |
+
return false;
|
3231 |
+
}
|
3232 |
+
}
|
3233 |
+
|
3234 |
+
if ( empty( $payment_method ) ) {
|
3235 |
+
return false;
|
3236 |
+
}
|
3237 |
+
|
3238 |
+
return $payment_method;
|
3239 |
+
}
|
3240 |
+
|
3241 |
+
/**
|
3242 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private in a future version.
|
3243 |
+
*/
|
3244 |
+
public function process_charges( &$order ) {
|
3245 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3246 |
+
if ( 0 == floatval( $order->InitialPayment ) ) {
|
3247 |
+
return true;
|
3248 |
+
}
|
3249 |
+
|
3250 |
+
$payment_intent = $this->get_payment_intent( $order );
|
3251 |
+
if ( empty( $payment_intent) ) {
|
3252 |
+
// There was an error, and the message should already
|
3253 |
+
// be saved on the order.
|
3254 |
+
return false;
|
3255 |
+
}
|
3256 |
+
// Save payment intent to order so that we can use it in confirm_payment_intent().
|
3257 |
+
$order->stripe_payment_intent = $payment_intent;
|
3258 |
+
|
3259 |
+
$this->confirm_payment_intent( $order );
|
3260 |
+
|
3261 |
+
if ( ! empty( $order->error ) ) {
|
3262 |
+
$order->error = $order->error;
|
3263 |
+
|
3264 |
+
return false;
|
3265 |
+
}
|
3266 |
+
|
3267 |
+
return true;
|
3268 |
+
}
|
3269 |
+
|
3270 |
+
/**
|
3271 |
+
* Only called during subscription updates. Should be completely deprecated once that functionality is removed.
|
3272 |
*
|
3273 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3274 |
+
*
|
3275 |
+
* @param MemberOrder $order The MemberOrder object.
|
3276 |
*/
|
3277 |
+
public function get_setup_intent( &$order ) {
|
3278 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3279 |
+
if ( ! empty( $order->setup_intent_id ) ) {
|
3280 |
+
try {
|
3281 |
+
$setup_intent = Stripe_SetupIntent::retrieve( $order->setup_intent_id );
|
3282 |
+
} catch ( Stripe\Error\Base $e ) {
|
3283 |
+
$order->error = $e->getMessage();
|
3284 |
+
return false;
|
3285 |
+
} catch ( \Throwable $e ) {
|
3286 |
+
$order->error = $e->getMessage();
|
3287 |
+
return false;
|
3288 |
+
} catch ( \Exception $e ) {
|
3289 |
+
$order->error = $e->getMessage();
|
3290 |
+
return false;
|
3291 |
+
}
|
3292 |
+
}
|
3293 |
|
3294 |
+
if ( empty( $setup_intent ) ) {
|
3295 |
+
$setup_intent = $this->create_setup_intent( $order );
|
3296 |
+
}
|
|
|
3297 |
|
3298 |
+
if ( empty( $setup_intent ) ) {
|
3299 |
+
return false;
|
3300 |
+
}
|
3301 |
+
|
3302 |
+
return $setup_intent;
|
3303 |
+
}
|
3304 |
+
|
3305 |
+
/**
|
3306 |
+
* @deprecated 2.7.0. Use get_setup_intent() instead.
|
3307 |
+
*/
|
3308 |
+
public function set_setup_intent( &$order, $force = false ) {
|
3309 |
+
_deprecated_function( __FUNCTION__, '2.7.0', 'get_setup_intent()' );
|
3310 |
+
if ( ! empty( $this->setup_intent ) && ! $force ) {
|
3311 |
+
return true;
|
3312 |
+
}
|
3313 |
+
|
3314 |
+
$setup_intent = $this->get_setup_intent( $order );
|
3315 |
+
|
3316 |
+
if ( empty( $setup_intent ) ) {
|
3317 |
+
return false;
|
3318 |
+
}
|
3319 |
+
|
3320 |
+
$this->setup_intent = $setup_intent;
|
3321 |
+
|
3322 |
+
return true;
|
3323 |
+
}
|
3324 |
+
|
3325 |
+
/**
|
3326 |
+
* Only called during subscription updates. Should be completely deprecated once that functionality is removed.
|
3327 |
+
*
|
3328 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3329 |
+
*
|
3330 |
+
* @param MemberOrder $order The MemberOrder object.
|
3331 |
+
*/
|
3332 |
+
public function create_setup_intent( &$order ) {
|
3333 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3334 |
+
$this->create_plan( $order );
|
3335 |
+
$order->stripe_subscription = $this->create_subscription( $order );
|
3336 |
+
$this->delete_plan( $order );
|
3337 |
+
|
3338 |
+
if ( ! empty( $order->error ) || empty( $order->stripe_subscription->pending_setup_intent ) ) {
|
3339 |
+
return false;
|
3340 |
+
}
|
3341 |
+
|
3342 |
+
return $order->stripe_subscription->pending_setup_intent;
|
3343 |
+
}
|
3344 |
+
|
3345 |
+
/**
|
3346 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3347 |
+
*/
|
3348 |
+
public function confirm_payment_intent( &$order ) {
|
3349 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3350 |
+
try {
|
3351 |
+
$params = array(
|
3352 |
+
'expand' => array(
|
3353 |
+
'payment_method',
|
3354 |
+
),
|
3355 |
+
);
|
3356 |
+
$order->stripe_payment_intent->confirm( $params );
|
3357 |
+
} catch ( Stripe\Error\Base $e ) {
|
3358 |
+
$order->error = $e->getMessage();
|
3359 |
+
return false;
|
3360 |
+
} catch ( \Throwable $e ) {
|
3361 |
+
$order->error = $e->getMessage();
|
3362 |
+
return false;
|
3363 |
+
} catch ( \Exception $e ) {
|
3364 |
+
$order->error = $e->getMessage();
|
3365 |
+
return false;
|
3366 |
+
}
|
3367 |
+
|
3368 |
+
if ( 'requires_action' == $order->stripe_payment_intent->status ) {
|
3369 |
+
$order->errorcode = true;
|
3370 |
+
$order->error = __( 'Customer authentication is required to complete this transaction. Please complete the verification steps issued by your payment provider.', 'paid-memberships-pro' );
|
3371 |
+
$order->error_type = 'pmpro_alert';
|
3372 |
+
|
3373 |
+
return false;
|
3374 |
+
}
|
3375 |
+
|
3376 |
+
return true;
|
3377 |
+
}
|
3378 |
+
|
3379 |
+
/**
|
3380 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3381 |
+
*/
|
3382 |
+
public function confirm_setup_intent( &$order ) {
|
3383 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3384 |
+
if ( empty( $order->stripe_setup_intent ) ) {
|
3385 |
+
return true;
|
3386 |
+
}
|
3387 |
+
|
3388 |
+
if ( 'requires_action' === $order->stripe_setup_intent->status ) {
|
3389 |
+
$order->errorcode = true;
|
3390 |
+
$order->error = __( 'Customer authentication is required to finish setting up your subscription. Please complete the verification steps issued by your payment provider.', 'paid-memberships-pro' );
|
3391 |
+
|
3392 |
+
return false;
|
3393 |
+
}
|
3394 |
+
|
3395 |
+
}
|
3396 |
+
|
3397 |
+
/**
|
3398 |
+
* Get available Apple Pay domains.
|
3399 |
+
*
|
3400 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3401 |
+
*/
|
3402 |
+
public function pmpro_get_apple_pay_domains( $limit = 10 ) {
|
3403 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3404 |
+
try {
|
3405 |
+
$apple_pay_domains = Stripe_ApplePayDomain::all( [ 'limit' => apply_filters( 'pmpro_stripe_apple_pay_domain_retrieve_limit', $limit ) ] );
|
3406 |
+
} catch (\Throwable $th) {
|
3407 |
+
$apple_pay_domains = array();
|
3408 |
+
}
|
3409 |
+
|
3410 |
+
return $apple_pay_domains;
|
3411 |
+
}
|
3412 |
+
|
3413 |
+
/**
|
3414 |
+
* Register domain with Apple Pay.
|
3415 |
+
*
|
3416 |
+
* @since 2.4
|
3417 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3418 |
+
*/
|
3419 |
+
public function pmpro_create_apple_pay_domain() {
|
3420 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3421 |
+
try {
|
3422 |
+
$create = Stripe_ApplePayDomain::create([
|
3423 |
+
'domain_name' => $_SERVER['HTTP_HOST'],
|
3424 |
+
]);
|
3425 |
+
} catch (\Throwable $th) {
|
3426 |
+
//throw $th;
|
3427 |
+
return false;
|
3428 |
+
}
|
3429 |
+
return $create;
|
3430 |
+
}
|
3431 |
+
|
3432 |
+
/**
|
3433 |
+
* See if domain is registered with Apple Pay.
|
3434 |
+
*
|
3435 |
+
* @since 2.4
|
3436 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3437 |
+
*/
|
3438 |
+
public function pmpro_does_apple_pay_domain_exist() {
|
3439 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3440 |
+
$apple_pay_domains = $this->pmpro_get_apple_pay_domains();
|
3441 |
+
|
3442 |
+
if ( empty( $apple_pay_domains ) ) {
|
3443 |
+
return false;
|
3444 |
+
}
|
3445 |
+
|
3446 |
+
foreach( $apple_pay_domains as $apple_pay_domain ) {
|
3447 |
+
if ( $apple_pay_domain->domain_name === $_SERVER['HTTP_HOST'] ) {
|
3448 |
+
return true;
|
3449 |
}
|
3450 |
}
|
3451 |
+
return false;
|
3452 |
+
}
|
3453 |
|
3454 |
+
/**
|
3455 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3456 |
+
*/
|
3457 |
+
public function get_account() {
|
3458 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3459 |
+
try {
|
3460 |
+
$account = Stripe_Account::retrieve();
|
3461 |
+
} catch ( Stripe\Error\Base $e ) {
|
3462 |
+
return false;
|
3463 |
+
} catch ( \Throwable $e ) {
|
3464 |
+
return false;
|
3465 |
+
} catch ( \Exception $e ) {
|
3466 |
+
return false;
|
3467 |
+
}
|
3468 |
+
|
3469 |
+
if ( empty( $account ) ) {
|
3470 |
+
return false;
|
3471 |
+
}
|
3472 |
+
|
3473 |
+
return $account;
|
3474 |
+
}
|
3475 |
+
|
3476 |
+
/**
|
3477 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3478 |
+
*/
|
3479 |
+
public static function get_account_country() {
|
3480 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3481 |
+
$account_country = get_transient( 'pmpro_stripe_account_country' );
|
3482 |
+
if ( empty( $account_country ) ) {
|
3483 |
+
$stripe = new PMProGateway_stripe();
|
3484 |
+
$account = $stripe->get_account();
|
3485 |
+
if ( ! empty( $account ) && ! empty( $account->country ) ) {
|
3486 |
+
$account_country = $account->country;
|
3487 |
+
set_transient( 'pmpro_stripe_account_country', $account_country );
|
3488 |
+
}
|
3489 |
+
}
|
3490 |
+
return $account_country ?: 'US';
|
3491 |
+
}
|
3492 |
+
|
3493 |
+
/**
|
3494 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3495 |
+
*/
|
3496 |
+
public function clean_up( &$order ) {
|
3497 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3498 |
+
if ( ! empty( $order->stripe_payment_intent ) && 'succeeded' == $order->stripe_payment_intent->status ) {
|
3499 |
+
$order->payment_transaction_id = $order->stripe_payment_intent->charges->data[0]->id;
|
3500 |
+
}
|
3501 |
+
|
3502 |
+
if ( empty( $order->subscription_transaction_id ) && ! empty( $order->stripe_subscription ) ) {
|
3503 |
+
$order->subscription_transaction_id = $order->stripe_subscription->id;
|
3504 |
+
}
|
3505 |
+
}
|
3506 |
+
|
3507 |
+
/**
|
3508 |
+
* Get percentage of Stripe payment to charge as application fee.
|
3509 |
+
*
|
3510 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3511 |
+
*
|
3512 |
+
* @return int percentage to charge for application fee.
|
3513 |
+
*/
|
3514 |
+
public static function get_application_fee_percentage() {
|
3515 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3516 |
+
$application_fee_percentage = pmpro_license_isValid( null, 'plus' ) ? 0 : 1;
|
3517 |
+
$application_fee_percentage = apply_filters( 'pmpro_set_application_fee_percentage', $application_fee_percentage );
|
3518 |
+
return round( floatval( $application_fee_percentage ), 2 );
|
3519 |
+
}
|
3520 |
+
|
3521 |
+
/**
|
3522 |
+
* Add application fee to params to be sent to Stripe.
|
3523 |
+
*
|
3524 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3525 |
+
*
|
3526 |
+
* @param array $params to be sent to Stripe.
|
3527 |
+
* @param bool $add_percent true if percentage should be added, false if actual amount.
|
3528 |
+
* @return array params with application fee if applicable.
|
3529 |
+
*/
|
3530 |
+
public static function add_application_fee_amount( $params ) {
|
3531 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3532 |
+
if ( empty( $params['amount'] ) || self::using_legacy_keys() ) {
|
3533 |
+
return $params;
|
3534 |
+
}
|
3535 |
+
$amount = $params['amount'];
|
3536 |
+
$application_fee = $amount * ( self::get_application_fee_percentage() / 100 );
|
3537 |
+
$application_fee = floor( $application_fee );
|
3538 |
+
if ( ! empty( $application_fee ) ) {
|
3539 |
+
$params['application_fee_amount'] = intval( $application_fee );
|
3540 |
+
}
|
3541 |
+
return $params;
|
3542 |
+
}
|
3543 |
+
|
3544 |
+
/**
|
3545 |
+
* Should we show the legacy key fields on the payment settings page.
|
3546 |
+
* We should if the site is using legacy keys already or
|
3547 |
+
* if a filter has been set.
|
3548 |
+
* @since 2.6
|
3549 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3550 |
+
*/
|
3551 |
+
public static function show_legacy_keys_settings() {
|
3552 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3553 |
+
$r = self::using_legacy_keys();
|
3554 |
+
$r = apply_filters( 'pmpro_stripe_show_legacy_keys_settings', $r );
|
3555 |
+
return $r;
|
3556 |
+
}
|
3557 |
+
|
3558 |
+
/**
|
3559 |
+
* Get the Stripe secret key based on gateway environment.
|
3560 |
+
*
|
3561 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3562 |
+
*
|
3563 |
+
* @return The Stripe secret key.
|
3564 |
+
*/
|
3565 |
+
public static function get_secretkey() {
|
3566 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3567 |
+
$secretkey = '';
|
3568 |
+
if ( self::using_legacy_keys() ) {
|
3569 |
+
$secretkey = pmpro_getOption( 'stripe_secretkey' );
|
3570 |
+
} else {
|
3571 |
+
$secretkey = pmpro_getOption( 'gateway_environment' ) === 'live'
|
3572 |
+
? pmpro_getOption( 'live_stripe_connect_secretkey' )
|
3573 |
+
: pmpro_getOption( 'sandbox_stripe_connect_secretkey' );
|
3574 |
+
}
|
3575 |
+
return $secretkey;
|
3576 |
+
}
|
3577 |
+
|
3578 |
+
/**
|
3579 |
+
* Get the Stripe publishable key based on gateway environment.
|
3580 |
+
*
|
3581 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3582 |
+
*
|
3583 |
+
* @return The Stripe publishable key.
|
3584 |
+
*/
|
3585 |
+
public static function get_publishablekey() {
|
3586 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3587 |
+
$publishablekey = '';
|
3588 |
+
if ( self::using_legacy_keys() ) {
|
3589 |
+
$publishablekey = pmpro_getOption( 'stripe_publishablekey' );
|
3590 |
+
} else {
|
3591 |
+
$publishablekey = pmpro_getOption( 'gateway_environment' ) === 'live'
|
3592 |
+
? pmpro_getOption( 'live_stripe_connect_publishablekey' )
|
3593 |
+
: pmpro_getOption( 'sandbox_stripe_connect_publishablekey' );
|
3594 |
+
}
|
3595 |
+
return $publishablekey;
|
3596 |
}
|
3597 |
|
3598 |
/**
|
3599 |
+
* Get the Stripe Connect User ID based on gateway environment.
|
3600 |
*
|
3601 |
+
* @since 2.6.0
|
3602 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3603 |
*
|
3604 |
+
* @return string The Stripe Connect User ID.
|
3605 |
*/
|
3606 |
+
public static function get_connect_user_id() {
|
3607 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3608 |
+
return pmpro_getOption( 'gateway_environment' ) === 'live'
|
3609 |
+
? pmpro_getOption( 'live_stripe_connect_user_id' )
|
3610 |
+
: pmpro_getOption( 'sandbox_stripe_connect_user_id' );
|
3611 |
}
|
3612 |
|
3613 |
/**
|
3614 |
+
* Determine whether the webhook is working by checking for Stripe orders with invalid transaction IDs.
|
3615 |
*
|
3616 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
|
|
3617 |
*
|
3618 |
+
* @param string|null $gateway_environment to check webhooks for. Defaults to set gateway environment.
|
3619 |
+
* @return bool Whether the webhook is working.
|
3620 |
*/
|
3621 |
+
public static function webhook_is_working( $gateway_environment = null ) {
|
3622 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3623 |
+
global $wpdb;
|
|
|
|
|
3624 |
|
3625 |
+
if ( empty( $gateway_environment ) ) {
|
3626 |
+
$gateway_engvironemnt = pmpro_getOption( 'pmpro_gateway_environment' );
|
|
|
3627 |
}
|
3628 |
|
3629 |
+
$last_webhook = get_option( 'pmpro_stripe_last_webhook_received_' . $gateway_environment );
|
|
|
|
|
3630 |
|
3631 |
+
if ( empty( $last_webhook ) ) {
|
3632 |
+
// Probably never got a webhook event.
|
3633 |
+
$last_webhook_safe = date( 'Y-m-d H:i:s', strtotime( '-5 years' ) );
|
3634 |
+
} else {
|
3635 |
+
// In case recurring order made after webhook event received.
|
3636 |
+
$last_webhook_safe = date( 'Y-m-d H:i:s', strtotime( $last_webhook . ' +5 minutes' ) );
|
3637 |
+
}
|
3638 |
+
|
3639 |
+
$hour_before_now = date( 'Y-m-d H:i:s', strtotime( '-1 hour' ) );
|
3640 |
+
|
3641 |
+
$num_problem_orders = $wpdb->get_var(
|
3642 |
+
$wpdb->prepare(
|
3643 |
+
"
|
3644 |
+
SELECT COUNT(*)
|
3645 |
+
FROM `{$wpdb->pmpro_membership_orders}`
|
3646 |
+
WHERE
|
3647 |
+
`gateway` = 'stripe'
|
3648 |
+
AND `gateway_environment` = %s
|
3649 |
+
AND `subscription_transaction_id` <> ''
|
3650 |
+
AND `subscription_transaction_id` IS NOT NULL
|
3651 |
+
AND `timestamp` > %s
|
3652 |
+
AND `timestamp` < %s
|
3653 |
+
",
|
3654 |
+
$gateway_environment,
|
3655 |
+
$last_webhook_safe,
|
3656 |
+
$hour_before_now
|
3657 |
+
)
|
3658 |
+
);
|
3659 |
+
|
3660 |
+
return ( empty( $num_problem_orders ) );
|
3661 |
+
}
|
3662 |
+
|
3663 |
+
/**
|
3664 |
+
* Get the date the last webhook was processed.
|
3665 |
+
* @param environment The gateway environment (live or sandbox) to check for.
|
3666 |
+
* @returns HTML with the date of the last webhook or an error message.
|
3667 |
+
* @since 2.6
|
3668 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3669 |
+
*/
|
3670 |
+
public static function get_last_webhook_date( $environment = 'live' ) {
|
3671 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3672 |
+
$last_webhook = get_option( 'pmpro_stripe_last_webhook_received_' . $environment );
|
3673 |
+
if ( ! empty( $last_webhook ) ) {
|
3674 |
+
echo '<p>' . esc_html__( 'Last webhook received at', 'paid-memberships-pro' ) . ': ' . esc_html( $last_webhook ) . ' GMT.</p>';
|
3675 |
+
} else {
|
3676 |
+
echo '<p>' . esc_html__( 'No webhooks have been received.', 'paid-memberships-pro' ) . '</p>';
|
3677 |
}
|
3678 |
+
if ( ! self::webhook_is_working( $environment ) ) {
|
3679 |
+
echo '<div class="notice error inline"><p>';
|
3680 |
+
echo esc_html__( 'Your webhook may not be working correctly.', 'paid-memberships-pro' );
|
3681 |
+
echo ' <a target="_blank" href="https://www.paidmembershipspro.com/gateway/stripe/?utm_source=plugin&utm_medium=pmpro-paymentsettings&utm_campaign=gateways&utm_content=stripe-webhook#tab-gateway-setup">';
|
3682 |
+
echo esc_html__( 'Click here for info on setting up your webhook with Stripe.', 'paid-memberships-pro' );
|
3683 |
+
echo '</a>';
|
3684 |
+
echo '</p></div>';
|
3685 |
+
}
|
3686 |
+
}
|
3687 |
|
3688 |
+
/**
|
3689 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private in a future version.
|
3690 |
+
*/
|
3691 |
+
public function get_payment_intent( &$order ) {
|
3692 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3693 |
+
if ( ! empty( $order->payment_intent_id ) ) {
|
3694 |
+
try {
|
3695 |
+
$payment_intent = Stripe_PaymentIntent::retrieve( $order->payment_intent_id );
|
3696 |
+
} catch ( Stripe\Error\Base $e ) {
|
3697 |
+
$order->error = $e->getMessage();
|
3698 |
+
return false;
|
3699 |
+
} catch ( \Throwable $e ) {
|
3700 |
+
$order->error = $e->getMessage();
|
3701 |
+
return false;
|
3702 |
+
} catch ( \Exception $e ) {
|
3703 |
+
$order->error = $e->getMessage();
|
3704 |
+
return false;
|
3705 |
+
}
|
3706 |
}
|
3707 |
|
3708 |
+
if ( empty( $payment_intent ) ) {
|
3709 |
+
$payment_intent = $this->create_payment_intent( $order );
|
3710 |
+
}
|
|
|
|
|
|
|
3711 |
|
3712 |
+
if ( empty( $payment_intent ) ) {
|
3713 |
return false;
|
3714 |
}
|
3715 |
|
3716 |
+
return $payment_intent;
|
3717 |
+
}
|
3718 |
+
|
3719 |
+
/**
|
3720 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private in a future version.
|
3721 |
+
*/
|
3722 |
+
public function create_payment_intent( &$order ) {
|
3723 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3724 |
+
global $pmpro_currency;
|
3725 |
+
|
3726 |
+
$amount = $order->InitialPayment;
|
3727 |
+
$order->subtotal = $amount;
|
3728 |
+
$tax = $order->getTax( true );
|
3729 |
+
|
3730 |
+
$amount = pmpro_round_price( (float) $order->subtotal + (float) $tax );
|
3731 |
+
|
3732 |
+
$params = array(
|
3733 |
+
'customer' => $order->stripe_customer->id,
|
3734 |
+
'payment_method' => $order->payment_method_id,
|
3735 |
+
'amount' => $this->convert_price_to_unit_amount( $amount ),
|
3736 |
+
'currency' => $pmpro_currency,
|
3737 |
+
'confirmation_method' => 'manual',
|
3738 |
+
'description' => apply_filters( 'pmpro_stripe_order_description', "Order #" . $order->code . ", " . trim( $order->FirstName . " " . $order->LastName ) . " (" . $order->Email . ")", $order ),
|
3739 |
+
'setup_future_usage' => 'off_session',
|
3740 |
+
);
|
3741 |
+
$params = self::add_application_fee_amount( $params );
|
3742 |
+
|
3743 |
+
/**
|
3744 |
+
* Filter params used to create the payment intent.
|
3745 |
+
*
|
3746 |
+
* @since 2.4.1
|
3747 |
+
*
|
3748 |
+
* @param array $params Array of params sent to Stripe.
|
3749 |
+
* @param object $order Order object for this checkout.
|
3750 |
+
*/
|
3751 |
+
$params = apply_filters( 'pmpro_stripe_payment_intent_params', $params, $order );
|
3752 |
+
|
3753 |
try {
|
3754 |
+
$payment_intent = Stripe_PaymentIntent::create( $params );
|
3755 |
+
} catch ( Stripe\Error\Base $e ) {
|
3756 |
+
$order->error = $e->getMessage();
|
3757 |
+
return false;
|
3758 |
} catch ( \Throwable $e ) {
|
3759 |
+
$order->error = $e->getMessage();
|
|
|
|
|
|
|
3760 |
return false;
|
3761 |
} catch ( \Exception $e ) {
|
3762 |
+
$order->error = $e->getMessage();
|
|
|
|
|
|
|
3763 |
return false;
|
3764 |
}
|
3765 |
|
3766 |
+
return $payment_intent;
|
3767 |
+
}
|
|
|
3768 |
|
3769 |
+
/**
|
3770 |
+
* Only called during subscription updates. Should be completely deprecated once that functionality is removed.
|
3771 |
+
*
|
3772 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private in a future version.
|
3773 |
+
*
|
3774 |
+
* @param MemberOrder $order The MemberOrder object.
|
3775 |
+
*/
|
3776 |
+
public function process_subscriptions( &$order ) {
|
3777 |
+
pmpro_method_should_be_private( '2.7.0' );
|
3778 |
+
if ( ! pmpro_isLevelRecurring( $order->membership_level ) ) {
|
3779 |
return true;
|
3780 |
+
}
|
|
|
|
|
|
|
|
|
3781 |
|
3782 |
+
//before subscribing, let's clear out the updates so we don't trigger any during sub
|
3783 |
+
if ( ! empty( $user_id ) ) {
|
3784 |
+
$old_user_updates = get_user_meta( $user_id, "pmpro_stripe_updates", true );
|
3785 |
+
update_user_meta( $user_id, "pmpro_stripe_updates", array() );
|
3786 |
}
|
|
|
3787 |
|
3788 |
+
$setup_intent = $this->get_setup_intent( $order );
|
3789 |
+
if ( empty( $setup_intent ) ) {
|
3790 |
+
// There was an error, and the message should already
|
3791 |
+
// be saved on the order.
|
3792 |
+
return false;
|
3793 |
}
|
3794 |
+
// Save setup intent to order so that we can use it in confirm_setup_intent().
|
3795 |
+
$order->stripe_setup_intent = $setup_intent;
|
3796 |
|
3797 |
+
$this->confirm_setup_intent( $order );
|
3798 |
+
|
3799 |
+
if ( ! empty( $order->error ) ) {
|
3800 |
+
$order->error = $order->error;
|
3801 |
+
|
3802 |
+
//give the user any old updates back
|
3803 |
+
if ( ! empty( $user_id ) ) {
|
3804 |
+
update_user_meta( $user_id, "pmpro_stripe_updates", $old_user_updates );
|
3805 |
+
}
|
3806 |
|
|
|
3807 |
return false;
|
3808 |
}
|
3809 |
|
3810 |
+
//save new updates if this is at checkout
|
3811 |
+
//empty out updates unless set above
|
3812 |
+
if ( empty( $new_user_updates ) ) {
|
3813 |
+
$new_user_updates = array();
|
3814 |
+
}
|
3815 |
+
|
3816 |
+
//update user meta
|
3817 |
+
if ( ! empty( $user_id ) ) {
|
3818 |
+
update_user_meta( $user_id, "pmpro_stripe_updates", $new_user_updates );
|
3819 |
+
} else {
|
3820 |
+
//need to remember the user updates to save later
|
3821 |
+
global $pmpro_stripe_updates;
|
3822 |
+
$pmpro_stripe_updates = $new_user_updates;
|
3823 |
+
|
3824 |
+
if( ! function_exists( 'pmpro_user_register_stripe_updates' ) ) {
|
3825 |
+
function pmpro_user_register_stripe_updates( $user_id ) {
|
3826 |
+
global $pmpro_stripe_updates;
|
3827 |
+
update_user_meta( $user_id, 'pmpro_stripe_updates', $pmpro_stripe_updates );
|
3828 |
+
}
|
3829 |
+
add_action( 'user_register', 'pmpro_user_register_stripe_updates' );
|
3830 |
+
}
|
3831 |
+
}
|
3832 |
|
3833 |
return true;
|
3834 |
}
|
3835 |
|
3836 |
+
/**
|
3837 |
+
* Only called during subscription updates. Should be completely deprecated once that functionality is removed.
|
3838 |
+
*
|
3839 |
+
* @deprecated 2.7.0. Will only be deprecated once we create a function with better params.
|
3840 |
+
*
|
3841 |
+
* @param MemberOrder $order The MemberOrder object.
|
3842 |
+
*/
|
3843 |
+
public function create_subscription( &$order ) {
|
3844 |
+
// _deprecated_function( __FUNCTION__, '2.7.0' );
|
3845 |
+
//subscribe to the plan
|
3846 |
+
try {
|
3847 |
+
$params = array(
|
3848 |
+
'customer' => $order->stripe_customer->id,
|
3849 |
+
'items' => array(
|
3850 |
+
array( 'plan' => $order->code ),
|
3851 |
+
),
|
3852 |
+
'trial_period_days' => $order->TrialPeriodDays,
|
3853 |
+
'expand' => array(
|
3854 |
+
'pending_setup_intent.payment_method',
|
3855 |
+
),
|
3856 |
+
);
|
3857 |
+
if ( ! self::using_legacy_keys() ) {
|
3858 |
+
$params['application_fee_percent'] = self::get_application_fee_percentage();
|
3859 |
+
}
|
3860 |
+
$order->subscription = Stripe_Subscription::create( apply_filters( 'pmpro_stripe_create_subscription_array', $params ) );
|
3861 |
+
} catch ( Stripe\Error\Base $e ) {
|
3862 |
+
$order->error = $e->getMessage();
|
3863 |
+
return false;
|
3864 |
+
} catch ( \Throwable $e ) {
|
3865 |
+
$order->error = $e->getMessage();
|
3866 |
+
return false;
|
3867 |
+
} catch ( \Exception $e ) {
|
3868 |
+
$order->error = $e->getMessage();
|
3869 |
+
return false;
|
3870 |
+
}
|
3871 |
+
|
3872 |
+
return $order->subscription;
|
3873 |
|
3874 |
+
}
|
3875 |
+
|
3876 |
+
/**
|
3877 |
+
* Only called during subscription updates. Should be completely deprecated once that functionality is removed.
|
3878 |
+
*
|
3879 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3880 |
+
*
|
3881 |
+
* @param MemberOrder $order The MemberOrder object.
|
3882 |
+
*/
|
3883 |
+
public function delete_plan( &$order ) {
|
3884 |
+
// _deprecated_function( __FUNCTION__, '2.7.0' );
|
3885 |
+
try {
|
3886 |
+
// Delete the product first while we have a reference to it...
|
3887 |
+
if ( ( ! empty( $order->plan->product ) ) && ( ! $this->archive_product( $order ) ) ) {
|
3888 |
return false;
|
3889 |
}
|
3890 |
+
// Then delete the plan.
|
3891 |
+
$order->plan->delete();
|
3892 |
+
} catch ( Stripe\Error\Base $e ) {
|
3893 |
+
$order->error = $e->getMessage();
|
3894 |
+
|
3895 |
+
return false;
|
3896 |
+
} catch ( \Throwable $e ) {
|
3897 |
+
$order->error = $e->getMessage();
|
3898 |
+
|
3899 |
+
return false;
|
3900 |
+
} catch ( \Exception $e ) {
|
3901 |
+
$order->error = $e->getMessage();
|
3902 |
+
|
3903 |
+
return false;
|
3904 |
}
|
3905 |
|
3906 |
+
return true;
|
3907 |
+
}
|
3908 |
+
|
3909 |
+
/**
|
3910 |
+
* Only called during subscription updates. Should be completely deprecated once that functionality is removed.
|
3911 |
+
*
|
3912 |
+
* @deprecated 2.7.0. Only deprecated for public use, will be changed to private non-static in a future version.
|
3913 |
+
*
|
3914 |
+
* @param MemberOrder $order The MemberOrder object.
|
3915 |
+
*/
|
3916 |
+
public function archive_product( &$order ) {
|
3917 |
+
// _deprecated_function( __FUNCTION__, '2.7.0' );
|
3918 |
+
try {
|
3919 |
+
$product = Stripe_Product::update( $order->plan->product, array( 'active' => false ) );
|
3920 |
+
} catch ( Stripe\Error\Base $e ) {
|
3921 |
+
$order->error = $e->getMessage();
|
3922 |
+
return false;
|
3923 |
+
} catch ( \Throwable $e ) {
|
3924 |
+
$order->error = $e->getMessage();
|
3925 |
+
return false;
|
3926 |
+
} catch ( \Exception $e ) {
|
3927 |
+
$order->error = $e->getMessage();
|
3928 |
return false;
|
3929 |
}
|
3930 |
|
3931 |
+
return true;
|
3932 |
}
|
3933 |
|
3934 |
+
/****************************************
|
3935 |
+
********** DEPRECATED METHODS **********
|
3936 |
+
****************************************/
|
3937 |
+
/**
|
3938 |
+
* Make a one-time charge with Stripe
|
3939 |
+
*
|
3940 |
+
* @since 1.4
|
3941 |
+
* @deprecated 2.7.0. Use process_charges() instead.
|
3942 |
+
*/
|
3943 |
+
public function charge( &$order ) {
|
3944 |
+
_deprecated_function( __FUNCTION__, '2.7.0' );
|
3945 |
+
global $pmpro_currency;
|
3946 |
+
|
3947 |
+
//create a code for the order
|
3948 |
+
if ( empty( $order->code ) ) {
|
3949 |
+
$order->code = $order->getRandomCode();
|
3950 |
}
|
|
|
|
|
3951 |
|
3952 |
+
//what amount to charge?
|
3953 |
+
$amount = $order->InitialPayment;
|
3954 |
|
3955 |
+
//tax
|
3956 |
+
$order->subtotal = $amount;
|
3957 |
+
$tax = $order->getTax( true );
|
3958 |
+
$amount = pmpro_round_price( (float) $order->subtotal + (float) $tax );
|
3959 |
+
|
3960 |
+
//create a customer
|
3961 |
+
$customer = $this->update_customer_at_checkout( $order );
|
3962 |
+
if ( empty( $customer ) ) {
|
3963 |
+
//failed to create customer
|
3964 |
+
return false;
|
3965 |
}
|
3966 |
|
3967 |
+
//charge
|
3968 |
try {
|
3969 |
+
$params = array(
|
3970 |
+
"amount" => $this->convert_price_to_unit_amount( $amount ), # amount in cents, again
|
3971 |
+
"currency" => strtolower( $pmpro_currency ),
|
3972 |
+
"customer" => $customer->id,
|
3973 |
+
"description" => apply_filters( 'pmpro_stripe_order_description', "Order #" . $order->code . ", " . trim( $order->FirstName . " " . $order->LastName ) . " (" . $order->Email . ")", $order )
|
3974 |
+
);
|
3975 |
+
$params = self::add_application_fee_amount( $params );
|
3976 |
+
/**
|
3977 |
+
* Filter params used to create the Stripe charge.
|
3978 |
+
*
|
3979 |
+
* @since 2.4.4
|
3980 |
+
*
|
3981 |
+
* @param array $params Array of params sent to Stripe.
|
3982 |
+
* @param object $order Order object for this checkout.
|
3983 |
+
*/
|
3984 |
+
$params = apply_filters( 'pmpro_stripe_charge_params', $params, $order );
|
3985 |
+
$response = Stripe_Charge::create( $params );
|
3986 |
} catch ( \Throwable $e ) {
|
3987 |
+
//$order->status = "error";
|
3988 |
+
$order->errorcode = true;
|
3989 |
+
$order->error = "Error: " . $e->getMessage();
|
3990 |
+
$order->shorterror = $order->error;
|
3991 |
+
|
3992 |
return false;
|
3993 |
} catch ( \Exception $e ) {
|
3994 |
+
//$order->status = "error";
|
3995 |
+
$order->errorcode = true;
|
3996 |
+
$order->error = "Error: " . $e->getMessage();
|
3997 |
+
$order->shorterror = $order->error;
|
3998 |
+
|
3999 |
return false;
|
4000 |
}
|
4001 |
|
4002 |
+
if ( empty( $response["failure_message"] ) ) {
|
4003 |
+
//successful charge
|
4004 |
+
$order->payment_transaction_id = $response["id"];
|
4005 |
+
$order->updateStatus( "success" );
|
4006 |
+
$order->saveOrder();
|
4007 |
|
|
|
4008 |
return true;
|
4009 |
+
} else {
|
4010 |
+
//$order->status = "error";
|
4011 |
+
$order->errorcode = true;
|
4012 |
+
$order->error = $response['failure_message'];
|
4013 |
+
$order->shorterror = $response['failure_message'];
|
|
|
|
|
4014 |
|
4015 |
return false;
|
4016 |
}
|
4017 |
+
}
|
4018 |
|
4019 |
+
/**
|
4020 |
+
* Get a Stripe Customer object and update it.
|
4021 |
+
*
|
4022 |
+
* @since 1.4
|
4023 |
+
* @deprecated 2.7.0. Use get_customer_for_user() or update_customer_from_user().
|
4024 |
+
*
|
4025 |
+
* @return Stripe_Customer|false
|
4026 |
+
*/
|
4027 |
+
public function getCustomer( &$order = false, $force = false ) {
|
4028 |
+
_deprecated_function( __FUNCTION__, '2.7.0', 'update_customer_from_user()' );
|
4029 |
+
return $this->update_customer_at_checkout( $order );
|
4030 |
}
|
4031 |
|
4032 |
+
/**
|
4033 |
+
* Get a Stripe subscription from a PMPro order
|
4034 |
+
*
|
4035 |
+
* @since 1.8
|
4036 |
+
* @deprecated 2.7.0. Need to write replacement methods for this.
|
4037 |
+
*/
|
4038 |
+
public function getSubscription( &$order ) {
|
4039 |
+
_deprecated_function( __FUNCTION__, '2.7.0' );
|
4040 |
+
global $wpdb;
|
4041 |
|
4042 |
+
//no order?
|
4043 |
+
if ( empty( $order ) || empty( $order->code ) ) {
|
4044 |
+
return false;
|
4045 |
}
|
4046 |
|
4047 |
+
$customer = $this->update_customer_at_checkout( $order, true ); //force so we don't get a cached sub for someone else
|
4048 |
|
4049 |
+
//no customer?
|
4050 |
+
if ( empty( $customer ) ) {
|
4051 |
return false;
|
4052 |
}
|
4053 |
|
4054 |
+
//no subscriptions?
|
4055 |
+
if ( empty( $customer->subscriptions ) ) {
|
4056 |
+
return false;
|
4057 |
+
}
|
|
|
|
|
4058 |
|
4059 |
+
//is there a subscription transaction id pointing to a sub?
|
4060 |
+
if ( ! empty( $order->subscription_transaction_id ) && strpos( $order->subscription_transaction_id, "sub_" ) !== false ) {
|
4061 |
try {
|
4062 |
+
$sub = $customer->subscriptions->retrieve( $order->subscription_transaction_id );
|
|
|
|
|
|
|
4063 |
} catch ( \Throwable $e ) {
|
4064 |
+
$order->error = __( "Error getting subscription with Stripe:", 'paid-memberships-pro' ) . $e->getMessage();
|
4065 |
+
$order->shorterror = $order->error;
|
4066 |
+
|
4067 |
return false;
|
4068 |
} catch ( \Exception $e ) {
|
4069 |
+
$order->error = __( "Error getting subscription with Stripe:", 'paid-memberships-pro' ) . $e->getMessage();
|
4070 |
+
$order->shorterror = $order->error;
|
4071 |
+
|
4072 |
return false;
|
4073 |
}
|
|
|
4074 |
|
4075 |
+
return $sub;
|
|
|
4076 |
}
|
4077 |
|
4078 |
+
//find subscription based on customer id and order/plan id
|
4079 |
+
$subscriptions = $customer->subscriptions->all();
|
4080 |
+
|
4081 |
+
//no subscriptions
|
4082 |
+
if ( empty( $subscriptions ) || empty( $subscriptions->data ) ) {
|
4083 |
return false;
|
4084 |
}
|
4085 |
|
4086 |
+
//we really want to test against the order codes of all orders with the same subscription_transaction_id (customer id)
|
4087 |
+
$codes = $wpdb->get_col( "SELECT code FROM $wpdb->pmpro_membership_orders WHERE user_id = '" . esc_sql( $order->user_id ) . "' AND subscription_transaction_id = '" . esc_sql( $order->subscription_transaction_id ) . "' AND status NOT IN('refunded', 'review', 'token', 'error')" );
|
4088 |
+
|
4089 |
+
//find the one for this order
|
4090 |
+
foreach ( $subscriptions->data as $sub ) {
|
4091 |
+
if ( in_array( $sub->plan->id, $codes ) ) {
|
4092 |
+
return $sub;
|
4093 |
+
}
|
4094 |
+
}
|
4095 |
+
|
4096 |
+
//didn't find anything yet
|
4097 |
+
return false;
|
4098 |
}
|
4099 |
|
4100 |
+
/**
|
4101 |
+
* Create a new subscription with Stripe.
|
4102 |
+
*
|
4103 |
+
* This function is not run as a part of the PMPro Checkout Process.
|
4104 |
+
* See method create_setup_intent().
|
4105 |
+
*
|
4106 |
+
* @since 1.4
|
4107 |
+
* @deprecated 2.7.0. Use process_subscriptions() instead.
|
4108 |
+
*/
|
4109 |
+
public function subscribe( &$order, $checkout = true ) {
|
4110 |
+
_deprecated_function( __FUNCTION__, '2.7.0' );
|
4111 |
+
global $pmpro_currency;
|
4112 |
|
4113 |
+
//create a code for the order
|
4114 |
+
if ( empty( $order->code ) ) {
|
4115 |
+
$order->code = $order->getRandomCode();
|
4116 |
+
}
|
4117 |
|
4118 |
+
//filter order before subscription. use with care.
|
4119 |
+
$order = apply_filters( "pmpro_subscribe_order", $order, $this );
|
4120 |
+
|
4121 |
+
//figure out the user
|
4122 |
+
if ( ! empty( $order->user_id ) ) {
|
4123 |
+
$user_id = $order->user_id;
|
4124 |
+
} else {
|
4125 |
+
global $current_user;
|
4126 |
+
$user_id = $current_user->ID;
|
4127 |
}
|
4128 |
|
4129 |
+
//set up customer
|
|
|
|
|
4130 |
|
4131 |
+
$result = $this->update_customer_at_checkout( $order );
|
4132 |
+
if ( empty( $result ) ) {
|
4133 |
+
return false; //error retrieving customer
|
4134 |
+
}
|
4135 |
+
$order->stripe_customer = $result;
|
4136 |
|
4137 |
+
// set subscription id to custom id
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4138 |
|
4139 |
+
$order->subscription_transaction_id = $order->stripe_customer['id']; //transaction id is the customer id, we save it in user meta later too
|
4140 |
+
|
4141 |
+
//figure out the amounts
|
4142 |
+
$amount = $order->PaymentAmount;
|
4143 |
+
$amount_tax = $order->getTaxForPrice( $amount );
|
4144 |
+
$amount = pmpro_round_price( (float) $amount + (float) $amount_tax );
|
4145 |
+
|
4146 |
+
$trial_period_days = $this->calculate_trial_period_days( $order );
|
4147 |
+
|
4148 |
+
// Save $trial_period_days to order for now too.
|
4149 |
+
$order->TrialPeriodDays = $trial_period_days;
|
4150 |
|
4151 |
+
//create a plan
|
4152 |
try {
|
4153 |
+
$plan = array(
|
4154 |
+
"amount" => $this->convert_price_to_unit_amount( $amount ),
|
4155 |
+
"interval_count" => $order->BillingFrequency,
|
4156 |
+
"interval" => strtolower( $order->BillingPeriod ),
|
4157 |
+
"trial_period_days" => $trial_period_days,
|
4158 |
+
'product' => array( 'name' => $order->membership_name . " for order " . $order->code ),
|
4159 |
+
"currency" => strtolower( $pmpro_currency ),
|
4160 |
+
"id" => $order->code
|
4161 |
+
);
|
4162 |
+
$plan = self::add_application_fee_amount( $plan );
|
4163 |
+
$plan = Stripe_Plan::create( apply_filters( 'pmpro_stripe_create_plan_array', $plan ) );
|
4164 |
} catch ( \Throwable $e ) {
|
4165 |
+
$order->error = __( "Error creating plan with Stripe:", 'paid-memberships-pro' ) . $e->getMessage();
|
4166 |
+
$order->shorterror = $order->error;
|
4167 |
+
|
4168 |
return false;
|
4169 |
} catch ( \Exception $e ) {
|
4170 |
+
$order->error = __( "Error creating plan with Stripe:", 'paid-memberships-pro' ) . $e->getMessage();
|
4171 |
+
$order->shorterror = $order->error;
|
|
|
|
|
|
|
|
|
|
|
|
|
4172 |
|
4173 |
+
return false;
|
|
|
4174 |
}
|
4175 |
|
4176 |
+
// before subscribing, let's clear out the updates so we don't trigger any during sub
|
4177 |
if ( ! empty( $user_id ) ) {
|
4178 |
$old_user_updates = get_user_meta( $user_id, "pmpro_stripe_updates", true );
|
4179 |
update_user_meta( $user_id, "pmpro_stripe_updates", array() );
|
4180 |
}
|
4181 |
|
|
|
|
|
4182 |
|
4183 |
+
if ( empty( $order->subscription_transaction_id ) && ! empty( $order->stripe_customer['id'] ) ) {
|
4184 |
+
$order->subscription_transaction_id = $order->stripe_customer['id'];
|
4185 |
+
}
|
4186 |
+
|
4187 |
+
// subscribe to the plan
|
4188 |
+
try {
|
4189 |
+
$subscription = array( "plan" => $order->code );
|
4190 |
+
$result = $this->create_subscription( $order );
|
4191 |
+
} catch ( \Throwable $e ) {
|
4192 |
+
//try to delete the plan
|
4193 |
+
$plan->delete();
|
4194 |
|
4195 |
//give the user any old updates back
|
4196 |
if ( ! empty( $user_id ) ) {
|
4197 |
update_user_meta( $user_id, "pmpro_stripe_updates", $old_user_updates );
|
4198 |
}
|
4199 |
|
4200 |
+
//return error
|
4201 |
+
$order->error = __( "Error subscribing customer to plan with Stripe:", 'paid-memberships-pro' ) . $e->getMessage();
|
4202 |
+
$order->shorterror = $order->error;
|
4203 |
+
|
4204 |
return false;
|
4205 |
+
} catch ( \Exception $e ) {
|
4206 |
+
//try to delete the plan
|
4207 |
+
$plan->delete();
|
4208 |
|
4209 |
+
//give the user any old updates back
|
4210 |
+
if ( ! empty( $user_id ) ) {
|
4211 |
+
update_user_meta( $user_id, "pmpro_stripe_updates", $old_user_updates );
|
4212 |
+
}
|
4213 |
+
|
4214 |
+
//return error
|
4215 |
+
$order->error = __( "Error subscribing customer to plan with Stripe:", 'paid-memberships-pro' ) . $e->getMessage();
|
4216 |
+
$order->shorterror = $order->error;
|
4217 |
+
|
4218 |
+
return false;
|
4219 |
}
|
4220 |
|
4221 |
+
// delete the plan
|
4222 |
+
$plan = Stripe_Plan::retrieve( $order->code );
|
4223 |
+
$plan->delete();
|
4224 |
+
|
4225 |
+
//if we got this far, we're all good
|
4226 |
+
$order->status = "success";
|
4227 |
+
$order->subscription_transaction_id = $result['id'];
|
4228 |
+
|
4229 |
+
//save new updates if this is at checkout
|
4230 |
+
if ( $checkout ) {
|
4231 |
+
//empty out updates unless set above
|
4232 |
+
if ( empty( $new_user_updates ) ) {
|
4233 |
+
$new_user_updates = array();
|
4234 |
+
}
|
4235 |
+
|
4236 |
+
//update user meta
|
4237 |
+
if ( ! empty( $user_id ) ) {
|
4238 |
+
update_user_meta( $user_id, "pmpro_stripe_updates", $new_user_updates );
|
4239 |
+
} else {
|
4240 |
+
//need to remember the user updates to save later
|
4241 |
+
global $pmpro_stripe_updates;
|
4242 |
+
$pmpro_stripe_updates = $new_user_updates;
|
4243 |
function pmpro_user_register_stripe_updates( $user_id ) {
|
4244 |
global $pmpro_stripe_updates;
|
4245 |
+
update_user_meta( $user_id, "pmpro_stripe_updates", $pmpro_stripe_updates );
|
4246 |
}
|
4247 |
+
|
4248 |
+
add_action( "user_register", "pmpro_user_register_stripe_updates" );
|
4249 |
}
|
4250 |
+
} else {
|
4251 |
+
//give them their old updates back
|
4252 |
+
update_user_meta( $user_id, "pmpro_stripe_updates", $old_user_updates );
|
4253 |
}
|
4254 |
|
4255 |
return true;
|
4256 |
}
|
4257 |
|
4258 |
+
/**
|
4259 |
+
* Refund a payment or invoice
|
4260 |
+
*
|
4261 |
+
* @deprecated 2.7.0.
|
4262 |
+
*
|
4263 |
+
* @param object &$order Related PMPro order object.
|
4264 |
+
* @param string $transaction_id Payment or Invoice id to void.
|
4265 |
+
*
|
4266 |
+
* @return bool True or false if the void worked
|
4267 |
+
*/
|
4268 |
+
public function void( &$order, $transaction_id = null ) {
|
4269 |
+
_deprecated_function( __FUNCTION__, '2.7.0' );
|
4270 |
+
//stripe doesn't differentiate between voids and refunds, so let's just pass on to the refund function
|
4271 |
+
return $this->refund( $order, $transaction_id );
|
4272 |
+
}
|
4273 |
|
4274 |
+
/**
|
4275 |
+
* Refund a payment or invoice
|
4276 |
+
*
|
4277 |
+
* @deprecated 2.7.0.
|
4278 |
+
*
|
4279 |
+
* @param object &$order Related PMPro order object.
|
4280 |
+
* @param string $transaction_id Payment or invoice id to void.
|
4281 |
+
*
|
4282 |
+
* @return bool True or false if the refund worked.
|
4283 |
+
*/
|
4284 |
+
public function refund( &$order, $transaction_id = null ) {
|
4285 |
+
_deprecated_function( __FUNCTION__, '2.7.0' );
|
4286 |
+
//default to using the payment id from the order
|
4287 |
+
if ( empty( $transaction_id ) && ! empty( $order->payment_transaction_id ) ) {
|
4288 |
+
$transaction_id = $order->payment_transaction_id;
|
4289 |
}
|
4290 |
|
4291 |
+
//need a transaction id
|
4292 |
+
if ( empty( $transaction_id ) ) {
|
4293 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4294 |
}
|
4295 |
|
4296 |
+
//if an invoice ID is passed, get the charge/payment id
|
4297 |
+
if ( strpos( $transaction_id, "in_" ) !== false ) {
|
4298 |
+
$invoice = Stripe_Invoice::retrieve( $transaction_id );
|
|
|
|
|
|
|
|
|
|
|
4299 |
|
4300 |
+
if ( ! empty( $invoice ) && ! empty( $invoice->charge ) ) {
|
4301 |
+
$transaction_id = $invoice->charge;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4302 |
}
|
|
|
|
|
4303 |
}
|
4304 |
|
4305 |
+
//get the charge
|
|
|
|
|
|
|
4306 |
try {
|
4307 |
+
$charge = Stripe_Charge::retrieve( $transaction_id );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4308 |
} catch ( \Throwable $e ) {
|
4309 |
+
$charge = false;
|
|
|
|
|
4310 |
} catch ( \Exception $e ) {
|
4311 |
+
$charge = false;
|
|
|
|
|
4312 |
}
|
4313 |
|
4314 |
+
//can't find the charge?
|
4315 |
+
if ( empty( $charge ) ) {
|
4316 |
+
$order->status = "error";
|
4317 |
+
$order->errorcode = "";
|
4318 |
+
$order->error = "";
|
4319 |
+
$order->shorterror = "";
|
4320 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4321 |
return false;
|
4322 |
}
|
4323 |
|
4324 |
+
//attempt refund
|
|
|
|
|
|
|
|
|
4325 |
try {
|
4326 |
+
$refund = $charge->refund();
|
|
|
|
|
|
|
|
|
4327 |
} catch ( \Throwable $e ) {
|
4328 |
+
$order->errorcode = true;
|
4329 |
+
$order->error = __( "Error: ", 'paid-memberships-pro' ) . $e->getMessage();
|
4330 |
+
$order->shorterror = $order->error;
|
4331 |
|
4332 |
return false;
|
4333 |
} catch ( \Exception $e ) {
|
4334 |
+
$order->errorcode = true;
|
4335 |
+
$order->error = __( "Error: ", 'paid-memberships-pro' ) . $e->getMessage();
|
4336 |
+
$order->shorterror = $order->error;
|
4337 |
|
4338 |
return false;
|
4339 |
}
|
4340 |
|
4341 |
+
if ( $refund->status == "succeeded" ) {
|
4342 |
+
$order->status = "refunded";
|
4343 |
+
$order->saveOrder();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4344 |
|
4345 |
+
return true;
|
4346 |
+
} else {
|
4347 |
+
$order->status = "error";
|
4348 |
+
$order->errorcode = true;
|
4349 |
+
$order->error = sprintf( __( "Error: Unkown error while refunding charge #%s", 'paid-memberships-pro' ), $transaction_id );
|
4350 |
+
$order->shorterror = $order->error;
|
4351 |
|
|
|
4352 |
return false;
|
4353 |
}
|
|
|
|
|
4354 |
}
|
4355 |
|
4356 |
+
/**
|
4357 |
+
* @deprecated 2.7.0. Use get_payment_method() instead.
|
4358 |
+
*/
|
4359 |
+
public function set_payment_method( &$order, $force = false ) {
|
4360 |
+
_deprecated_function( __FUNCTION__, '2.7.0', 'get_payment_method' );
|
4361 |
+
if ( ! empty( $this->payment_method ) && ! $force ) {
|
4362 |
return true;
|
4363 |
}
|
4364 |
|
4365 |
+
$payment_method = $this->get_payment_method( $order );
|
4366 |
|
4367 |
+
if ( empty( $payment_method ) ) {
|
4368 |
return false;
|
4369 |
}
|
4370 |
|
4371 |
+
$this->payment_method = $payment_method;
|
4372 |
|
4373 |
return true;
|
4374 |
}
|
4375 |
|
4376 |
+
/**
|
4377 |
+
* @deprecated 2.7.0. Use get_customer_for_user() or update_customer_from_user().
|
4378 |
+
*/
|
4379 |
+
public function set_customer( &$order, $force = false ) {
|
4380 |
+
_deprecated_function( __FUNCTION__, '2.7.0', 'get_customer_for_user()' );
|
4381 |
+
if ( ! empty( $this->customer ) && ! $force ) {
|
4382 |
+
return true;
|
|
|
4383 |
}
|
4384 |
+
// Temporarily setting this, will be removed when this function is deprecated.
|
4385 |
+
$this->customer = $this->update_customer_at_checkout( $order );
|
4386 |
+
return $this->customer;
|
4387 |
}
|
4388 |
|
4389 |
+
/**
|
4390 |
+
* @deprecated 2.7.0. Use set_default_payment_method_for_customer().
|
4391 |
+
*/
|
4392 |
+
public function attach_payment_method_to_customer( &$order ) {
|
4393 |
+
_deprecated_function( __FUNCTION__, '2.7.0', 'set_default_payment_method_for_customer()' );
|
4394 |
+
$customer = $this->update_customer_at_checkout( $order );
|
4395 |
+
|
4396 |
+
if ( ! empty( $customer->invoice_settings->default_payment_method ) &&
|
4397 |
+
$customer->invoice_settings->default_payment_method === $this->payment_method->id ) {
|
4398 |
+
return true;
|
4399 |
+
}
|
4400 |
|
4401 |
try {
|
4402 |
+
$this->payment_method->attach( [ 'customer' => $customer->id ] );
|
4403 |
+
$customer->invoice_settings->default_payment_method = $this->payment_method->id;
|
4404 |
+
$customer->save();
|
|
|
|
|
|
|
4405 |
} catch ( Stripe\Error\Base $e ) {
|
4406 |
$order->error = $e->getMessage();
|
4407 |
return false;
|
4413 |
return false;
|
4414 |
}
|
4415 |
|
4416 |
+
return true;
|
4417 |
+
}
|
4418 |
+
|
4419 |
+
/**
|
4420 |
+
* @deprecated 2.7.0. Use get_payment_intent() instead.
|
4421 |
+
*/
|
4422 |
+
public function set_payment_intent( &$order, $force = false ) {
|
4423 |
+
_deprecated_function( __FUNCTION__, '2.7.0', 'get_payment_intent()' );
|
4424 |
+
if ( ! empty( $order->stripe_payment_intent ) && ! $force ) {
|
4425 |
+
return true;
|
4426 |
+
}
|
4427 |
+
|
4428 |
+
$payment_intent = $this->get_payment_intent( $order );
|
4429 |
|
4430 |
+
if ( empty( $payment_intent ) ) {
|
4431 |
return false;
|
4432 |
}
|
4433 |
|
4434 |
+
$this->payment_intent = $payment_intent;
|
4435 |
+
|
4436 |
return true;
|
4437 |
}
|
4438 |
|
4439 |
+
/**
|
4440 |
+
* Only called during subscription updates. Should be completely deprecated once that functionality is removed.
|
4441 |
+
*
|
4442 |
+
* @deprecated 2.7.0. Will only be deprecated once we are using Prices.
|
4443 |
+
*/
|
4444 |
+
public function create_plan( &$order ) {
|
4445 |
+
// _deprecated_function( __FUNCTION__, '2.7.0' );
|
4446 |
+
global $pmpro_currency;
|
4447 |
+
|
4448 |
+
//figure out the amounts
|
4449 |
+
$amount = $order->PaymentAmount;
|
4450 |
+
$amount_tax = $order->getTaxForPrice( $amount );
|
4451 |
+
$amount = pmpro_round_price( (float) $amount + (float) $amount_tax );
|
4452 |
|
4453 |
+
|
4454 |
+
$trial_period_days = $this->calculate_trial_period_days( $order );
|
4455 |
+
// Save $trial_period_days to order for now too.
|
4456 |
+
$order->TrialPeriodDays = $trial_period_days;
|
4457 |
|
4458 |
+
//create a plan
|
4459 |
+
try {
|
4460 |
+
$plan = array(
|
4461 |
+
"amount" => $this->convert_price_to_unit_amount( $amount ),
|
4462 |
+
"interval_count" => $order->BillingFrequency,
|
4463 |
+
"interval" => strtolower( $order->BillingPeriod ),
|
4464 |
+
"trial_period_days" => $trial_period_days,
|
4465 |
+
'product' => array( 'name' => $order->membership_name . " for order " . $order->code ),
|
4466 |
+
"currency" => strtolower( $pmpro_currency ),
|
4467 |
+
"id" => $order->code
|
4468 |
+
);
|
4469 |
+
$order->plan = Stripe_Plan::create( apply_filters( 'pmpro_stripe_create_plan_array', $plan ) );
|
4470 |
+
} catch ( Stripe\Error\Base $e ) {
|
4471 |
+
$order->error = $e->getMessage();
|
4472 |
|
4473 |
return false;
|
4474 |
+
} catch ( \Throwable $e ) {
|
4475 |
+
$order->error = $e->getMessage();
|
4476 |
|
4477 |
+
return false;
|
4478 |
+
} catch ( \Exception $e ) {
|
4479 |
+
$order->error = $e->getMessage();
|
4480 |
|
4481 |
+
return false;
|
|
|
|
|
4482 |
}
|
4483 |
|
4484 |
+
return $order->plan;
|
|
|
|
|
4485 |
}
|
4486 |
+
|
4487 |
|
4488 |
}
|
classes/gateways/class.pmprogateway_twocheckout.php
CHANGED
@@ -129,7 +129,7 @@
|
|
129 |
<label for="twocheckout_apipassword"><?php _e('API Password', 'paid-memberships-pro' );?>:</label>
|
130 |
</th>
|
131 |
<td>
|
132 |
-
<input type="text" id="twocheckout_apipassword" name="twocheckout_apipassword" value="<?php echo esc_attr($values['twocheckout_apipassword'])?>" class="regular-text code" />
|
133 |
<p class="description"><?php esc_html_e( 'Password for the API user created.', 'paid-memberships-pro' ); ?></p>
|
134 |
</td>
|
135 |
</tr>
|
@@ -217,7 +217,7 @@
|
|
217 |
*/
|
218 |
static function pmpro_checkout_before_change_membership_level($user_id, $morder)
|
219 |
{
|
220 |
-
global $wpdb
|
221 |
|
222 |
//if no order, no need to pay
|
223 |
if(empty($morder))
|
@@ -227,9 +227,11 @@
|
|
227 |
$morder->saveOrder();
|
228 |
|
229 |
//save discount code use
|
230 |
-
if(!empty($
|
|
|
|
|
231 |
$wpdb->query("INSERT INTO $wpdb->pmpro_discount_codes_uses (code_id, user_id, order_id, timestamp) VALUES('" . $discount_code_id . "', '" . $user_id . "', '" . $morder->id . "', now())");
|
232 |
-
|
233 |
do_action("pmpro_before_send_to_twocheckout", $user_id, $morder);
|
234 |
|
235 |
$morder->Gateway->sendToTwocheckout($morder);
|
129 |
<label for="twocheckout_apipassword"><?php _e('API Password', 'paid-memberships-pro' );?>:</label>
|
130 |
</th>
|
131 |
<td>
|
132 |
+
<input type="text" id="twocheckout_apipassword" name="twocheckout_apipassword" value="<?php echo esc_attr($values['twocheckout_apipassword'])?>" autocomplete="off" class="regular-text code pmpro-admin-secure-key" />
|
133 |
<p class="description"><?php esc_html_e( 'Password for the API user created.', 'paid-memberships-pro' ); ?></p>
|
134 |
</td>
|
135 |
</tr>
|
217 |
*/
|
218 |
static function pmpro_checkout_before_change_membership_level($user_id, $morder)
|
219 |
{
|
220 |
+
global $wpdb;
|
221 |
|
222 |
//if no order, no need to pay
|
223 |
if(empty($morder))
|
227 |
$morder->saveOrder();
|
228 |
|
229 |
//save discount code use
|
230 |
+
if(isset($morder->membership_level) && !empty($morder->membership_level->code_id))
|
231 |
+
{
|
232 |
+
$discount_code_id = (int)$morder->membership_level->code_id;
|
233 |
$wpdb->query("INSERT INTO $wpdb->pmpro_discount_codes_uses (code_id, user_id, order_id, timestamp) VALUES('" . $discount_code_id . "', '" . $user_id . "', '" . $morder->id . "', now())");
|
234 |
+
}
|
235 |
do_action("pmpro_before_send_to_twocheckout", $user_id, $morder);
|
236 |
|
237 |
$morder->Gateway->sendToTwocheckout($morder);
|
css/admin.css
CHANGED
@@ -1,485 +1,847 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
/* icon */
|
2 |
#wp-admin-bar-paid-memberships-pro .ab-item .ab-icon:before {
|
3 |
-
|
4 |
-
|
|
|
|
|
|
|
5 |
}
|
6 |
-
.pmpro_admin tr td .dashicons {padding-top: 5px; }
|
7 |
|
8 |
/* header/etc */
|
9 |
.pmpro_admin {
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
}
|
16 |
.pmpro_admin .pmpro_banner {
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
}
|
21 |
.pmpro_admin .pmpro_banner .pmpro_logo {
|
22 |
-
|
23 |
}
|
24 |
.pmpro_admin .pmpro_banner .pmpro_meta {
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
}
|
30 |
.pmpro_admin .pmpro_banner .pmpro_meta .pmpro_version {
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
}
|
36 |
.pmpro_admin .pmpro_banner .pmpro_meta a {
|
37 |
-
|
38 |
-
|
39 |
}
|
40 |
.pmpro_admin .pmpro_banner .pmpro_meta a.pmpro_license_tag {
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
}
|
45 |
.pmpro_admin .pmpro_banner .pmpro_meta a.pmpro_license_tag:before {
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
}
|
54 |
.pmpro_admin .pmpro_banner .pmpro_meta a.pmpro_license_tag.pmpro_license_tag-valid {
|
55 |
-
|
56 |
}
|
57 |
.pmpro_admin .pmpro_banner .pmpro_meta a.pmpro_license_tag.pmpro_license_tag-valid:before {
|
58 |
-
|
59 |
}
|
60 |
.pmpro_admin .pmpro_banner .pmpro_meta a.pmpro_license_tag.pmpro_license_tag-invalid {
|
61 |
-
|
62 |
}
|
63 |
.pmpro_admin .pmpro_banner .pmpro_meta a.pmpro_license_tag.pmpro_license_tag-invalid:before {
|
64 |
-
|
65 |
}
|
66 |
|
67 |
.pmpro_admin .pmpro_wp-notice-fix {
|
68 |
-
|
69 |
-
|
70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
}
|
72 |
-
.pmpro_admin .topborder {border-top: 1px solid #CCC; margin-top: 1em; padding-top: 1em; }
|
73 |
-
.pmpro_admin #editorcontainer #description {width: 100%; height: 180px; }
|
74 |
-
|
75 |
.pmpro_admin .pmpro_icon {
|
76 |
-
|
77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
}
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
|
86 |
-
/*
|
87 |
.pmpro_consent_log.pmpro_scrollable {
|
88 |
-
padding: .5em;
|
89 |
-
background: #FFF;
|
90 |
-
border: 1px solid #CCC;
|
91 |
-
height: 200px;
|
92 |
max-width: 800px;
|
93 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
}
|
95 |
|
96 |
/* levels */
|
97 |
-
.memberships_page_pmpro-membershiplevels .pmpro_admin #posts-filter p.search-box {
|
98 |
-
|
99 |
-
|
100 |
-
.memberships_page_pmpro-membershiplevels .pmpro_admin .
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
.memberships_page_pmpro-membershiplevels .pmpro_admin .membership-levels tr.ui-sortable-handle {
|
103 |
-
|
104 |
-
|
105 |
}
|
106 |
.memberships_page_pmpro-membershiplevels .pmpro_admin .membership-levels tr th:first-child:before,
|
107 |
.memberships_page_pmpro-membershiplevels .pmpro_admin .membership-levels tr td:first-child:before {
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
}
|
115 |
.memberships_page_pmpro-membershiplevels .pmpro_admin .membership-levels tr:hover td:first-child:before {
|
116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
}
|
118 |
-
.memberships_page_pmpro-membershiplevels .pmpro_admin tr.testclass {border: 3px solid #2997C8; background: #2997C8;}
|
119 |
-
.memberships_page_pmpro-membershiplevels .pmpro_admin tr.membership_categories ul {margin-left: 25px;}
|
120 |
|
121 |
/* payment settings */
|
122 |
.admin_page_pmpro-paymentsettings .form-table select {
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
}
|
125 |
|
126 |
/* advanced settings */
|
127 |
.admin_page_pmpro-advancedsettings .form-table select:not(.admin_page_pmpro-advancedsettings .form-table select#tospage) {
|
128 |
-
|
129 |
}
|
130 |
|
131 |
/* orders */
|
132 |
.memberships_page_pmpro-orders .pmpro_admin .nav-tab-wrapper {
|
133 |
-
|
134 |
}
|
135 |
|
136 |
/* members list */
|
137 |
.wp-list-table.members .column-ID {
|
138 |
-
|
139 |
}
|
140 |
-
.wp-list-table.members
|
141 |
-
|
142 |
}
|
143 |
|
144 |
/* settings */
|
145 |
tr.pmpro_settings_divider td {
|
146 |
-
|
147 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
}
|
149 |
|
150 |
/* messages */
|
151 |
.pmpro_admin .pmpro_message {
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
}
|
157 |
.pmpro_admin .pmpro_success {
|
158 |
-
|
159 |
-
|
160 |
}
|
161 |
.pmpro_admin .pmpro_error,
|
162 |
.pmpro_admin tr.pmpro_error td {
|
163 |
-
|
164 |
-
|
165 |
}
|
166 |
.pmpro_admin .pmpro_alert {
|
167 |
-
|
168 |
-
|
169 |
}
|
170 |
.pmpro_admin .pmpro_success a {
|
171 |
-
|
172 |
}
|
173 |
.pmpro_admin .pmpro_error a,
|
174 |
.pmpro_admin tr.pmpro_error td {
|
175 |
-
|
176 |
}
|
177 |
.pmpro_admin .pmpro_alert a {
|
178 |
-
|
179 |
}
|
180 |
|
181 |
/* notifications */
|
182 |
#pmpro_notifications .pmpro_notification {
|
183 |
-
|
184 |
}
|
185 |
#pmpro_notifications .pmpro_notification .pmpro_notification-general {
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
}
|
192 |
#pmpro_notifications .pmpro_notification .pmpro_notification-error {
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
}
|
199 |
#pmpro_notifications .pmpro_notification h3 {
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
}
|
204 |
#pmpro_notifications .pmpro_notification p {
|
205 |
-
|
206 |
}
|
207 |
#pmpro_notifications .pmpro_notification .button {
|
208 |
-
|
209 |
}
|
210 |
#pmpro_notifications .pmpro_notification .pmpro_notification-general h3 {
|
211 |
-
|
212 |
}
|
213 |
#pmpro_notifications .pmpro_notification .pmpro_notification-error h3 {
|
214 |
-
|
215 |
}
|
216 |
|
217 |
/* highlighted trs */
|
218 |
-
tr.pmpro_message {
|
219 |
-
|
220 |
-
|
221 |
-
tr.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
|
223 |
/* discount levels */
|
224 |
.pmpro_discount_levels .pmpro_discount_level {
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
}
|
229 |
.pmpro_discount_levels .pmpro_discount_level .pmpro_discount_levels_pricing {
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
}
|
235 |
|
236 |
/* pagination */
|
237 |
-
div.pmpro_pagination {
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
|
243 |
-
p.pmpro_meta_notice {
|
|
|
|
|
|
|
|
|
244 |
|
245 |
/* add ons */
|
246 |
.memberships_page_pmpro-addons .pmpro_admin .nav-tab-wrapper {
|
247 |
-
|
248 |
-
}
|
249 |
-
.pmpro_admin .widgets-holder-wrap {
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
.pmpro_admin .widgets-holder-wrap .widget
|
255 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
256 |
.pmpro_admin .widgets-holder-wrap .widget-title { }
|
257 |
.pmpro_admin .widgets-holder-wrap .widget-title h4 { }
|
258 |
-
.pmpro_admin .widgets-holder-wrap .widget-title .status-label {
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
|
266 |
-
|
267 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
268 |
}
|
269 |
-
|
270 |
@media (max-width:900px) {
|
271 |
-
.auto-fold .pmpro_admin .widgets-holder-wrap .widget {
|
272 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
}
|
274 |
|
275 |
/* license */
|
276 |
.memberships_page_pmpro-license h2 {
|
277 |
-
|
278 |
}
|
279 |
.memberships_page_pmpro-license .pmpro_icon {
|
280 |
-
|
281 |
}
|
282 |
|
283 |
/* misc */
|
284 |
-
.pmpro_lite {
|
285 |
-
|
286 |
-
|
287 |
-
.
|
288 |
-
|
289 |
-
|
290 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
291 |
|
292 |
/* reports */
|
293 |
.memberships_page_pmpro-reports .pmpro_admin .nav-tab-wrapper {
|
294 |
-
|
295 |
}
|
296 |
.pmpro_reports-holder { }
|
297 |
-
.pmpro_reports-holder .postbox h2 {
|
298 |
-
|
299 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
#pmpro_report_login .wp-list-table tbody td,
|
301 |
#pmpro_report_memberships .wp-list-table tbody tr.pmpro_report_tr td,
|
302 |
#pmpro_report_sales .wp-list-table tbody tr.pmpro_report_tr td {
|
303 |
-
|
304 |
-
|
305 |
}
|
306 |
#pmpro_report_sales .wp-list-table tbody td:last-child {
|
307 |
-
|
308 |
}
|
309 |
.pmpro_report-holder .wp-list-table tbody th button {
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
}
|
319 |
button.pmpro_report_th:before {
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
}
|
329 |
button.pmpro_report_th_opened:before {
|
330 |
-
|
331 |
}
|
332 |
button.pmpro_report_th_closed:before {
|
333 |
-
|
334 |
}
|
335 |
.pmpro_report-holder .wp-list-table tbody tr.pmpro_report_tr_sub:last-child th,
|
336 |
.pmpro_report-holder .wp-list-table tbody tr.pmpro_report_tr_sub:last-child td {
|
337 |
-
|
338 |
}
|
339 |
#pmpro_report_memberships .wp-list-table tbody:nth-child(odd) .pmpro_report_tr th,
|
340 |
#pmpro_report_memberships .wp-list-table tbody:nth-child(odd) .pmpro_report_tr td,
|
341 |
#pmpro_report_sales .wp-list-table tbody:nth-child(odd) .pmpro_report_tr th,
|
342 |
#pmpro_report_sales .wp-list-table tbody:nth-child(odd) .pmpro_report_tr td {
|
343 |
-
|
344 |
}
|
345 |
#pmpro_report_memberships .wp-list-table tbody:nth-child(even) .pmpro_report_tr th,
|
346 |
#pmpro_report_memberships .wp-list-table tbody:nth-child(even) .pmpro_report_tr td,
|
347 |
#pmpro_report_sales .wp-list-table tbody:nth-child(even) .pmpro_report_tr th,
|
348 |
#pmpro_report_sales .wp-list-table tbody:nth-child(even) .pmpro_report_tr td {
|
349 |
-
|
350 |
}
|
351 |
.pmpro_report-holder .pmpro_report-button {
|
352 |
-
|
353 |
}
|
354 |
|
355 |
/* Dashboard */
|
356 |
.pmpro_admin #pmpro_dashboard_welcome h3 {
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
}
|
361 |
.pmpro_admin #pmpro_dashboard_welcome .pmpro-dashboard-welcome-columns {
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
}
|
366 |
.pmpro_admin #pmpro_dashboard_welcome .button-action {
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
|
|
371 |
}
|
372 |
.pmpro_admin #pmpro_dashboard_welcome ul li {
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
}
|
377 |
.pmpro_admin #pmpro_dashboard_welcome ul li a .dashicons {
|
378 |
-
|
379 |
}
|
380 |
.pmpro_admin p.text-center {
|
381 |
-
|
382 |
}
|
383 |
|
384 |
/* new installation notices */
|
385 |
.pmpro-new-install {
|
386 |
-
|
387 |
-
|
388 |
}
|
389 |
.pmpro-new-install h2 {
|
390 |
-
|
391 |
-
|
392 |
}
|
393 |
.pmpro-new-install h2:before {
|
394 |
-
|
395 |
-
|
396 |
}
|
397 |
.memberships_page_pmpro-membershiplevels .pmpro-new-install h2:before {
|
398 |
-
|
399 |
}
|
400 |
.memberships_page_pmpro-pagesettings .pmpro-new-install h2:before {
|
401 |
-
|
402 |
}
|
403 |
.memberships_page_pmpro-discountcodes .pmpro-new-install h2:before {
|
404 |
-
|
405 |
}
|
406 |
#wpbody-content .pmpro-new-install .button-primary,
|
407 |
#wpbody-content .pmpro-new-install .button {
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
}
|
413 |
|
414 |
@media screen and (max-width: 782px) {
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
}
|
1 |
+
/* Metaboxes on Editor */
|
2 |
+
#poststuff #pmpro_page_meta.postbox .postbox-header {
|
3 |
+
border-bottom-width: 0;
|
4 |
+
}
|
5 |
+
#poststuff #pmpro_page_meta.postbox.closed .postbox-header {
|
6 |
+
border-bottom-width: 1px;
|
7 |
+
}
|
8 |
+
|
9 |
/* icon */
|
10 |
#wp-admin-bar-paid-memberships-pro .ab-item .ab-icon:before {
|
11 |
+
font-family: "dashicons";
|
12 |
+
content: "\f307";
|
13 |
+
}
|
14 |
+
.pmpro_admin tr td .dashicons {
|
15 |
+
padding-top: 5px;
|
16 |
}
|
|
|
17 |
|
18 |
/* header/etc */
|
19 |
.pmpro_admin {
|
20 |
+
background-image: url(../images/Paid-Memberships-Pro_watermark.png);
|
21 |
+
background-position: bottom right;
|
22 |
+
background-repeat: no-repeat;
|
23 |
+
background-size: 290px 40px;
|
24 |
+
padding: 1em 0 70px 0;
|
25 |
}
|
26 |
.pmpro_admin .pmpro_banner {
|
27 |
+
display: grid;
|
28 |
+
grid-template-areas: "logo meta";
|
29 |
+
grid-template-columns: 350px auto;
|
30 |
}
|
31 |
.pmpro_admin .pmpro_banner .pmpro_logo {
|
32 |
+
grid-area: logo;
|
33 |
}
|
34 |
.pmpro_admin .pmpro_banner .pmpro_meta {
|
35 |
+
align-self: center;
|
36 |
+
grid-area: meta;
|
37 |
+
font-size: 16px;
|
38 |
+
line-height: 1.5;
|
39 |
}
|
40 |
.pmpro_admin .pmpro_banner .pmpro_meta .pmpro_version {
|
41 |
+
color: #77a02e;
|
42 |
+
display: inline-block;
|
43 |
+
font-weight: bold;
|
44 |
+
padding: 5px 10px 5px 2px;
|
45 |
}
|
46 |
.pmpro_admin .pmpro_banner .pmpro_meta a {
|
47 |
+
border-left: 1px solid #CCC;
|
48 |
+
padding: 5px 10px;
|
49 |
}
|
50 |
.pmpro_admin .pmpro_banner .pmpro_meta a.pmpro_license_tag {
|
51 |
+
font-weight: bold;
|
52 |
+
padding: 5px 10px 5px 5px;
|
53 |
+
text-decoration: none;
|
54 |
}
|
55 |
.pmpro_admin .pmpro_banner .pmpro_meta a.pmpro_license_tag:before {
|
56 |
+
bottom: 7px;
|
57 |
+
display: inline-block;
|
58 |
+
font: 400 20px/1 dashicons;
|
59 |
+
left: 0;
|
60 |
+
position: relative;
|
61 |
+
text-decoration: none;
|
62 |
+
vertical-align: bottom;
|
63 |
}
|
64 |
.pmpro_admin .pmpro_banner .pmpro_meta a.pmpro_license_tag.pmpro_license_tag-valid {
|
65 |
+
color: rgb( 70, 180, 80 );
|
66 |
}
|
67 |
.pmpro_admin .pmpro_banner .pmpro_meta a.pmpro_license_tag.pmpro_license_tag-valid:before {
|
68 |
+
content: "\f147";
|
69 |
}
|
70 |
.pmpro_admin .pmpro_banner .pmpro_meta a.pmpro_license_tag.pmpro_license_tag-invalid {
|
71 |
+
color: #AAA;
|
72 |
}
|
73 |
.pmpro_admin .pmpro_banner .pmpro_meta a.pmpro_license_tag.pmpro_license_tag-invalid:before {
|
74 |
+
content: "\f335";
|
75 |
}
|
76 |
|
77 |
.pmpro_admin .pmpro_wp-notice-fix {
|
78 |
+
height: 1px;
|
79 |
+
line-height: 1px;
|
80 |
+
margin: 0;
|
81 |
+
}
|
82 |
+
.pmpro_admin .topborder {
|
83 |
+
border-top: 1px solid #CCC;
|
84 |
+
margin-top: 1em;
|
85 |
+
padding-top: 1em;
|
86 |
+
}
|
87 |
+
.pmpro_admin #editorcontainer #description {
|
88 |
+
width: 100%;
|
89 |
+
height: 180px;
|
90 |
}
|
|
|
|
|
|
|
91 |
.pmpro_admin .pmpro_icon {
|
92 |
+
max-width: 200px;
|
93 |
+
height: auto;
|
94 |
+
}
|
95 |
+
|
96 |
+
/* Scollable Boxes */
|
97 |
+
.pmpro_scrollable {
|
98 |
+
background-color: #FFFFFF;
|
99 |
+
height: 170px;
|
100 |
+
overflow: auto;
|
101 |
+
}
|
102 |
+
.pmpro_scrollable::-webkit-scrollbar {
|
103 |
+
background-color: #c3c4c7;
|
104 |
+
width: 8px;
|
105 |
+
height: 8px;
|
106 |
+
}
|
107 |
+
.pmpro_scrollable::-webkit-scrollbar-thumb {
|
108 |
+
background: #2c3338;
|
109 |
+
border-radius: 5px;
|
110 |
+
}
|
111 |
+
.pmpro_scrollable table.widefat {
|
112 |
+
border: none;
|
113 |
}
|
114 |
|
115 |
+
/**
|
116 |
+
* Checkbox Boxes
|
117 |
+
*
|
118 |
+
* Note: We will eventually remove the non-prefixed class names here. They are still in some Add Ons.
|
119 |
+
*
|
120 |
+
*/
|
121 |
+
.pmpro_checkbox_box,
|
122 |
+
.checkbox_box {
|
123 |
+
background-color: #FFFFFF;
|
124 |
+
border: 1px solid #c3c4c7;
|
125 |
+
max-width: 300px;
|
126 |
+
}
|
127 |
+
.pmpro_checkbox_box div,
|
128 |
+
.checkbox_box div {
|
129 |
+
border-bottom: 1px solid #CCC;
|
130 |
+
padding: 3px;
|
131 |
+
}
|
132 |
+
.pmpro_checkbox_box div:last-child,
|
133 |
+
.checkbox_box div:last-child {
|
134 |
+
border-bottom: none;
|
135 |
+
}
|
136 |
+
.pmpro_checkbox_box .pmpro_clickable,
|
137 |
+
.checkbox_box .clickable {
|
138 |
+
cursor: pointer;
|
139 |
+
}
|
140 |
+
.pmpro_checkbox_box .pmpro_clickable:hover,
|
141 |
+
.checkbox_box .clickable:hover {
|
142 |
+
background: #FFC;
|
143 |
+
}
|
144 |
+
.pmpro_checkbox_box .pmpro_clickable {
|
145 |
+
align-items: center;
|
146 |
+
display: flex;
|
147 |
+
}
|
148 |
+
.pmpro_checkbox_box .pmpro_clickable label {
|
149 |
+
flex-grow: 1;
|
150 |
+
}
|
151 |
+
.pmpro_checkbox_box .pmpro_clickable input[type=checkbox] {
|
152 |
+
margin-top: 0;
|
153 |
+
}
|
154 |
|
155 |
+
/* Consent Log */
|
156 |
.pmpro_consent_log.pmpro_scrollable {
|
|
|
|
|
|
|
|
|
157 |
max-width: 800px;
|
158 |
+
border: 1px solid #c3c4c7;
|
159 |
+
padding: 0;
|
160 |
+
}
|
161 |
+
.pmpro_consent_log li {
|
162 |
+
font-size: 13px;
|
163 |
+
line-height: 1.5em;
|
164 |
+
margin: 0;
|
165 |
+
}
|
166 |
+
.pmpro_consent_log.pmpro_scrollable li {
|
167 |
+
padding: 8px 10px;
|
168 |
+
}
|
169 |
+
.pmpro_consent_log.pmpro_scrollable li:nth-child(odd) {
|
170 |
+
background-color: #f6f7f7;
|
171 |
}
|
172 |
|
173 |
/* levels */
|
174 |
+
.memberships_page_pmpro-membershiplevels .pmpro_admin #posts-filter p.search-box {
|
175 |
+
margin: 2em 0 1em 0;
|
176 |
+
}
|
177 |
+
.memberships_page_pmpro-membershiplevels .pmpro_admin tr.pmpro_gray td {
|
178 |
+
color: #AAA;
|
179 |
+
}
|
180 |
+
.memberships_page_pmpro-membershiplevels .pmpro_admin tr td.level_name span.level-name a {
|
181 |
+
font-size: 115%;
|
182 |
+
font-weight: bold;
|
183 |
+
}
|
184 |
+
.memberships_page_pmpro-membershiplevels .pmpro_admin .membership-levels tr {
|
185 |
+
background: #fff;
|
186 |
+
}
|
187 |
+
.memberships_page_pmpro-membershiplevels .pmpro_admin .membership-levels tr.alternate {
|
188 |
+
background: #f1f1f1;
|
189 |
+
}
|
190 |
.memberships_page_pmpro-membershiplevels .pmpro_admin .membership-levels tr.ui-sortable-handle {
|
191 |
+
border: 1px solid #2997C8;
|
192 |
+
cursor: move;
|
193 |
}
|
194 |
.memberships_page_pmpro-membershiplevels .pmpro_admin .membership-levels tr th:first-child:before,
|
195 |
.memberships_page_pmpro-membershiplevels .pmpro_admin .membership-levels tr td:first-child:before {
|
196 |
+
color: #CCC;
|
197 |
+
content: "\f333";
|
198 |
+
display: inline-block;
|
199 |
+
font: 400 16px/1 dashicons;
|
200 |
+
opacity: 0;
|
201 |
+
width: 25px;
|
202 |
}
|
203 |
.memberships_page_pmpro-membershiplevels .pmpro_admin .membership-levels tr:hover td:first-child:before {
|
204 |
+
opacity: 1;
|
205 |
+
}
|
206 |
+
.memberships_page_pmpro-membershiplevels .pmpro_admin tr.testclass {
|
207 |
+
border: 3px solid #2997C8;
|
208 |
+
background: #2997C8;
|
209 |
+
}
|
210 |
+
.memberships_page_pmpro-membershiplevels .pmpro_admin tr.membership_categories ul {
|
211 |
+
margin-left: 25px;
|
212 |
}
|
|
|
|
|
213 |
|
214 |
/* payment settings */
|
215 |
.admin_page_pmpro-paymentsettings .form-table select {
|
216 |
+
max-width: none;
|
217 |
+
}
|
218 |
+
|
219 |
+
.admin_page_pmpro-paymentsettings span.pmpro_gateway-mode {
|
220 |
+
border: 1px solid;
|
221 |
+
border-radius: 3px;
|
222 |
+
display: inline-block;
|
223 |
+
font-size: 75%;
|
224 |
+
margin-left: 5px;
|
225 |
+
padding: 3px 5px;
|
226 |
+
}
|
227 |
+
|
228 |
+
.admin_page_pmpro-paymentsettings span.pmpro_gateway-mode-live {
|
229 |
+
background-color: #edfaef;
|
230 |
+
border-color: #00a32a;
|
231 |
+
color: #00a32a;
|
232 |
+
}
|
233 |
+
|
234 |
+
.admin_page_pmpro-paymentsettings span.pmpro_gateway-mode-live.pmpro_gateway-mode-not-connected {
|
235 |
+
background-color: #fcf0f1;
|
236 |
+
border-color: #d63638;
|
237 |
+
color: #d63638;
|
238 |
+
}
|
239 |
+
|
240 |
+
.admin_page_pmpro-paymentsettings span.pmpro_gateway-mode-test {
|
241 |
+
background-color: #fcf9e8;
|
242 |
+
border-color: #dba617;
|
243 |
+
color: #dba617;
|
244 |
+
}
|
245 |
+
|
246 |
+
.admin_page_pmpro-paymentsettings span.pmpro_gateway-mode-test.pmpro_gateway-mode-not-connected {
|
247 |
+
background-color: #f9f3d3;
|
248 |
+
border-color: #d59a13;
|
249 |
+
color: #d59a13;
|
250 |
+
}
|
251 |
+
|
252 |
+
.admin_page_pmpro-paymentsettings .pmpro-stripe-connect {
|
253 |
+
display: inline-block;
|
254 |
+
margin-bottom: 1px;
|
255 |
+
|
256 |
+
background-image: -webkit-linear-gradient(#28A0E5, #015E94);
|
257 |
+
background-image: -moz-linear-gradient(#28A0E5, #015E94);
|
258 |
+
background-image: -ms-linear-gradient(#28A0E5, #015E94);
|
259 |
+
background-image: linear-gradient(#28A0E5, #015E94);
|
260 |
+
|
261 |
+
-webkit-font-smoothing: antialiased;
|
262 |
+
border: 0;
|
263 |
+
padding: 1px;
|
264 |
+
height: 30px;
|
265 |
+
text-decoration: none;
|
266 |
+
|
267 |
+
-moz-border-radius: 4px;
|
268 |
+
-webkit-border-radius: 4px;
|
269 |
+
border-radius: 4px;
|
270 |
+
|
271 |
+
-moz-box-shadow: 0 1px 0 rgba(0,0,0,0.2);
|
272 |
+
-webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
|
273 |
+
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
|
274 |
+
|
275 |
+
-webkit-box-sizing: initial;
|
276 |
+
-moz-box-sizing: initial;
|
277 |
+
box-sizing: initial;
|
278 |
+
|
279 |
+
cursor: pointer;
|
280 |
+
|
281 |
+
-moz-user-select: none;
|
282 |
+
-webkit-user-select: none;
|
283 |
+
-ms-user-select: none;
|
284 |
+
user-select: none;
|
285 |
+
}
|
286 |
+
|
287 |
+
.admin_page_pmpro-paymentsettings .pmpro-stripe-connect span {
|
288 |
+
display: block;
|
289 |
+
position: relative;
|
290 |
+
padding: 0 12px 0 44px;
|
291 |
+
height: 30px;
|
292 |
+
|
293 |
+
background: #1275FF;
|
294 |
+
background-image: -webkit-linear-gradient(#7DC5EE, #008CDD 85%, #30A2E4);
|
295 |
+
background-image: -moz-linear-gradient(#7DC5EE, #008CDD 85%, #30A2E4);
|
296 |
+
background-image: -ms-linear-gradient(#7DC5EE, #008CDD 85%, #30A2E4);
|
297 |
+
background-image: linear-gradient(#7DC5EE, #008CDD 85%, #30A2E4);
|
298 |
+
|
299 |
+
font-size: 14px;
|
300 |
+
line-height: 30px;
|
301 |
+
color: white;
|
302 |
+
font-weight: bold;
|
303 |
+
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
304 |
+
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
|
305 |
+
|
306 |
+
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.25);
|
307 |
+
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
|
308 |
+
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
|
309 |
+
|
310 |
+
-moz-border-radius: 3px;
|
311 |
+
-webkit-border-radius: 3px;
|
312 |
+
border-radius: 3px;
|
313 |
+
}
|
314 |
+
|
315 |
+
.admin_page_pmpro-paymentsettings .pmpro-stripe-connect span:before {
|
316 |
+
content: '';
|
317 |
+
display: block;
|
318 |
+
position: absolute;
|
319 |
+
left: 11px;
|
320 |
+
top: 50%;
|
321 |
+
width: 23px;
|
322 |
+
height: 24px;
|
323 |
+
margin-top: -12px;
|
324 |
+
background-repeat: no-repeat;
|
325 |
+
background-size: 23px 24px;
|
326 |
+
}
|
327 |
+
|
328 |
+
.admin_page_pmpro-paymentsettings .pmpro-stripe-connect:active {
|
329 |
+
background: #005D93;
|
330 |
+
}
|
331 |
+
|
332 |
+
.admin_page_pmpro-paymentsettings .pmpro-stripe-connect:active span {
|
333 |
+
color: #EEE;
|
334 |
+
|
335 |
+
background: #008CDD;
|
336 |
+
background-image: -webkit-linear-gradient(#008CDD, #008CDD 85%, #239ADF);
|
337 |
+
background-image: -moz-linear-gradient(#008CDD, #008CDD 85%, #239ADF);
|
338 |
+
background-image: -ms-linear-gradient(#008CDD, #008CDD 85%, #239ADF);
|
339 |
+
background-image: linear-gradient(#008CDD, #008CDD 85%, #239ADF);
|
340 |
+
|
341 |
+
-moz-box-shadow: inset 0 1px 0 rgba(0,0,0,0.1);
|
342 |
+
-webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1);
|
343 |
+
box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1);
|
344 |
+
}
|
345 |
+
|
346 |
+
.admin_page_pmpro-paymentsettings .pmpro-stripe-connect span:before {
|
347 |
+
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAYCAYAAAARfGZ1AAAKRGlDQ1BJQ0MgUHJvZmlsZQAASA2dlndUFNcXx9/MbC+0XZYiZem9twWkLr1IlSYKy+4CS1nWZRewN0QFIoqICFYkKGLAaCgSK6JYCAgW7AEJIkoMRhEVlczGHPX3Oyf5/U7eH3c+8333nnfn3vvOGQAoASECYQ6sAEC2UCKO9PdmxsUnMPG9AAZEgAM2AHC4uaLQKL9ogK5AXzYzF3WS8V8LAuD1LYBaAK5bBIQzmX/p/+9DkSsSSwCAwtEAOx4/l4tyIcpZ+RKRTJ9EmZ6SKWMYI2MxmiDKqjJO+8Tmf/p8Yk8Z87KFPNRHlrOIl82TcRfKG/OkfJSREJSL8gT8fJRvoKyfJc0WoPwGZXo2n5MLAIYi0yV8bjrK1ihTxNGRbJTnAkCgpH3FKV+xhF+A5gkAO0e0RCxIS5cwjbkmTBtnZxYzgJ+fxZdILMI53EyOmMdk52SLOMIlAHz6ZlkUUJLVlokW2dHG2dHRwtYSLf/n9Y+bn73+GWS9/eTxMuLPnkGMni/al9gvWk4tAKwptDZbvmgpOwFoWw+A6t0vmv4+AOQLAWjt++p7GLJ5SZdIRC5WVvn5+ZYCPtdSVtDP6386fPb8e/jqPEvZeZ9rx/Thp3KkWRKmrKjcnKwcqZiZK+Jw+UyL/x7ifx34VVpf5WEeyU/li/lC9KgYdMoEwjS03UKeQCLIETIFwr/r8L8M+yoHGX6aaxRodR8BPckSKPTRAfJrD8DQyABJ3IPuQJ/7FkKMAbKbF6s99mnuUUb3/7T/YeAy9BXOFaQxZTI7MprJlYrzZIzeCZnBAhKQB3SgBrSAHjAGFsAWOAFX4Al8QRAIA9EgHiwCXJAOsoEY5IPlYA0oAiVgC9gOqsFeUAcaQBM4BtrASXAOXARXwTVwE9wDQ2AUPAOT4DWYgSAID1EhGqQGaUMGkBlkC7Egd8gXCoEioXgoGUqDhJAUWg6tg0qgcqga2g81QN9DJ6Bz0GWoH7oDDUPj0O/QOxiBKTAd1oQNYSuYBXvBwXA0vBBOgxfDS+FCeDNcBdfCR+BW+Bx8Fb4JD8HP4CkEIGSEgeggFggLYSNhSAKSioiRlUgxUonUIk1IB9KNXEeGkAnkLQaHoWGYGAuMKyYAMx/DxSzGrMSUYqoxhzCtmC7MdcwwZhLzEUvFamDNsC7YQGwcNg2bjy3CVmLrsS3YC9ib2FHsaxwOx8AZ4ZxwAbh4XAZuGa4UtxvXjDuL68eN4KbweLwa3gzvhg/Dc/ASfBF+J/4I/gx+AD+Kf0MgE7QJtgQ/QgJBSFhLqCQcJpwmDBDGCDNEBaIB0YUYRuQRlxDLiHXEDmIfcZQ4Q1IkGZHcSNGkDNIaUhWpiXSBdJ/0kkwm65KdyRFkAXk1uYp8lHyJPEx+S1GimFLYlESKlLKZcpBylnKH8pJKpRpSPakJVAl1M7WBep76kPpGjiZnKRcox5NbJVcj1yo3IPdcnihvIO8lv0h+qXyl/HH5PvkJBaKCoQJbgaOwUqFG4YTCoMKUIk3RRjFMMVuxVPGw4mXFJ0p4JUMlXyWeUqHSAaXzSiM0hKZHY9O4tHW0OtoF2igdRzeiB9Iz6CX07+i99EllJWV75RjlAuUa5VPKQwyEYcgIZGQxyhjHGLcY71Q0VbxU+CqbVJpUBlSmVeeoeqryVYtVm1Vvqr5TY6r5qmWqbVVrU3ugjlE3VY9Qz1ffo35BfWIOfY7rHO6c4jnH5tzVgDVMNSI1lmkc0OjRmNLU0vTXFGnu1DyvOaHF0PLUytCq0DqtNa5N03bXFmhXaJ/RfspUZnoxs5hVzC7mpI6GToCOVGe/Tq/OjK6R7nzdtbrNug/0SHosvVS9Cr1OvUl9bf1Q/eX6jfp3DYgGLIN0gx0G3QbThkaGsYYbDNsMnxipGgUaLTVqNLpvTDX2MF5sXGt8wwRnwjLJNNltcs0UNnUwTTetMe0zg80czQRmu836zbHmzuZC81rzQQuKhZdFnkWjxbAlwzLEcq1lm+VzK32rBKutVt1WH60drLOs66zv2SjZBNmstemw+d3W1JZrW2N7w45q52e3yq7d7oW9mT3ffo/9bQeaQ6jDBodOhw+OTo5ixybHcSd9p2SnXU6DLDornFXKuuSMdfZ2XuV80vmti6OLxOWYy2+uFq6Zroddn8w1msufWzd3xE3XjeO2323Ineme7L7PfchDx4PjUevxyFPPk+dZ7znmZeKV4XXE67m3tbfYu8V7mu3CXsE+64P4+PsU+/T6KvnO9632fein65fm1+g36e/gv8z/bAA2IDhga8BgoGYgN7AhcDLIKWhFUFcwJTgquDr4UYhpiDikIxQODQrdFnp/nsE84by2MBAWGLYt7EG4Ufji8B8jcBHhETURjyNtIpdHdkfRopKiDke9jvaOLou+N994vnR+Z4x8TGJMQ8x0rE9seexQnFXcirir8erxgvj2BHxCTEJ9wtQC3wXbF4wmOiQWJd5aaLSwYOHlReqLshadSpJP4iQdT8YmxyYfTn7PCePUcqZSAlN2pUxy2dwd3Gc8T14Fb5zvxi/nj6W6pZanPklzS9uWNp7ukV6ZPiFgC6oFLzICMvZmTGeGZR7MnM2KzWrOJmQnZ58QKgkzhV05WjkFOf0iM1GRaGixy+LtiyfFweL6XCh3YW67hI7+TPVIjaXrpcN57nk1eW/yY/KPFygWCAt6lpgu2bRkbKnf0m+XYZZxl3Uu11m+ZvnwCq8V+1dCK1NWdq7SW1W4anS1/+pDa0hrMtf8tNZ6bfnaV+ti13UUahauLhxZ77++sUiuSFw0uMF1w96NmI2Cjb2b7Dbt3PSxmFd8pcS6pLLkfSm39Mo3Nt9UfTO7OXVzb5lj2Z4tuC3CLbe2emw9VK5YvrR8ZFvottYKZkVxxavtSdsvV9pX7t1B2iHdMVQVUtW+U3/nlp3vq9Orb9Z41zTv0ti1adf0bt7ugT2ee5r2au4t2ftun2Df7f3++1trDWsrD+AO5B14XBdT1/0t69uGevX6kvoPB4UHhw5FHupqcGpoOKxxuKwRbpQ2jh9JPHLtO5/v2pssmvY3M5pLjoKj0qNPv0/+/tax4GOdx1nHm34w+GFXC62luBVqXdI62ZbeNtQe395/IuhEZ4drR8uPlj8ePKlzsuaU8qmy06TThadnzyw9M3VWdHbiXNq5kc6kznvn487f6Iro6r0QfOHSRb+L57u9us9ccrt08rLL5RNXWFfarjpebe1x6Gn5yeGnll7H3tY+p772a87XOvrn9p8e8Bg4d93n+sUbgTeu3px3s//W/Fu3BxMHh27zbj+5k3Xnxd28uzP3Vt/H3i9+oPCg8qHGw9qfTX5uHnIcOjXsM9zzKOrRvRHuyLNfcn95P1r4mPq4ckx7rOGJ7ZOT437j154ueDr6TPRsZqLoV8Vfdz03fv7Db56/9UzGTY6+EL+Y/b30pdrLg6/sX3VOhU89fJ39ema6+I3am0NvWW+738W+G5vJf49/X/XB5EPHx+CP92ezZ2f/AAOY8/wRDtFgAAADQklEQVRIDbWVaUiUQRjHZ96dXY/d1fYQj1U03dJSw9YkFgy6DIkILRArQSSC7PjQjQQqVH7oQ0GHQUWgpQhKHzoNSqiUwpXcsrwIjzVtPVrzbPV9Z6bZhYV3N3WXYAeGmWeeZ37z8J95GEgpBf5oeXn1Es4fYAdzPDlM6je4RBYhR+LMU89UxiCBGiCgkUwsBYSA+SlPKLQBQAYEAZm+3j42K96z3NyOF7VOeMrp62opRcacjPW5+43rDTpNSKQ8QKZAEg7xmPCTs/O27uGJgXuNbW0pxyvLfTmAEBzthEsFZLxRvPdi5rpYo2cmUiQJDA4IVeo0obGdlvGfXUPj0Sym2zPuHxvzcWjDyVupJ/YYizKTGNjLw/HiduNTAqIRIUJ6Vpp+ky8bCSFgwQ2xgkGxFi1ioNWEBGuJB31gbLIv/2pd7SpFoGxtpCYkLSEq4ptlzIYFO7tc7w0TKkeEYg5ADnrWkkYhD8s26GPq3nW0WKxTptftPYBI4Mj3O2fHvKNZBMVSDmMwarXNjDkSF3d5kExZeiCr8M2VI+VFu9IvsPcYtzAvkfoEZkEEE45jMppq3ppbCNPFIY1nD1cpo07lbMmvOXeoDCF8BLKy9uUAAjDkBh+c6bz78mNtVVP7MwET7JBnqb4xXpdWVpC1OVzWn+ELHLCsneX/s7rkRWl1463cy1U3WroG21jhCGKJXPOtKQnpAuENvsAppgDB3TcDVIrpDHbK5Kd+y7W8iodNybHh22rOHyxUK+UaMYjZaoyp25rYL54TSihSKmwZ14v3lc3ZFxdbeywjn/tGJnkmzrydX1ApxOEACKymmXLYfXVpi1JMEOGxPi1ep18doY4r2J7uFumQQ9yGf01bMcZW8dpyc0oIjxxpuC5wuUDX+ovWrnYeg3aXvdLIqnmOvXPsfH6uA5YbTb1DX8ofvTLzTy6ZV4K6fAw+gXiATfdffmjeaUgc1UdpdWplsCooQBrEnqUw82dhdnjit/Vxc4f59tP3DRjzJvYteqrl4rmNlJIfrOwpgNklesDRNQBCHYtQAQqD2CgACNjHAJnG1EyfV/S67fZiJB5t2OGEe4n7L3fS4fpEv/2hUEATfoPbuam5v8N7nps70YTbAAAAAElFTkSuQmCC");
|
348 |
+
}
|
349 |
+
|
350 |
+
/* Retina support */
|
351 |
+
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
352 |
+
only screen and (min--moz-device-pixel-ratio: 1.5),
|
353 |
+
only screen and (min-device-pixel-ratio: 1.5) {
|
354 |
+
.admin_page_pmpro-paymentsettings .pmpro-stripe-connect span:before {
|
355 |
+
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAwCAYAAABuZUjcAAAKRGlDQ1BJQ0MgUHJvZmlsZQAASA2dlndUFNcXx9/MbC+0XZYiZem9twWkLr1IlSYKy+4CS1nWZRewN0QFIoqICFYkKGLAaCgSK6JYCAgW7AEJIkoMRhEVlczGHPX3Oyf5/U7eH3c+8333nnfn3vvOGQAoASECYQ6sAEC2UCKO9PdmxsUnMPG9AAZEgAM2AHC4uaLQKL9ogK5AXzYzF3WS8V8LAuD1LYBaAK5bBIQzmX/p/+9DkSsSSwCAwtEAOx4/l4tyIcpZ+RKRTJ9EmZ6SKWMYI2MxmiDKqjJO+8Tmf/p8Yk8Z87KFPNRHlrOIl82TcRfKG/OkfJSREJSL8gT8fJRvoKyfJc0WoPwGZXo2n5MLAIYi0yV8bjrK1ihTxNGRbJTnAkCgpH3FKV+xhF+A5gkAO0e0RCxIS5cwjbkmTBtnZxYzgJ+fxZdILMI53EyOmMdk52SLOMIlAHz6ZlkUUJLVlokW2dHG2dHRwtYSLf/n9Y+bn73+GWS9/eTxMuLPnkGMni/al9gvWk4tAKwptDZbvmgpOwFoWw+A6t0vmv4+AOQLAWjt++p7GLJ5SZdIRC5WVvn5+ZYCPtdSVtDP6386fPb8e/jqPEvZeZ9rx/Thp3KkWRKmrKjcnKwcqZiZK+Jw+UyL/x7ifx34VVpf5WEeyU/li/lC9KgYdMoEwjS03UKeQCLIETIFwr/r8L8M+yoHGX6aaxRodR8BPckSKPTRAfJrD8DQyABJ3IPuQJ/7FkKMAbKbF6s99mnuUUb3/7T/YeAy9BXOFaQxZTI7MprJlYrzZIzeCZnBAhKQB3SgBrSAHjAGFsAWOAFX4Al8QRAIA9EgHiwCXJAOsoEY5IPlYA0oAiVgC9gOqsFeUAcaQBM4BtrASXAOXARXwTVwE9wDQ2AUPAOT4DWYgSAID1EhGqQGaUMGkBlkC7Egd8gXCoEioXgoGUqDhJAUWg6tg0qgcqga2g81QN9DJ6Bz0GWoH7oDDUPj0O/QOxiBKTAd1oQNYSuYBXvBwXA0vBBOgxfDS+FCeDNcBdfCR+BW+Bx8Fb4JD8HP4CkEIGSEgeggFggLYSNhSAKSioiRlUgxUonUIk1IB9KNXEeGkAnkLQaHoWGYGAuMKyYAMx/DxSzGrMSUYqoxhzCtmC7MdcwwZhLzEUvFamDNsC7YQGwcNg2bjy3CVmLrsS3YC9ib2FHsaxwOx8AZ4ZxwAbh4XAZuGa4UtxvXjDuL68eN4KbweLwa3gzvhg/Dc/ASfBF+J/4I/gx+AD+Kf0MgE7QJtgQ/QgJBSFhLqCQcJpwmDBDGCDNEBaIB0YUYRuQRlxDLiHXEDmIfcZQ4Q1IkGZHcSNGkDNIaUhWpiXSBdJ/0kkwm65KdyRFkAXk1uYp8lHyJPEx+S1GimFLYlESKlLKZcpBylnKH8pJKpRpSPakJVAl1M7WBep76kPpGjiZnKRcox5NbJVcj1yo3IPdcnihvIO8lv0h+qXyl/HH5PvkJBaKCoQJbgaOwUqFG4YTCoMKUIk3RRjFMMVuxVPGw4mXFJ0p4JUMlXyWeUqHSAaXzSiM0hKZHY9O4tHW0OtoF2igdRzeiB9Iz6CX07+i99EllJWV75RjlAuUa5VPKQwyEYcgIZGQxyhjHGLcY71Q0VbxU+CqbVJpUBlSmVeeoeqryVYtVm1Vvqr5TY6r5qmWqbVVrU3ugjlE3VY9Qz1ffo35BfWIOfY7rHO6c4jnH5tzVgDVMNSI1lmkc0OjRmNLU0vTXFGnu1DyvOaHF0PLUytCq0DqtNa5N03bXFmhXaJ/RfspUZnoxs5hVzC7mpI6GToCOVGe/Tq/OjK6R7nzdtbrNug/0SHosvVS9Cr1OvUl9bf1Q/eX6jfp3DYgGLIN0gx0G3QbThkaGsYYbDNsMnxipGgUaLTVqNLpvTDX2MF5sXGt8wwRnwjLJNNltcs0UNnUwTTetMe0zg80czQRmu836zbHmzuZC81rzQQuKhZdFnkWjxbAlwzLEcq1lm+VzK32rBKutVt1WH60drLOs66zv2SjZBNmstemw+d3W1JZrW2N7w45q52e3yq7d7oW9mT3ffo/9bQeaQ6jDBodOhw+OTo5ixybHcSd9p2SnXU6DLDornFXKuuSMdfZ2XuV80vmti6OLxOWYy2+uFq6Zroddn8w1msufWzd3xE3XjeO2323Ineme7L7PfchDx4PjUevxyFPPk+dZ7znmZeKV4XXE67m3tbfYu8V7mu3CXsE+64P4+PsU+/T6KvnO9632fein65fm1+g36e/gv8z/bAA2IDhga8BgoGYgN7AhcDLIKWhFUFcwJTgquDr4UYhpiDikIxQODQrdFnp/nsE84by2MBAWGLYt7EG4Ufji8B8jcBHhETURjyNtIpdHdkfRopKiDke9jvaOLou+N994vnR+Z4x8TGJMQ8x0rE9seexQnFXcirir8erxgvj2BHxCTEJ9wtQC3wXbF4wmOiQWJd5aaLSwYOHlReqLshadSpJP4iQdT8YmxyYfTn7PCePUcqZSAlN2pUxy2dwd3Gc8T14Fb5zvxi/nj6W6pZanPklzS9uWNp7ukV6ZPiFgC6oFLzICMvZmTGeGZR7MnM2KzWrOJmQnZ58QKgkzhV05WjkFOf0iM1GRaGixy+LtiyfFweL6XCh3YW67hI7+TPVIjaXrpcN57nk1eW/yY/KPFygWCAt6lpgu2bRkbKnf0m+XYZZxl3Uu11m+ZvnwCq8V+1dCK1NWdq7SW1W4anS1/+pDa0hrMtf8tNZ6bfnaV+ti13UUahauLhxZ77++sUiuSFw0uMF1w96NmI2Cjb2b7Dbt3PSxmFd8pcS6pLLkfSm39Mo3Nt9UfTO7OXVzb5lj2Z4tuC3CLbe2emw9VK5YvrR8ZFvottYKZkVxxavtSdsvV9pX7t1B2iHdMVQVUtW+U3/nlp3vq9Orb9Z41zTv0ti1adf0bt7ugT2ee5r2au4t2ftun2Df7f3++1trDWsrD+AO5B14XBdT1/0t69uGevX6kvoPB4UHhw5FHupqcGpoOKxxuKwRbpQ2jh9JPHLtO5/v2pssmvY3M5pLjoKj0qNPv0/+/tax4GOdx1nHm34w+GFXC62luBVqXdI62ZbeNtQe395/IuhEZ4drR8uPlj8ePKlzsuaU8qmy06TThadnzyw9M3VWdHbiXNq5kc6kznvn487f6Iro6r0QfOHSRb+L57u9us9ccrt08rLL5RNXWFfarjpebe1x6Gn5yeGnll7H3tY+p772a87XOvrn9p8e8Bg4d93n+sUbgTeu3px3s//W/Fu3BxMHh27zbj+5k3Xnxd28uzP3Vt/H3i9+oPCg8qHGw9qfTX5uHnIcOjXsM9zzKOrRvRHuyLNfcn95P1r4mPq4ckx7rOGJ7ZOT437j154ueDr6TPRsZqLoV8Vfdz03fv7Db56/9UzGTY6+EL+Y/b30pdrLg6/sX3VOhU89fJ39ema6+I3am0NvWW+738W+G5vJf49/X/XB5EPHx+CP92ezZ2f/AAOY8/wRDtFgAAAIbklEQVRoBdVZa5BURxU+fZ9z57mzs7PvF4i7srAQSCifMVDERC0jYlzUlJalKeGPlCnL/NEfywpWacoiVZRVJIYfGjGUu5bxj5qHFSAYyQOBEsJzYSHDvnd2dp535j66PX1vNgsULDPs1cr2Vs+9e7v79NfnnnP663MJYwwWYxEWI2iOedEClxabxgkBwjEvOuA9PQOOlSw64JMr4vK8GidYYMcOES4tVSEAAZ8FAUqon1GiAJEEEG0CjFB8cTaxZUMAo1gEqQA0UABprAjPbrUwXnkesgqKP8CBk5vDIenrE+BKmwI+MawA1MbCkdV10cBDflXuVmSxQRbFkCAQZ9U2ZTaONyxKcyXDHjMs83ImV3rz6njmDRPMUZB80zAJOuvvsflkXpTP7DrWyeXcYCqk75AEieawrEoty1vrvlcV0ja3VQdb1rVUQVd9EFqqNIj5ZfDJooPBsCnohq2ldDMynC42XZnW7z09lu25lMxDMl34y0gyvTsBwyewc84Z4MEPpWIzF/MBcLLtNzJISmxZU+PmWETbtqGzfvVja5uguyF02+kCIEJUk6Ex4oMV9XP9ZnQT/nZ24it7XrtoJ5LZ7SjAM+Bg2+0ckAOcbBkQIaZFVzY1bGurjezYfn87PNQZ5+13ZaQRXMzH26Lg8ymfUokQdAR59INOc53GQ6q/Jiiua6oJ7+h9uAPua47cHeLrwHEmQRmTGLHV6x4v+JYwWsOFCGRDn6RKem1rPPrkN9Y0uqAXLN4VwCgjYGEE8rBgMAjwKsF9S9WgLa9qjYcf+Po9jXdlGrfC5Wj8Vg0Lf+ZENAFmpGB9TWTLhmUxUD1UDg/gtudRnK+a4RtkgqQyO+RT5LVrmiLgJcN19gcGNojUWriS5yRQm7pcBTc/vyCKdW1RrWwzOTiYhGf+dRUmcgZosgDVfgWaMCS2V2tO+OzG0MiVjdUwiFiYm9a7O4kJAoZEooV9H4T0O0ofODkKr5+6+nY6V3heVZQpv6ZWaz55qSJJnXjtUBW5pT7k8xeK5u+B0PQdBVbQgTLq9HbQYthyNVSmTT6A/nB0aGpF0K99+trY1F7TNI9PZGXkKUVRtYjGZCIOV1dHR4Ynz8FSLV8BrjK6uiAlpLcmco1ipmgpAaU8rfesboCuumBg31uJbx6+qH0uX9D/em0i85xFhaslKZKA8/82RtYDhd/1MkCuBnjxrLgKB0EQSb5oWO+9O1bZrsy3+Kc3dcH+b99b07NuyXe6P9r8z/am+C9lkuqCjo4qGGkQES76qJcuz/2GOlUoFuVsQS+98frlaSeq8Gkqqctrg7Dz853wwrfugUfXtj3W3tJ8oCletRUEXy1SCSSYHhdu41gFqILcZCrzwkvnJmE0U3JtHefiL7eS2l7th11f7IQ9j65aVh+r+nlzbd2TELJrHPLmIXZX3wyBX8MTQMm8PJ0u9Pe9chGQYy9omvXouHu/thJqI+Ef1sZDm0AMBmfPiQsSPDuY2zhWwSH5ISU5Pjm98x9nRo7+7JVBB3wl5nJz35Vo/z/esBQUVf2+QlkD9Aw42/Ts3Au7ushdAhQ5UzJoOjE+OrV9/1tDR7cNnIax7N2bDX9nm1bUQXdz9Rp/MLwRoqAtDOzcaO7rvDrAWW8vhcatWVNjF6cmJre9embkz1947h3YfXgIUgVzblQldxgFH0ZOr/qULwM15k4Zlci4Vd9ZU5ltY71oObHBnBFQBidmUk8kEsOP7Hntwqsb974NfS8PAh7LKoo23Hw+2R4FQcSzKlDPgFOEyf8kx3HW94kQ7xJgRRdAJG7CyIWxgiXNUN0+k5nJLN83k3n8D8eHN3+1ux5+8uBHIKiWt1G1Rn3IJkiUCcQzU3G0h9qWHMeJdoSrwtr9dl6I6DNjFwRRyxiKnStSqkPJPsGSmZ+mp1P9z2dzOy3Klj31yMdmX9S8V75APEsomMZwT9fz9i6vkW9AvEgQyqrBQM2Dq9rrD0gCgXfHA0jpjIRm2Zcw+3CR2tZl27SnMZFSZ1lWcRwZITeDckresAEXaoKwwBh7/WQubgTOQj5BVjdv7KiBJz7bztMNcHIk03JiONNyfiK/ntv2VMHAMx6BjpoA/Gj9Emdjul7W7e6TeQNDK9WJLRm361P5c1drEmAaymaYoXpfjZoiOk7FHWuh5dxEHmzLHiXM9oyTz9FawRZw65f5yyzXBMpd0JGhFKB5nSwRMVvumDv2cxm4m1f5X4AuWhRePDUOtqEPQJVVGfWcBz1ahmPlTlxzqaJLquYZU1HTvjcTMD6dOULM0n+g5nKposHzdWbo7FgEkDBviWlYx++53XtQ33kvDU8dHAJm6L8usdwEZn09S3qiPed5lcCSLUpI0eEA8620zLbDl6bh8T+egkI+/7Rl6kegcTSPst1QUKaM+brhrjnF2yUQJNxnrGMnR7KbTw5nYFVjyAl98w2+VdvVlA67Dw3BgROjAKa+yyrpz0BKTbJnez1NT6AKrrnA1bEi1av2v3xaiL90dnxL2Kc0rsXc4WpcQEc8AEtiGrRiejmK6WWeMDIxtVwwKExijB5KFuBYIg1cy8dx0dTQ/yQVc78yBXMIqJ5i/VvvkqHdSjXuM/THKy7w2LQJ6fpJms38QiHGvlzBt+RwJv2JQ2elbjyRtjIi1AIRMAsKPuQduHVzr2YW+kIBE5BTwOzzxLKOiMX8QVuWh00IpqD+S0WHtLlzefpLBOZo/IYvEqQPnTX5dxmy4xookqaCjRuT4mMi8g3bxs2KCkj3GFj4+QSzA0RkeskU8iCJeUiBDv09Jt8OPEV6k7DlP3gxxh/dAPymPh/Kf5d897dIOd9P7H8oEd4G1JV8wPGbRadx52sgLmrRAZ99EZ5+LZgV+v+4Llrg/wX6HRCxgvzAAwAAAABJRU5ErkJggg==");
|
356 |
+
}
|
357 |
+
}
|
358 |
+
|
359 |
+
.admin_page_pmpro-paymentsettings .pmpro-admin-secure-key {
|
360 |
+
-webkit-text-security: disc;
|
361 |
}
|
362 |
|
363 |
/* advanced settings */
|
364 |
.admin_page_pmpro-advancedsettings .form-table select:not(.admin_page_pmpro-advancedsettings .form-table select#tospage) {
|
365 |
+
max-width: none;
|
366 |
}
|
367 |
|
368 |
/* orders */
|
369 |
.memberships_page_pmpro-orders .pmpro_admin .nav-tab-wrapper {
|
370 |
+
margin-bottom: 10px;
|
371 |
}
|
372 |
|
373 |
/* members list */
|
374 |
.wp-list-table.members .column-ID {
|
375 |
+
white-space: nowrap;
|
376 |
}
|
377 |
+
.wp-list-table.members #display_name {
|
378 |
+
width: auto;
|
379 |
}
|
380 |
|
381 |
/* settings */
|
382 |
tr.pmpro_settings_divider td {
|
383 |
+
padding: 0;
|
384 |
+
margin: 0;
|
385 |
+
}
|
386 |
+
|
387 |
+
/* admin pages */
|
388 |
+
.pmpro_admin_section-email-templates-content .pmpro-email-templates-variable-reference .form-table td {
|
389 |
+
padding: 5px;
|
390 |
+
}
|
391 |
+
.pmpro_admin_section-email-templates-content .pmpro-email-templates-variable-reference .form-table .widefat {
|
392 |
+
margin-bottom: 20px;
|
393 |
}
|
394 |
|
395 |
/* messages */
|
396 |
.pmpro_admin .pmpro_message {
|
397 |
+
background: #FFF;
|
398 |
+
border-left: 4px solid #FFF;
|
399 |
+
margin-right: 15px;
|
400 |
+
padding: 15px;
|
401 |
}
|
402 |
.pmpro_admin .pmpro_success {
|
403 |
+
background-color: rgba( 70, 180, 80, 0.1 );
|
404 |
+
border-left-color: rgb( 70, 180, 80 );
|
405 |
}
|
406 |
.pmpro_admin .pmpro_error,
|
407 |
.pmpro_admin tr.pmpro_error td {
|
408 |
+
background-color: rgba( 220, 50, 50, 0.1 );
|
409 |
+
border-left-color: rgb( 220, 50, 50 );
|
410 |
}
|
411 |
.pmpro_admin .pmpro_alert {
|
412 |
+
background-color: rgba( 255, 185, 0, 0.1 );
|
413 |
+
border-left-color: rgb( 255, 185, 0 );
|
414 |
}
|
415 |
.pmpro_admin .pmpro_success a {
|
416 |
+
color: #208A1B;
|
417 |
}
|
418 |
.pmpro_admin .pmpro_error a,
|
419 |
.pmpro_admin tr.pmpro_error td {
|
420 |
+
color: #CC0000;
|
421 |
}
|
422 |
.pmpro_admin .pmpro_alert a {
|
423 |
+
color: #CF8516;
|
424 |
}
|
425 |
|
426 |
/* notifications */
|
427 |
#pmpro_notifications .pmpro_notification {
|
428 |
+
position: relative;
|
429 |
}
|
430 |
#pmpro_notifications .pmpro_notification .pmpro_notification-general {
|
431 |
+
background: #FFF;
|
432 |
+
border-left: 4px solid #77A02E;
|
433 |
+
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
434 |
+
margin: 1em 0;
|
435 |
+
padding: 15px;
|
436 |
}
|
437 |
#pmpro_notifications .pmpro_notification .pmpro_notification-error {
|
438 |
+
background: #FFF;
|
439 |
+
border-left: 4px solid #DC3232;
|
440 |
+
box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
|
441 |
+
margin: 1em 0;
|
442 |
+
padding: 15px;
|
443 |
}
|
444 |
#pmpro_notifications .pmpro_notification h3 {
|
445 |
+
font-size: 24px;
|
446 |
+
font-weight: 400;
|
447 |
+
margin: 0;
|
448 |
}
|
449 |
#pmpro_notifications .pmpro_notification p {
|
450 |
+
margin: 1em 0 0 0;
|
451 |
}
|
452 |
#pmpro_notifications .pmpro_notification .button {
|
453 |
+
margin-right: 5px;
|
454 |
}
|
455 |
#pmpro_notifications .pmpro_notification .pmpro_notification-general h3 {
|
456 |
+
color: #77A02E;
|
457 |
}
|
458 |
#pmpro_notifications .pmpro_notification .pmpro_notification-error h3 {
|
459 |
+
color: #DC3232;
|
460 |
}
|
461 |
|
462 |
/* highlighted trs */
|
463 |
+
tr.pmpro_message {
|
464 |
+
background-image: none;
|
465 |
+
}
|
466 |
+
tr.pmpro_success {
|
467 |
+
background-image: none;
|
468 |
+
}
|
469 |
+
tr.pmpro_error {
|
470 |
+
background-image: none;
|
471 |
+
}
|
472 |
+
tr.pmpro_alert {
|
473 |
+
background-image: none;
|
474 |
+
}
|
475 |
|
476 |
/* discount levels */
|
477 |
.pmpro_discount_levels .pmpro_discount_level {
|
478 |
+
border: 1px solid #CCC;
|
479 |
+
margin: 15px 0;
|
480 |
+
padding: 10px;
|
481 |
}
|
482 |
.pmpro_discount_levels .pmpro_discount_level .pmpro_discount_levels_pricing {
|
483 |
+
background: #FFFFFF;
|
484 |
+
border: 1px solid #CCC;
|
485 |
+
margin: 10px 0 0 0;
|
486 |
+
padding: 0px 20px;
|
487 |
}
|
488 |
|
489 |
/* pagination */
|
490 |
+
div.pmpro_pagination {
|
491 |
+
padding: 3px;
|
492 |
+
margin: 5px 0px 5px 0px;
|
493 |
+
font-size: 10px;
|
494 |
+
float: right;
|
495 |
+
}
|
496 |
+
div.pmpro_pagination a {
|
497 |
+
padding: 2px 5px 2px 5px;
|
498 |
+
margin: 1px;
|
499 |
+
border: 1px solid #666;
|
500 |
+
text-decoration: none;
|
501 |
+
/* no underline */ color: #666;
|
502 |
+
background: #EEE;
|
503 |
+
}
|
504 |
+
div.pmpro_pagination a:hover, div.pmpro_pagination a:active {
|
505 |
+
background: #FFF;
|
506 |
+
}
|
507 |
+
div.pmpro_pagination span.current {
|
508 |
+
border: 1px solid #FFF;
|
509 |
+
color: #FFF;
|
510 |
+
background: #666;
|
511 |
+
padding: 2px 5px 2px 5px;
|
512 |
+
margin: 1px;
|
513 |
+
font-weight: bold;
|
514 |
+
}
|
515 |
+
div.pmpro_pagination span.disabled {
|
516 |
+
padding: 2px 5px 2px 5px;
|
517 |
+
margin: 2px;
|
518 |
+
border: 1px solid #BBB;
|
519 |
+
color: #BBB;
|
520 |
+
background: #EFEFEF;
|
521 |
+
}
|
522 |
|
523 |
+
p.pmpro_meta_notice {
|
524 |
+
font-size: .8em;
|
525 |
+
padding-top: 5px;
|
526 |
+
border-top: 1px solid #CCC;
|
527 |
+
}
|
528 |
|
529 |
/* add ons */
|
530 |
.memberships_page_pmpro-addons .pmpro_admin .nav-tab-wrapper {
|
531 |
+
margin-bottom: 10px;
|
532 |
+
}
|
533 |
+
.pmpro_admin .widgets-holder-wrap {
|
534 |
+
clear: both;
|
535 |
+
margin-top: 20px;
|
536 |
+
padding: 0 8px;
|
537 |
+
}
|
538 |
+
.pmpro_admin .widgets-holder-wrap .widget {
|
539 |
+
float: left;
|
540 |
+
width: 32%;
|
541 |
+
margin: 0 1% 1% 0;
|
542 |
+
position: relative;
|
543 |
+
}
|
544 |
+
.pmpro_admin .widgets-holder-wrap p.description {
|
545 |
+
padding: 0;
|
546 |
+
}
|
547 |
+
.pmpro_admin .widgets-holder-wrap .widget-top {
|
548 |
+
height: auto;
|
549 |
+
cursor: default;
|
550 |
+
}
|
551 |
+
.pmpro_admin .widgets-holder-wrap .widget-inside {
|
552 |
+
display: block;
|
553 |
+
height: 130px;
|
554 |
+
overflow: hidden;
|
555 |
+
}
|
556 |
+
.pmpro_admin .widgets-holder-wrap .widget-inside p {
|
557 |
+
height: 80px;
|
558 |
+
overflow: hidden;
|
559 |
+
}
|
560 |
+
.pmpro_admin #pmpro-gists.widgets-holder-wrap .widget-inside,
|
561 |
+
.pmpro_admin #pmpro-gists.widgets-holder-wrap .widget-inside p {
|
562 |
+
height: auto;
|
563 |
+
}
|
564 |
.pmpro_admin .widgets-holder-wrap .widget-title { }
|
565 |
.pmpro_admin .widgets-holder-wrap .widget-title h4 { }
|
566 |
+
.pmpro_admin .widgets-holder-wrap .widget-title .status-label {
|
567 |
+
display: block;
|
568 |
+
float: left;
|
569 |
+
margin: 0 5px 0 0;
|
570 |
+
width: 10px;
|
571 |
+
height: 10px;
|
572 |
+
overflow: hidden;
|
573 |
+
border-radius: 10px;
|
574 |
+
-moz-border-radius: 10px;
|
575 |
+
-webkit-border-radius: 10px;
|
576 |
+
border: 1px solid #DFDFDF;
|
577 |
+
text-indent: -9999em;
|
578 |
+
}
|
579 |
+
.pmpro_admin .widgets-holder-wrap .disabled .widget-title .status-label {
|
580 |
+
background: #F00;
|
581 |
+
}
|
582 |
+
.pmpro_admin .widgets-holder-wrap .enabled .widget-title .status-label {
|
583 |
+
background: #0C0;
|
584 |
+
}
|
585 |
|
586 |
+
.pmpro_admin .widgets-holder-wrap .widget-title .version {
|
587 |
+
position: absolute;
|
588 |
+
top: 13px;
|
589 |
+
right: 10px;
|
590 |
+
}
|
591 |
+
.pmpro_admin .widgets-holder-wrap .widget-inside .addon-thumb {
|
592 |
+
width: 100px;
|
593 |
+
height: 100px;
|
594 |
+
float: right;
|
595 |
+
margin: 10px 0 0 10px;
|
596 |
+
border: 1px solid #DFDFDF;
|
597 |
+
background: #FFF;
|
598 |
+
padding: 2px;
|
599 |
}
|
600 |
+
|
601 |
@media (max-width:900px) {
|
602 |
+
.auto-fold .pmpro_admin .widgets-holder-wrap .widget {
|
603 |
+
float: none;
|
604 |
+
width: 100%;
|
605 |
+
}
|
606 |
+
.auto-fold .pmpro_admin .widgets-holder-wrap .widget-inside,
|
607 |
+
.auto-fold .pmpro_admin .widgets-holder-wrap .widget-inside p {
|
608 |
+
height: auto;
|
609 |
+
}
|
610 |
}
|
611 |
|
612 |
/* license */
|
613 |
.memberships_page_pmpro-license h2 {
|
614 |
+
text-align: left;
|
615 |
}
|
616 |
.memberships_page_pmpro-license .pmpro_icon {
|
617 |
+
margin-top: 20px;
|
618 |
}
|
619 |
|
620 |
/* misc */
|
621 |
+
.pmpro_lite {
|
622 |
+
color: #777;
|
623 |
+
}
|
624 |
+
.pmpro_pad20 {
|
625 |
+
padding: 20px !important;
|
626 |
+
}
|
627 |
+
.pmpro_red {
|
628 |
+
color: #CC0000;
|
629 |
+
}
|
630 |
+
.pmpro_green {
|
631 |
+
color: #00AA00;
|
632 |
+
}
|
633 |
+
.ssp_description #description {
|
634 |
+
width: 100%;
|
635 |
+
}
|
636 |
+
.top0em {
|
637 |
+
margin-top: 0;
|
638 |
+
}
|
639 |
+
h2.nav-tab-wrapper {
|
640 |
+
margin-bottom: 1em;
|
641 |
+
}
|
642 |
|
643 |
/* reports */
|
644 |
.memberships_page_pmpro-reports .pmpro_admin .nav-tab-wrapper {
|
645 |
+
margin-bottom: 10px;
|
646 |
}
|
647 |
.pmpro_reports-holder { }
|
648 |
+
.pmpro_reports-holder .postbox h2 {
|
649 |
+
border-bottom: 1px solid #eee;
|
650 |
+
font-size: 14px;
|
651 |
+
padding: 8px 12px;
|
652 |
+
margin: 0;
|
653 |
+
line-height: 1.4;
|
654 |
+
}
|
655 |
+
.pmpro_clickable {
|
656 |
+
cursor: pointer;
|
657 |
+
}
|
658 |
+
.js .postbox.pmpro_clickable h3 {
|
659 |
+
cursor: pointer;
|
660 |
+
}
|
661 |
#pmpro_report_login .wp-list-table tbody td,
|
662 |
#pmpro_report_memberships .wp-list-table tbody tr.pmpro_report_tr td,
|
663 |
#pmpro_report_sales .wp-list-table tbody tr.pmpro_report_tr td {
|
664 |
+
font-size: 1.2rem;
|
665 |
+
font-weight: bold;
|
666 |
}
|
667 |
#pmpro_report_sales .wp-list-table tbody td:last-child {
|
668 |
+
text-align: right;
|
669 |
}
|
670 |
.pmpro_report-holder .wp-list-table tbody th button {
|
671 |
+
border: none;
|
672 |
+
background: 0 0;
|
673 |
+
-webkit-border-radius: 0;
|
674 |
+
border-radius: 0;
|
675 |
+
color: #555;
|
676 |
+
cursor: pointer;
|
677 |
+
line-height: 1.7;
|
678 |
+
padding: 0;
|
679 |
}
|
680 |
button.pmpro_report_th:before {
|
681 |
+
bottom: 2px;
|
682 |
+
display: inline-block;
|
683 |
+
font: 400 20px/1 dashicons;
|
684 |
+
left: 0;
|
685 |
+
padding: 0 5px 0 0;
|
686 |
+
position: relative;
|
687 |
+
text-decoration: none;
|
688 |
+
vertical-align: bottom;
|
689 |
}
|
690 |
button.pmpro_report_th_opened:before {
|
691 |
+
content: "\f140";
|
692 |
}
|
693 |
button.pmpro_report_th_closed:before {
|
694 |
+
content: "\f139";
|
695 |
}
|
696 |
.pmpro_report-holder .wp-list-table tbody tr.pmpro_report_tr_sub:last-child th,
|
697 |
.pmpro_report-holder .wp-list-table tbody tr.pmpro_report_tr_sub:last-child td {
|
698 |
+
border-bottom: 1px solid #CCC;
|
699 |
}
|
700 |
#pmpro_report_memberships .wp-list-table tbody:nth-child(odd) .pmpro_report_tr th,
|
701 |
#pmpro_report_memberships .wp-list-table tbody:nth-child(odd) .pmpro_report_tr td,
|
702 |
#pmpro_report_sales .wp-list-table tbody:nth-child(odd) .pmpro_report_tr th,
|
703 |
#pmpro_report_sales .wp-list-table tbody:nth-child(odd) .pmpro_report_tr td {
|
704 |
+
background-color: #fff;
|
705 |
}
|
706 |
#pmpro_report_memberships .wp-list-table tbody:nth-child(even) .pmpro_report_tr th,
|
707 |
#pmpro_report_memberships .wp-list-table tbody:nth-child(even) .pmpro_report_tr td,
|
708 |
#pmpro_report_sales .wp-list-table tbody:nth-child(even) .pmpro_report_tr th,
|
709 |
#pmpro_report_sales .wp-list-table tbody:nth-child(even) .pmpro_report_tr td {
|
710 |
+
background-color: #f9f9f9;
|
711 |
}
|
712 |
.pmpro_report-holder .pmpro_report-button {
|
713 |
+
text-align: center;
|
714 |
}
|
715 |
|
716 |
/* Dashboard */
|
717 |
.pmpro_admin #pmpro_dashboard_welcome h3 {
|
718 |
+
font-size: 16px;
|
719 |
+
font-weight: 600;
|
720 |
+
margin: 1rem 0 0;
|
721 |
}
|
722 |
.pmpro_admin #pmpro_dashboard_welcome .pmpro-dashboard-welcome-columns {
|
723 |
+
display: grid;
|
724 |
+
grid-gap: 2rem;
|
725 |
+
grid-template-columns: 1fr 1fr 1fr;
|
726 |
}
|
727 |
.pmpro_admin #pmpro_dashboard_welcome .button-action {
|
728 |
+
background: #dd823b;
|
729 |
+
border-color: #c36922 #ad5d1e #ad5d1e;
|
730 |
+
color: #fff;
|
731 |
+
box-shadow: 0 1px 0 #ad5d1e;
|
732 |
+
text-shadow: 0 -1px 1px #ad5d1e, 1px 0 1px #ad5d1e, 0 1px 1px #ad5d1e, -1px 0 1px #ad5d1e;
|
733 |
}
|
734 |
.pmpro_admin #pmpro_dashboard_welcome ul li {
|
735 |
+
font-size: 14px;
|
736 |
+
line-height: 16px;
|
737 |
+
padding: 0 0 8px;
|
738 |
}
|
739 |
.pmpro_admin #pmpro_dashboard_welcome ul li a .dashicons {
|
740 |
+
color: #82878c;
|
741 |
}
|
742 |
.pmpro_admin p.text-center {
|
743 |
+
text-align: center;
|
744 |
}
|
745 |
|
746 |
/* new installation notices */
|
747 |
.pmpro-new-install {
|
748 |
+
padding: 2rem;
|
749 |
+
text-align: center;
|
750 |
}
|
751 |
.pmpro-new-install h2 {
|
752 |
+
color: #AAA;
|
753 |
+
font-size: 2rem;
|
754 |
}
|
755 |
.pmpro-new-install h2:before {
|
756 |
+
display: block;
|
757 |
+
font: 400 5rem/1.5 dashicons;
|
758 |
}
|
759 |
.memberships_page_pmpro-membershiplevels .pmpro-new-install h2:before {
|
760 |
+
content: "\f110";
|
761 |
}
|
762 |
.memberships_page_pmpro-pagesettings .pmpro-new-install h2:before {
|
763 |
+
content: "\f133";
|
764 |
}
|
765 |
.memberships_page_pmpro-discountcodes .pmpro-new-install h2:before {
|
766 |
+
content: "\f323";
|
767 |
}
|
768 |
#wpbody-content .pmpro-new-install .button-primary,
|
769 |
#wpbody-content .pmpro-new-install .button {
|
770 |
+
font-size: 1.2em;
|
771 |
+
height: auto;
|
772 |
+
margin-bottom: .5rem;
|
773 |
+
padding: .75em 1.5em;
|
774 |
}
|
775 |
|
776 |
@media screen and (max-width: 782px) {
|
777 |
+
.pmpro_admin .pmpro_banner {
|
778 |
+
display: block;
|
779 |
+
}
|
780 |
+
.pmpro_admin .nav-tab-wrapper:after {
|
781 |
+
clear: both;
|
782 |
+
display: block;
|
783 |
+
}
|
784 |
+
.pmpro_admin .nav-tab-wrapper a {
|
785 |
+
margin-top: 5px;
|
786 |
+
}
|
787 |
+
.dashboard-widgets-wrap .wp-list-table tr:not(.inline-edit-row):not(.no-items) td:not(.check-column),
|
788 |
+
.pmpro_report-holder .wp-list-table tr:not(.inline-edit-row):not(.no-items) td:not(.check-column) {
|
789 |
+
display: table-cell;
|
790 |
+
overflow: hidden;
|
791 |
+
word-wrap: break-word;
|
792 |
+
}
|
793 |
+
#pmpro_dashboard_report_recent_members .wp-list-table .column-username img {
|
794 |
+
display: none;
|
795 |
+
}
|
796 |
+
#pmpro_dashboard_report_recent_orders .wp-list-table {
|
797 |
+
border: none;
|
798 |
+
}
|
799 |
+
#pmpro_dashboard_report_recent_orders .wp-list-table thead,
|
800 |
+
#pmpro_dashboard_report_recent_orders br {
|
801 |
+
display: none;
|
802 |
+
}
|
803 |
+
#pmpro_dashboard_report_recent_orders .wp-list-table tr,
|
804 |
+
#pmpro_dashboard_report_recent_orders .wp-list-table tr td {
|
805 |
+
background: none;
|
806 |
+
display: inline-block;
|
807 |
+
padding: 0;
|
808 |
+
position: relative;
|
809 |
+
}
|
810 |
+
#pmpro_dashboard_report_recent_orders .wp-list-table tr td:after {
|
811 |
+
color: #CCC;
|
812 |
+
content: ' |';
|
813 |
+
}
|
814 |
+
#pmpro_dashboard_report_recent_orders .wp-list-table tr {
|
815 |
+
padding: 5px;
|
816 |
+
}
|
817 |
+
#pmpro_dashboard_report_recent_orders .wp-list-table tr td:last-child:after {
|
818 |
+
content: '';
|
819 |
+
}
|
820 |
+
.pmpro-new-install {
|
821 |
+
padding: 0;
|
822 |
+
}
|
823 |
+
.pmpro-new-install h2 {
|
824 |
+
font-size: 1.4rem;
|
825 |
+
}
|
826 |
+
.pmpro-new-install .button-primary, .pmpro-new-install .button {
|
827 |
+
display: block;
|
828 |
+
}
|
829 |
+
.pmpro_admin #pmpro_dashboard_welcome .pmpro-dashboard-welcome-columns {
|
830 |
+
display: block;
|
831 |
+
}
|
832 |
+
.pmpro_admin #pmpro_dashboard_welcome .pmpro-dashboard-welcome-column {
|
833 |
+
border-bottom: 1px solid #CCC;
|
834 |
+
margin-bottom: 2em;
|
835 |
+
padding-bottom: 2em;
|
836 |
+
}
|
837 |
+
.pmpro_admin #pmpro_dashboard_welcome .pmpro-dashboard-welcome-column:last-child {
|
838 |
+
border: none;
|
839 |
+
margin: 0;
|
840 |
+
padding: 0;
|
841 |
+
}
|
842 |
+
.memberships_page_pmpro-membershiplevels .pmpro_admin .membership-levels tr th:first-child:before,
|
843 |
+
.memberships_page_pmpro-membershiplevels .pmpro_admin .membership-levels tr td:first-child:before {
|
844 |
+
content: '';
|
845 |
+
width: 0;
|
846 |
+
}
|
847 |
}
|
css/blocks.editor.css
CHANGED
@@ -44,15 +44,23 @@
|
|
44 |
text-transform: uppercase;
|
45 |
}
|
46 |
.pmpro-block-require-membership-element .components-panel__body {
|
47 |
-
background: rgba(237, 239, 240, 0
|
48 |
border-bottom: 0;
|
49 |
border-top: none;
|
|
|
|
|
50 |
padding-top: 0;
|
|
|
|
|
51 |
}
|
52 |
.pmpro-block-require-membership-element .block-editor-inner-blocks {
|
53 |
padding-left: 16px;
|
54 |
padding-right: 16px;
|
55 |
}
|
|
|
|
|
|
|
|
|
56 |
|
57 |
/* Checkout Button Block */
|
58 |
.wp-block-pmpro-checkout-button {
|
44 |
text-transform: uppercase;
|
45 |
}
|
46 |
.pmpro-block-require-membership-element .components-panel__body {
|
47 |
+
background: rgba(237, 239, 240, 0);
|
48 |
border-bottom: 0;
|
49 |
border-top: none;
|
50 |
+
border-left: 5px solid rgba(237, 239, 240, 0.8);
|
51 |
+
border-bottom: 5px solid rgba(237, 239, 240, 0.8);
|
52 |
padding-top: 0;
|
53 |
+
height: 200px;
|
54 |
+
overflow: auto;
|
55 |
}
|
56 |
.pmpro-block-require-membership-element .block-editor-inner-blocks {
|
57 |
padding-left: 16px;
|
58 |
padding-right: 16px;
|
59 |
}
|
60 |
+
.pmpro-block-inspector-scrollable {
|
61 |
+
height: 200px;
|
62 |
+
overflow: auto;
|
63 |
+
}
|
64 |
|
65 |
/* Checkout Button Block */
|
66 |
.wp-block-pmpro-checkout-button {
|
css/frontend.css
CHANGED
@@ -279,6 +279,29 @@ select.pmpro_error {
|
|
279 |
#pmpro_message_bottom {
|
280 |
margin-bottom: 1em;
|
281 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
282 |
/*---------------------------------------
|
283 |
Membership Checkout
|
284 |
---------------------------------------*/
|
@@ -306,6 +329,14 @@ select.pmpro_error {
|
|
306 |
-ms-grid-columns: 3fr 1em 1fr;
|
307 |
grid-template-columns: 3fr 1fr;
|
308 |
grid-column-gap: 1em;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
309 |
}
|
310 |
#pmpro_license {
|
311 |
background: #FFF;
|
@@ -318,12 +349,23 @@ select.pmpro_error {
|
|
318 |
}
|
319 |
|
320 |
/* Stripe gateway Membership Checkout specific styles. */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
321 |
.pmpro_checkout_gateway-stripe form.pmpro_form #pmpro_payment_information_fields .pmpro_checkout-fields,
|
322 |
.pmpro_billing_gateway-stripe form.pmpro_form #pmpro_payment_information_fields .pmpro_checkout-fields {
|
323 |
display: -ms-grid;
|
324 |
display: grid;
|
325 |
-ms-grid-rows: auto 1em auto 1em auto;
|
326 |
-
|
327 |
"AccountNumber AccountNumber"
|
328 |
"Expiry CVV"
|
329 |
"DiscountCode DiscountCode";
|
@@ -394,6 +436,17 @@ select.pmpro_error {
|
|
394 |
padding-right: 10px;
|
395 |
}
|
396 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
397 |
/*---------------------------------------
|
398 |
Membership Account
|
399 |
---------------------------------------*/
|
@@ -631,6 +684,16 @@ li.pmpro_more {
|
|
631 |
/*---------------------------------------
|
632 |
Responsive Styles
|
633 |
---------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
634 |
@media (max-width:768px) {
|
635 |
#pmpro_account #pmpro_account-membership .pmpro_table td:nth-child(1),
|
636 |
#pmpro_levels_table td:nth-child(1) {
|
279 |
#pmpro_message_bottom {
|
280 |
margin-bottom: 1em;
|
281 |
}
|
282 |
+
|
283 |
+
/*---------------------------------------
|
284 |
+
Display Price Parts
|
285 |
+
---------------------------------------*/
|
286 |
+
.pmpro_price_part_span {
|
287 |
+
display: block;
|
288 |
+
}
|
289 |
+
.pmpro_price_part-total {
|
290 |
+
border-top: 1px solid #CCC;
|
291 |
+
margin-top: 5px;
|
292 |
+
padding-top: 5px;
|
293 |
+
}
|
294 |
+
.pmpro_price_part_label:after {
|
295 |
+
content: ": ";
|
296 |
+
}
|
297 |
+
.pmpro_price_part_sub {
|
298 |
+
font-size: 75%;
|
299 |
+
}
|
300 |
+
span.pmpro_price_part_sub:before {
|
301 |
+
content: "\2022";
|
302 |
+
padding-right: 5px;
|
303 |
+
}
|
304 |
+
|
305 |
/*---------------------------------------
|
306 |
Membership Checkout
|
307 |
---------------------------------------*/
|
329 |
-ms-grid-columns: 3fr 1em 1fr;
|
330 |
grid-template-columns: 3fr 1fr;
|
331 |
grid-column-gap: 1em;
|
332 |
+
grid-template-areas:
|
333 |
+
"leftcol rightcol";
|
334 |
+
}
|
335 |
+
#pmpro_payment_information_fields .pmpro_checkout-fields-display-seal .pmpro_checkout-fields-leftcol {
|
336 |
+
grid-area: leftcol;
|
337 |
+
}
|
338 |
+
#pmpro_payment_information_fields .pmpro_checkout-fields-display-seal .pmpro_checkout-fields-rightcol {
|
339 |
+
grid-area: rightcol;
|
340 |
}
|
341 |
#pmpro_license {
|
342 |
background: #FFF;
|
349 |
}
|
350 |
|
351 |
/* Stripe gateway Membership Checkout specific styles. */
|
352 |
+
.pmpro_checkout_gateway-stripe form.pmpro_form #pmpro_payment_information_fields .pmpro_checkout-field-payment-request-button {
|
353 |
+
grid-area: paymentrequestbutton;
|
354 |
+
}
|
355 |
+
.pmpro_checkout_gateway-stripe form.pmpro_form #pmpro_payment_information_fields .pmpro_checkout-field-payment-request-button h4 {
|
356 |
+
margin-top: 1em;
|
357 |
+
}
|
358 |
+
.pmpro_checkout_gateway-stripe form.pmpro_form #pmpro_payment_information_fields .pmpro_checkout-fields-display-seal {
|
359 |
+
grid-template-areas:
|
360 |
+
"paymentrequestbutton rightcol"
|
361 |
+
"leftcol rightcol";
|
362 |
+
}
|
363 |
.pmpro_checkout_gateway-stripe form.pmpro_form #pmpro_payment_information_fields .pmpro_checkout-fields,
|
364 |
.pmpro_billing_gateway-stripe form.pmpro_form #pmpro_payment_information_fields .pmpro_checkout-fields {
|
365 |
display: -ms-grid;
|
366 |
display: grid;
|
367 |
-ms-grid-rows: auto 1em auto 1em auto;
|
368 |
+
grid-template-areas:
|
369 |
"AccountNumber AccountNumber"
|
370 |
"Expiry CVV"
|
371 |
"DiscountCode DiscountCode";
|
436 |
padding-right: 10px;
|
437 |
}
|
438 |
|
439 |
+
.pmpro_invoice-field-billing_name,
|
440 |
+
.pmpro_invoice-field-billing_street,
|
441 |
+
.pmpro_invoice-field-billing_country,
|
442 |
+
.pmpro_invoice-field-billing_phone {
|
443 |
+
display: block;
|
444 |
+
}
|
445 |
+
|
446 |
+
.pmpro_invoice-field-billing_city:after {
|
447 |
+
content: ',';
|
448 |
+
}
|
449 |
+
|
450 |
/*---------------------------------------
|
451 |
Membership Account
|
452 |
---------------------------------------*/
|
684 |
/*---------------------------------------
|
685 |
Responsive Styles
|
686 |
---------------------------------------*/
|
687 |
+
@media only screen and (min-width: 1160px) {
|
688 |
+
.pmpro_checkout_gateway-stripe form.pmpro_form #pmpro_payment_information_fields #payment-request-button {
|
689 |
+
max-width: 50%;
|
690 |
+
}
|
691 |
+
}
|
692 |
+
@media only screen and (min-width: 960px) and (max-width: 1160px) {
|
693 |
+
.pmpro_checkout_gateway-stripe form.pmpro_form #pmpro_payment_information_fields #payment-request-button {
|
694 |
+
max-width: 50%;
|
695 |
+
}
|
696 |
+
}
|
697 |
@media (max-width:768px) {
|
698 |
#pmpro_account #pmpro_account-membership .pmpro_table td:nth-child(1),
|
699 |
#pmpro_levels_table td:nth-child(1) {
|
email/admin_change.html
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
<p>An administrator at !!sitename!! has changed your membership level.</p>
|
2 |
-
|
3 |
-
<p>!!membership_change!!.</p>
|
4 |
-
|
5 |
-
<p>If you did not request this membership change and would like more information please contact us at !!siteemail!!</p>
|
6 |
-
|
7 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/admin_change_admin.html
DELETED
@@ -1,5 +0,0 @@
|
|
1 |
-
<p>An administrator at !!sitename!! has changed a membership level for !!name!!.</p>
|
2 |
-
|
3 |
-
<p>!!membership_change!!.</p>
|
4 |
-
|
5 |
-
<p>Log in to your WordPress admin here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
email/billable_invoice.html
DELETED
@@ -1,6 +0,0 @@
|
|
1 |
-
<p>Thank you for your membership to !!sitename!!. Below is your invoice for order #: !!order_code!!</p>
|
2 |
-
|
3 |
-
!!invoice!!
|
4 |
-
|
5 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
6 |
-
<p>To view an online version of this invoice, click here: !!invoice_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
email/billing.html
DELETED
@@ -1,16 +0,0 @@
|
|
1 |
-
<p>Your billing information at !!sitename!! has been changed.</p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>
|
5 |
-
Billing Information:<br />
|
6 |
-
!!billing_address!!
|
7 |
-
</p>
|
8 |
-
|
9 |
-
<p>
|
10 |
-
!!cardtype!!: !!accountnumber!!<br />
|
11 |
-
Expires: !!expirationmonth!!/!!expirationyear!!
|
12 |
-
</p>
|
13 |
-
|
14 |
-
<p>If you did not request a billing information change please contact us at !!siteemail!!</p>
|
15 |
-
|
16 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/billing_admin.html
DELETED
@@ -1,17 +0,0 @@
|
|
1 |
-
<p>The billing information for !!display_name!! at !!sitename!! has been changed.</p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>
|
5 |
-
Billing Information:<br />
|
6 |
-
!!billing_name!!<br />
|
7 |
-
!!billing_street!!<br />
|
8 |
-
!!billing_city!!, !!billing_state!! !!billing_zip!! !!billing_country!!
|
9 |
-
!!billing_phone!!
|
10 |
-
</p>
|
11 |
-
|
12 |
-
<p>
|
13 |
-
!!cardtype!!: !!accountnumber!!<br />
|
14 |
-
Expires: !!expirationmonth!!/!!expirationyear!!
|
15 |
-
</p>
|
16 |
-
|
17 |
-
<p>Log in to your WordPress dashboard here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/billing_failure.html
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<p>The current subscription payment for your !!sitename!! membership has failed. <strong>Please click the following link to log in and update your billing information to avoid account suspension. !!login_link!!</strong></p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
|
|
|
|
|
email/billing_failure_admin.html
DELETED
@@ -1,6 +0,0 @@
|
|
1 |
-
<p>The subscription payment for !!user_login!! at !!sitename!! has failed.</p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
5 |
-
|
6 |
-
<p>Log in to your WordPress admin here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
email/cancel.html
DELETED
@@ -1,6 +0,0 @@
|
|
1 |
-
<p>Your membership at !!sitename!! has been cancelled.</p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
5 |
-
|
6 |
-
<p>If you did not request this cancellation and would like more information please contact us at !!siteemail!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
email/cancel_admin.html
DELETED
@@ -1,8 +0,0 @@
|
|
1 |
-
<p>The membership for !!user_login!! at !!sitename!! has been cancelled.</p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
5 |
-
<p>Start Date: !!startdate!!</p>
|
6 |
-
<p>Cancellation Date: !!enddate!!</p>
|
7 |
-
|
8 |
-
<p>Log in to your WordPress admin here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/checkout_check.html
DELETED
@@ -1,19 +0,0 @@
|
|
1 |
-
<p>Thank you for your membership to !!sitename!!. Your membership account is now active.</p>
|
2 |
-
|
3 |
-
!!membership_level_confirmation_message!!
|
4 |
-
|
5 |
-
!!instructions!!
|
6 |
-
|
7 |
-
<p>Below are details about your membership account and a receipt for your initial membership invoice.</p>
|
8 |
-
|
9 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
10 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
11 |
-
<p>Membership Fee: !!membership_cost!!</p>
|
12 |
-
!!membership_expiration!! !!discount_code!!
|
13 |
-
|
14 |
-
<p>
|
15 |
-
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
16 |
-
Total Billed: !!invoice_total!!
|
17 |
-
</p>
|
18 |
-
|
19 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/checkout_check_admin.html
DELETED
@@ -1,17 +0,0 @@
|
|
1 |
-
<p>There was a new member checkout at !!sitename!!.</p>
|
2 |
-
|
3 |
-
<p><strong>They have chosen to pay by check.</strong></p>
|
4 |
-
|
5 |
-
<p>Below are details about the new membership account and a receipt for the initial membership invoice.</p>
|
6 |
-
|
7 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
8 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
9 |
-
<p>Membership Fee: !!membership_cost!!</p>
|
10 |
-
!!membership_expiration!! !!discount_code!!
|
11 |
-
|
12 |
-
<p>
|
13 |
-
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
14 |
-
Total Billed: $!!invoice_total!!
|
15 |
-
</p>
|
16 |
-
|
17 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/checkout_express.html
DELETED
@@ -1,15 +0,0 @@
|
|
1 |
-
<p>Thank you for your membership to !!sitename!!. Your membership account is now active.</p>
|
2 |
-
!!membership_level_confirmation_message!!
|
3 |
-
<p>Below are details about your membership account and a receipt for your initial membership invoice.</p>
|
4 |
-
|
5 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
6 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
7 |
-
<p>Membership Fee: !!membership_cost!!</p>
|
8 |
-
!!membership_expiration!! !!discount_code!!
|
9 |
-
|
10 |
-
<p>
|
11 |
-
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
12 |
-
Total Billed: !!invoice_total!!
|
13 |
-
</p>
|
14 |
-
|
15 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/checkout_express_admin.html
DELETED
@@ -1,14 +0,0 @@
|
|
1 |
-
<p>There was a new member checkout at !!sitename!!.</p>
|
2 |
-
<p>Below are details about the new membership account and a receipt for the initial membership invoice.</p>
|
3 |
-
|
4 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
6 |
-
<p>Membership Fee: !!membership_cost!!</p>
|
7 |
-
!!membership_expiration!! !!discount_code!!
|
8 |
-
|
9 |
-
<p>
|
10 |
-
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
11 |
-
Total Billed: !!invoice_total!!
|
12 |
-
</p>
|
13 |
-
|
14 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/checkout_free.html
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
<p>Thank you for your membership to !!sitename!!. Your membership account is now active.</p>
|
2 |
-
!!membership_level_confirmation_message!!
|
3 |
-
<p>Below are details about your membership account.</p>
|
4 |
-
|
5 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
6 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
7 |
-
!!membership_expiration!! !!discount_code!!
|
8 |
-
|
9 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/checkout_free_admin.html
DELETED
@@ -1,8 +0,0 @@
|
|
1 |
-
<p>There was a new member checkout at !!sitename!!.</p>
|
2 |
-
<p>Below are details about the new membership account.</p>
|
3 |
-
|
4 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
6 |
-
!!membership_expiration!! !!discount_code!!
|
7 |
-
|
8 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/checkout_freetrial.html
DELETED
@@ -1,20 +0,0 @@
|
|
1 |
-
<p>Thank you for your membership to !!sitename!!. Your membership account is now active.</p>
|
2 |
-
!!membership_level_confirmation_message!!
|
3 |
-
<p>Below are details about your membership account.</p>
|
4 |
-
|
5 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
6 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
7 |
-
<p>Membership Fee: !!membership_cost!!</p>
|
8 |
-
!!membership_expiration!! !!discount_code!!
|
9 |
-
|
10 |
-
<p>
|
11 |
-
Billing Information on File:<br />
|
12 |
-
!!billing_address!!
|
13 |
-
</p>
|
14 |
-
|
15 |
-
<p>
|
16 |
-
!!cardtype!!: !!accountnumber!!<br />
|
17 |
-
Expires: !!expirationmonth!!/!!expirationyear!!
|
18 |
-
</p>
|
19 |
-
|
20 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/checkout_freetrial_admin.html
DELETED
@@ -1,19 +0,0 @@
|
|
1 |
-
<p>There was a new member checkout at !!sitename!!.</p>
|
2 |
-
<p>Below are details about the new membership account and a receipt for the initial membership invoice.</p>
|
3 |
-
|
4 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
6 |
-
<p>Membership Fee: !!membership_cost!!</p>
|
7 |
-
!!membership_expiration!! !!discount_code!!
|
8 |
-
|
9 |
-
<p>
|
10 |
-
Billing Information on File:<br />
|
11 |
-
!!billing_address!!
|
12 |
-
</p>
|
13 |
-
|
14 |
-
<p>
|
15 |
-
!!cardtype!!: !!accountnumber!!<br />
|
16 |
-
Expires: !!expirationmonth!!/!!expirationyear!!
|
17 |
-
</p>
|
18 |
-
|
19 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/checkout_paid.html
DELETED
@@ -1,24 +0,0 @@
|
|
1 |
-
<p>Thank you for your membership to !!sitename!!. Your membership account is now active.</p>
|
2 |
-
!!membership_level_confirmation_message!!
|
3 |
-
<p>Below are details about your membership account and a receipt for your initial membership invoice.</p>
|
4 |
-
|
5 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
6 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
7 |
-
<p>Membership Fee: !!membership_cost!!</p>
|
8 |
-
!!membership_expiration!! !!discount_code!!
|
9 |
-
|
10 |
-
<p>
|
11 |
-
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
12 |
-
Total Billed: !!invoice_total!!
|
13 |
-
</p>
|
14 |
-
<p>
|
15 |
-
Billing Information:<br />
|
16 |
-
!!billing_address!!
|
17 |
-
</p>
|
18 |
-
|
19 |
-
<p>
|
20 |
-
!!cardtype!!: !!accountnumber!!<br />
|
21 |
-
Expires: !!expirationmonth!!/!!expirationyear!!
|
22 |
-
</p>
|
23 |
-
|
24 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/checkout_paid_admin.html
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
<p>There was a new member checkout at !!sitename!!.</p>
|
2 |
-
<p>Below are details about the new membership account and a receipt for the initial membership invoice.</p>
|
3 |
-
|
4 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
6 |
-
<p>Membership Fee: !!membership_cost!!</p>
|
7 |
-
!!membership_expiration!! !!discount_code!!
|
8 |
-
|
9 |
-
<p>
|
10 |
-
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
11 |
-
Total Billed: !!invoice_total!!
|
12 |
-
</p>
|
13 |
-
<p>
|
14 |
-
Billing Information:<br />
|
15 |
-
!!billing_address!!
|
16 |
-
</p>
|
17 |
-
|
18 |
-
<p>
|
19 |
-
!!cardtype!!: !!accountnumber!!<br />
|
20 |
-
Expires: !!expirationmonth!!/!!expirationyear!!
|
21 |
-
</p>
|
22 |
-
|
23 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/checkout_trial.html
DELETED
@@ -1,24 +0,0 @@
|
|
1 |
-
<p>Thank you for your membership to !!sitename!!. Your membership account is now active.</p>
|
2 |
-
!!membership_level_confirmation_message!!
|
3 |
-
<p>Below are details about your membership account and a receipt for your initial membership invoice.</p>
|
4 |
-
|
5 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
6 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
7 |
-
<p>Membership Fee: !!membership_cost!!</p>
|
8 |
-
!!membership_expiration!! !!discount_code!!
|
9 |
-
|
10 |
-
<p>
|
11 |
-
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
12 |
-
Total Billed: !!invoice_total!!
|
13 |
-
</p>
|
14 |
-
<p>
|
15 |
-
Billing Information:<br />
|
16 |
-
!!billing_address!!
|
17 |
-
</p>
|
18 |
-
|
19 |
-
<p>
|
20 |
-
!!cardtype!!: !!accountnumber!!<br />
|
21 |
-
Expires: !!expirationmonth!!/!!expirationyear!!
|
22 |
-
</p>
|
23 |
-
|
24 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/checkout_trial_admin.html
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
<p>There was a new member checkout at !!sitename!!.</p>
|
2 |
-
<p>Below are details about the new membership account and a receipt for the initial membership invoice.</p>
|
3 |
-
|
4 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
6 |
-
<p>Membership Fee: !!membership_cost!!</p>
|
7 |
-
!!membership_expiration!! !!discount_code!!
|
8 |
-
|
9 |
-
<p>
|
10 |
-
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
11 |
-
Total Billed: !!invoice_total!!
|
12 |
-
</p>
|
13 |
-
<p>
|
14 |
-
Billing Information:<br />
|
15 |
-
!!billing_address!!
|
16 |
-
</p>
|
17 |
-
|
18 |
-
<p>
|
19 |
-
!!cardtype!!: !!accountnumber!!<br />
|
20 |
-
Expires: !!expirationmonth!!/!!expirationyear!!
|
21 |
-
</p>
|
22 |
-
|
23 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/credit_card_expiring.html
DELETED
@@ -1,13 +0,0 @@
|
|
1 |
-
<p>The payment method used for your membership at !!sitename!! will expire soon. <strong>Please click the following link to log in and update your billing information to avoid account suspension. !!login_link!!</strong></p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>The most recent account information we have on file is:</p>
|
5 |
-
|
6 |
-
<p>!!billing_name!!</br />
|
7 |
-
!!billing_address!!
|
8 |
-
</p>
|
9 |
-
|
10 |
-
<p>
|
11 |
-
!!cardtype!!: !!accountnumber!!<br />
|
12 |
-
Expires: !!expirationmonth!!/!!expirationyear!!
|
13 |
-
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/default.html
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
!!body!!
|
|
email/footer.html
DELETED
@@ -1,4 +0,0 @@
|
|
1 |
-
<p>
|
2 |
-
Respectfully,<br />
|
3 |
-
!!sitename!!
|
4 |
-
</p>
|
|
|
|
|
|
|
|
email/header.html
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
<p>Dear !!name!!,</p>
|
|
email/invoice.html
DELETED
@@ -1,19 +0,0 @@
|
|
1 |
-
<p>Thank you for your membership to !!sitename!!. Below is a receipt for your most recent membership invoice.</p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>
|
5 |
-
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
6 |
-
Total Billed: !!invoice_total!!
|
7 |
-
</p>
|
8 |
-
<p>
|
9 |
-
Billing Information:<br />
|
10 |
-
!!billing_address!!
|
11 |
-
</p>
|
12 |
-
|
13 |
-
<p>
|
14 |
-
!!cardtype!!: !!accountnumber!!<br />
|
15 |
-
Expires: !!expirationmonth!!/!!expirationyear!!
|
16 |
-
</p>
|
17 |
-
|
18 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
19 |
-
<p>To view an online version of this invoice, click here: !!invoice_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/membership_expired.html
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
<p>Your membership at !!sitename!! has ended.</p>
|
2 |
-
|
3 |
-
<p>Thank you for your support.</p>
|
4 |
-
|
5 |
-
<p>View our current membership offerings here: !!levels_link!!</p>
|
6 |
-
|
7 |
-
<p>Log in to manage your account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/membership_expiring.html
DELETED
@@ -1,6 +0,0 @@
|
|
1 |
-
<p>Thank you for your membership to !!sitename!!. This is just a reminder that your membership will end on !!enddate!!.</p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
5 |
-
|
6 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
email/payment_action.html
DELETED
@@ -1,4 +0,0 @@
|
|
1 |
-
<p>Customer authentication is required to finish setting up your subscription at !!sitename!!.</p>
|
2 |
-
|
3 |
-
<p>Please complete the verification steps issued by your payment provider at the following link:</p>
|
4 |
-
<p>!!invoice_url!!</p>
|
|
|
|
|
|
|
|
email/payment_action_admin.html
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
<p>A payment at !!sitename!! for !!user_login!! requires additional authentication customer authentication to complete.</p>
|
2 |
-
<p>Below is a copy of the email we sent to !!user_email!! to notify them that they need to complete their payment:</p>
|
3 |
-
|
4 |
-
<p>Customer authentication is required to finish setting up your subscription at !!sitename!!.</p>
|
5 |
-
|
6 |
-
<p>Please complete the verification steps issued by your payment provider at the following link:</p>
|
7 |
-
<p>!!invoice_url!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
email/trial_ending.html
DELETED
@@ -1,8 +0,0 @@
|
|
1 |
-
<p>Thank you for your membership to !!sitename!!. Your trial period is ending on !!trial_end!!.</p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
5 |
-
|
6 |
-
<p>Your fee will be changing from !!trial_amount!! to !!billing_amount!! every !!cycle_number!! !!cycle_period!!(s).</p>
|
7 |
-
|
8 |
-
<p>Log in to your membership account here: !!login_link!!</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/addons.php
CHANGED
@@ -130,7 +130,7 @@ function pmpro_update_plugins_filter( $value ) {
|
|
130 |
}
|
131 |
|
132 |
// compare versions
|
133 |
-
if (
|
134 |
$value->response[ $plugin_file ] = pmpro_getPluginAPIObjectFromAddon( $addon );
|
135 |
$value->response[ $plugin_file ]->new_version = $addon['Version'];
|
136 |
} else {
|
@@ -306,7 +306,7 @@ function pmpro_admin_init_updating_plugins() {
|
|
306 |
|
307 |
$slug = str_replace( '.php', '', basename( $plugin ) );
|
308 |
$addon = pmpro_getAddonBySlug( $slug );
|
309 |
-
if ( ! empty( $addon ) && ! pmpro_license_isValid( null, 'plus' ) ) {
|
310 |
require_once( ABSPATH . 'wp-admin/admin-header.php' );
|
311 |
|
312 |
echo '<div class="wrap"><h2>' . __( 'Update Plugin' ) . '</h2>';
|
@@ -332,7 +332,7 @@ function pmpro_admin_init_updating_plugins() {
|
|
332 |
|
333 |
$slug = str_replace( '.php', '', basename( $plugin ) );
|
334 |
$addon = pmpro_getAddonBySlug( $slug );
|
335 |
-
if ( ! empty( $addon ) && ! pmpro_license_isValid( null, 'plus' ) ) {
|
336 |
$msg = __( 'You must enter a valid PMPro Plus License Key under Settings > PMPro License to update this add on.', 'paid-memberships-pro' );
|
337 |
echo '<div class="error"><p>' . $msg . '</p></div>';
|
338 |
|
130 |
}
|
131 |
|
132 |
// compare versions
|
133 |
+
if ( version_compare( $plugin_data['Version'], $addon['Version'], '<' ) ) {
|
134 |
$value->response[ $plugin_file ] = pmpro_getPluginAPIObjectFromAddon( $addon );
|
135 |
$value->response[ $plugin_file ]->new_version = $addon['Version'];
|
136 |
} else {
|
306 |
|
307 |
$slug = str_replace( '.php', '', basename( $plugin ) );
|
308 |
$addon = pmpro_getAddonBySlug( $slug );
|
309 |
+
if ( ! empty( $addon ) && $addon->License == 'plus' && ! pmpro_license_isValid( null, 'plus' ) ) {
|
310 |
require_once( ABSPATH . 'wp-admin/admin-header.php' );
|
311 |
|
312 |
echo '<div class="wrap"><h2>' . __( 'Update Plugin' ) . '</h2>';
|
332 |
|
333 |
$slug = str_replace( '.php', '', basename( $plugin ) );
|
334 |
$addon = pmpro_getAddonBySlug( $slug );
|
335 |
+
if ( ! empty( $addon ) && $addon->License == 'plus' && ! pmpro_license_isValid( null, 'plus' ) ) {
|
336 |
$msg = __( 'You must enter a valid PMPro Plus License Key under Settings > PMPro License to update this add on.', 'paid-memberships-pro' );
|
337 |
echo '<div class="error"><p>' . $msg . '</p></div>';
|
338 |
|
includes/admin.php
CHANGED
@@ -45,21 +45,41 @@ add_action( 'admin_init', 'pmpro_block_dashboard_redirect', 9 );
|
|
45 |
* @since 2.3
|
46 |
*/
|
47 |
function pmpro_block_dashboard() {
|
48 |
-
global $current_user;
|
49 |
|
50 |
$block_dashboard = pmpro_getOption( 'block_dashboard' );
|
51 |
|
52 |
-
if (
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
|
|
58 |
$block = true;
|
59 |
} else {
|
60 |
$block = false;
|
61 |
-
}
|
62 |
$block = apply_filters( 'pmpro_block_dashboard', $block );
|
63 |
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
65 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
* @since 2.3
|
46 |
*/
|
47 |
function pmpro_block_dashboard() {
|
48 |
+
global $current_user, $pagenow;
|
49 |
|
50 |
$block_dashboard = pmpro_getOption( 'block_dashboard' );
|
51 |
|
52 |
+
if (
|
53 |
+
! wp_doing_ajax()
|
54 |
+
&& 'admin-post.php' !== $pagenow
|
55 |
+
&& ! empty( $block_dashboard )
|
56 |
+
&& ! current_user_can( 'manage_options' )
|
57 |
+
&& ! current_user_can( 'edit_users' )
|
58 |
+
&& ! current_user_can( 'edit_posts' )
|
59 |
+
&& in_array( 'subscriber', (array) $current_user->roles )
|
60 |
+
) {
|
61 |
$block = true;
|
62 |
} else {
|
63 |
$block = false;
|
64 |
+
}
|
65 |
$block = apply_filters( 'pmpro_block_dashboard', $block );
|
66 |
|
67 |
+
/**
|
68 |
+
* Allow filtering whether to block Dashboard access.
|
69 |
+
*
|
70 |
+
* @param bool $block Whether to block Dashboard access.
|
71 |
+
*/
|
72 |
+
return apply_filters( 'pmpro_block_dashboard', $block );
|
73 |
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Initialize our Site Health integration and add hooks.
|
77 |
+
*
|
78 |
+
* @since 2.6.2
|
79 |
+
*/
|
80 |
+
function pmpro_init_site_health_integration() {
|
81 |
+
$site_health = PMPro_Site_Health::init();
|
82 |
+
$site_health->hook();
|
83 |
+
}
|
84 |
+
|
85 |
+
add_action( 'admin_init', 'pmpro_init_site_health_integration' );
|
includes/adminpages.php
CHANGED
@@ -10,6 +10,7 @@ function pmpro_getPMProCaps() {
|
|
10 |
'pmpro_pagesettings',
|
11 |
'pmpro_paymentsettings',
|
12 |
'pmpro_emailsettings',
|
|
|
13 |
'pmpro_advancedsettings',
|
14 |
'pmpro_addons',
|
15 |
'pmpro_memberslist',
|
@@ -68,6 +69,7 @@ function pmpro_add_pages() {
|
|
68 |
add_submenu_page( 'admin.php', __( 'Page Settings', 'paid-memberships-pro' ), __( 'Page Settings', 'paid-memberships-pro' ), 'pmpro_pagesettings', 'pmpro-pagesettings', 'pmpro_pagesettings' );
|
69 |
add_submenu_page( 'admin.php', __( 'Payment Settings', 'paid-memberships-pro' ), __( 'Payment Settings', 'paid-memberships-pro' ), 'pmpro_paymentsettings', 'pmpro-paymentsettings', 'pmpro_paymentsettings' );
|
70 |
add_submenu_page( 'admin.php', __( 'Email Settings', 'paid-memberships-pro' ), __( 'Email Settings', 'paid-memberships-pro' ), 'pmpro_emailsettings', 'pmpro-emailsettings', 'pmpro_emailsettings' );
|
|
|
71 |
add_submenu_page( 'admin.php', __( 'Advanced Settings', 'paid-memberships-pro' ), __( 'Advanced Settings', 'paid-memberships-pro' ), 'pmpro_advancedsettings', 'pmpro-advancedsettings', 'pmpro_advancedsettings' );
|
72 |
|
73 |
add_action( 'load-' . $list_table_hook, 'pmpro_list_table_screen_options' );
|
@@ -91,6 +93,7 @@ function pmpro_parent_file( $parent_file ) {
|
|
91 |
'pmpro-pagesettings',
|
92 |
'pmpro-paymentsettings',
|
93 |
'pmpro-emailsettings',
|
|
|
94 |
'pmpro-advancedsettings',
|
95 |
);
|
96 |
|
@@ -130,7 +133,7 @@ function pmpro_admin_bar_menu() {
|
|
130 |
array(
|
131 |
'id' => 'paid-memberships-pro',
|
132 |
'title' => __( '<span class="ab-icon"></span>Memberships', 'paid-memberships-pro' ),
|
133 |
-
'href' =>
|
134 |
)
|
135 |
);
|
136 |
|
@@ -141,7 +144,7 @@ function pmpro_admin_bar_menu() {
|
|
141 |
'id' => 'pmpro-dashboard',
|
142 |
'parent' => 'paid-memberships-pro',
|
143 |
'title' => __( 'Dashboard', 'paid-memberships-pro' ),
|
144 |
-
'href' =>
|
145 |
)
|
146 |
);
|
147 |
}
|
@@ -153,7 +156,7 @@ function pmpro_admin_bar_menu() {
|
|
153 |
'id' => 'pmpro-members-list',
|
154 |
'parent' => 'paid-memberships-pro',
|
155 |
'title' => __( 'Members', 'paid-memberships-pro' ),
|
156 |
-
'href' =>
|
157 |
)
|
158 |
);
|
159 |
}
|
@@ -165,7 +168,7 @@ function pmpro_admin_bar_menu() {
|
|
165 |
'id' => 'pmpro-orders',
|
166 |
'parent' => 'paid-memberships-pro',
|
167 |
'title' => __( 'Orders', 'paid-memberships-pro' ),
|
168 |
-
'href' =>
|
169 |
)
|
170 |
);
|
171 |
}
|
@@ -177,7 +180,7 @@ function pmpro_admin_bar_menu() {
|
|
177 |
'id' => 'pmpro-reports',
|
178 |
'parent' => 'paid-memberships-pro',
|
179 |
'title' => __( 'Reports', 'paid-memberships-pro' ),
|
180 |
-
'href' =>
|
181 |
)
|
182 |
);
|
183 |
}
|
@@ -189,7 +192,7 @@ function pmpro_admin_bar_menu() {
|
|
189 |
'id' => 'pmpro-membership-levels',
|
190 |
'parent' => 'paid-memberships-pro',
|
191 |
'title' => __( 'Settings', 'paid-memberships-pro' ),
|
192 |
-
'href' =>
|
193 |
)
|
194 |
);
|
195 |
}
|
@@ -201,7 +204,7 @@ function pmpro_admin_bar_menu() {
|
|
201 |
'id' => 'pmpro-addons',
|
202 |
'parent' => 'paid-memberships-pro',
|
203 |
'title' => __( 'Add Ons', 'paid-memberships-pro' ),
|
204 |
-
'href' =>
|
205 |
)
|
206 |
);
|
207 |
}
|
@@ -220,7 +223,7 @@ function pmpro_admin_bar_menu() {
|
|
220 |
'id' => 'pmpro-license',
|
221 |
'parent' => 'paid-memberships-pro',
|
222 |
'title' => __( '<span style="color: ' . $span_color . '; line-height: 26px;">License</span>', 'paid-memberships-pro' ),
|
223 |
-
'href' =>
|
224 |
)
|
225 |
);
|
226 |
}
|
@@ -272,6 +275,10 @@ function pmpro_emailsettings() {
|
|
272 |
require_once( PMPRO_DIR . '/adminpages/emailsettings.php' );
|
273 |
}
|
274 |
|
|
|
|
|
|
|
|
|
275 |
function pmpro_advancedsettings() {
|
276 |
require_once( PMPRO_DIR . '/adminpages/advancedsettings.php' );
|
277 |
}
|
@@ -392,7 +399,7 @@ function pmpro_add_action_links( $links ) {
|
|
392 |
}
|
393 |
|
394 |
$new_links = array(
|
395 |
-
'<a href="' .
|
396 |
);
|
397 |
return array_merge( $new_links, $links );
|
398 |
}
|
10 |
'pmpro_pagesettings',
|
11 |
'pmpro_paymentsettings',
|
12 |
'pmpro_emailsettings',
|
13 |
+
'pmpro_emailtemplates',
|
14 |
'pmpro_advancedsettings',
|
15 |
'pmpro_addons',
|
16 |
'pmpro_memberslist',
|
69 |
add_submenu_page( 'admin.php', __( 'Page Settings', 'paid-memberships-pro' ), __( 'Page Settings', 'paid-memberships-pro' ), 'pmpro_pagesettings', 'pmpro-pagesettings', 'pmpro_pagesettings' );
|
70 |
add_submenu_page( 'admin.php', __( 'Payment Settings', 'paid-memberships-pro' ), __( 'Payment Settings', 'paid-memberships-pro' ), 'pmpro_paymentsettings', 'pmpro-paymentsettings', 'pmpro_paymentsettings' );
|
71 |
add_submenu_page( 'admin.php', __( 'Email Settings', 'paid-memberships-pro' ), __( 'Email Settings', 'paid-memberships-pro' ), 'pmpro_emailsettings', 'pmpro-emailsettings', 'pmpro_emailsettings' );
|
72 |
+
add_submenu_page( 'admin.php', __( 'Email Templates', 'paid-memberships-pro' ), __( 'Email Templates', 'paid-memberships-pro' ), 'pmpro_emailtemplates', 'pmpro-emailtemplates', 'pmpro_emailtemplates' );
|
73 |
add_submenu_page( 'admin.php', __( 'Advanced Settings', 'paid-memberships-pro' ), __( 'Advanced Settings', 'paid-memberships-pro' ), 'pmpro_advancedsettings', 'pmpro-advancedsettings', 'pmpro_advancedsettings' );
|
74 |
|
75 |
add_action( 'load-' . $list_table_hook, 'pmpro_list_table_screen_options' );
|
93 |
'pmpro-pagesettings',
|
94 |
'pmpro-paymentsettings',
|
95 |
'pmpro-emailsettings',
|
96 |
+
'pmpro-emailtemplates',
|
97 |
'pmpro-advancedsettings',
|
98 |
);
|
99 |
|
133 |
array(
|
134 |
'id' => 'paid-memberships-pro',
|
135 |
'title' => __( '<span class="ab-icon"></span>Memberships', 'paid-memberships-pro' ),
|
136 |
+
'href' => admin_url( '/admin.php?page=' . $top_menu_page )
|
137 |
)
|
138 |
);
|
139 |
|
144 |
'id' => 'pmpro-dashboard',
|
145 |
'parent' => 'paid-memberships-pro',
|
146 |
'title' => __( 'Dashboard', 'paid-memberships-pro' ),
|
147 |
+
'href' => admin_url( '/admin.php?page=pmpro-dashboard' )
|
148 |
)
|
149 |
);
|
150 |
}
|
156 |
'id' => 'pmpro-members-list',
|
157 |
'parent' => 'paid-memberships-pro',
|
158 |
'title' => __( 'Members', 'paid-memberships-pro' ),
|
159 |
+
'href' => admin_url( '/admin.php?page=pmpro-memberslist' )
|
160 |
)
|
161 |
);
|
162 |
}
|
168 |
'id' => 'pmpro-orders',
|
169 |
'parent' => 'paid-memberships-pro',
|
170 |
'title' => __( 'Orders', 'paid-memberships-pro' ),
|
171 |
+
'href' => admin_url( '/admin.php?page=pmpro-orders' )
|
172 |
)
|
173 |
);
|
174 |
}
|
180 |
'id' => 'pmpro-reports',
|
181 |
'parent' => 'paid-memberships-pro',
|
182 |
'title' => __( 'Reports', 'paid-memberships-pro' ),
|
183 |
+
'href' => admin_url( '/admin.php?page=pmpro-reports' )
|
184 |
)
|
185 |
);
|
186 |
}
|
192 |
'id' => 'pmpro-membership-levels',
|
193 |
'parent' => 'paid-memberships-pro',
|
194 |
'title' => __( 'Settings', 'paid-memberships-pro' ),
|
195 |
+
'href' => admin_url( '/admin.php?page=pmpro-membershiplevels' )
|
196 |
)
|
197 |
);
|
198 |
}
|
204 |
'id' => 'pmpro-addons',
|
205 |
'parent' => 'paid-memberships-pro',
|
206 |
'title' => __( 'Add Ons', 'paid-memberships-pro' ),
|
207 |
+
'href' => admin_url( '/admin.php?page=pmpro-addons' )
|
208 |
)
|
209 |
);
|
210 |
}
|
223 |
'id' => 'pmpro-license',
|
224 |
'parent' => 'paid-memberships-pro',
|
225 |
'title' => __( '<span style="color: ' . $span_color . '; line-height: 26px;">License</span>', 'paid-memberships-pro' ),
|
226 |
+
'href' => admin_url( '/admin.php?page=pmpro-license' )
|
227 |
)
|
228 |
);
|
229 |
}
|
275 |
require_once( PMPRO_DIR . '/adminpages/emailsettings.php' );
|
276 |
}
|
277 |
|
278 |
+
function pmpro_emailtemplates() {
|
279 |
+
require_once( PMPRO_DIR . '/adminpages/emailtemplates.php' );
|
280 |
+
}
|
281 |
+
|
282 |
function pmpro_advancedsettings() {
|
283 |
require_once( PMPRO_DIR . '/adminpages/advancedsettings.php' );
|
284 |
}
|
399 |
}
|
400 |
|
401 |
$new_links = array(
|
402 |
+
'<a href="' . admin_url( 'admin.php?page=' . $top_menu_page ) . '">Settings</a>',
|
403 |
);
|
404 |
return array_merge( $new_links, $links );
|
405 |
}
|
includes/capabilities.php
CHANGED
@@ -57,6 +57,7 @@ function pmpro_get_capability_defs($role)
|
|
57 |
'pmpro_pagesettings',
|
58 |
'pmpro_paymentsettings',
|
59 |
'pmpro_emailsettings',
|
|
|
60 |
'pmpro_advancedsettings',
|
61 |
'pmpro_addons',
|
62 |
'pmpro_memberslist',
|
57 |
'pmpro_pagesettings',
|
58 |
'pmpro_paymentsettings',
|
59 |
'pmpro_emailsettings',
|
60 |
+
'pmpro_emailtemplates',
|
61 |
'pmpro_advancedsettings',
|
62 |
'pmpro_addons',
|
63 |
'pmpro_memberslist',
|
includes/compatibility.php
CHANGED
@@ -4,46 +4,113 @@
|
|
4 |
* Check if certain plugins or themes are installed and activated
|
5 |
* and if found dynamically load the relevant /includes/compatibility/ files.
|
6 |
*/
|
7 |
-
function pmpro_compatibility_checker
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
array(
|
30 |
-
'file' => '
|
31 |
'check_type' => 'constant',
|
32 |
-
'check_value' => '
|
33 |
-
),
|
34 |
-
array(
|
35 |
-
'file' => 'wp-engine.php',
|
36 |
-
'check_type' => 'function',
|
37 |
-
'check_value' => 'wpe_filter_site_url'
|
38 |
)
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
}
|
49 |
-
add_action( '
|
4 |
* Check if certain plugins or themes are installed and activated
|
5 |
* and if found dynamically load the relevant /includes/compatibility/ files.
|
6 |
*/
|
7 |
+
function pmpro_compatibility_checker() {
|
8 |
+
$compat_checks = [
|
9 |
+
[
|
10 |
+
'file' => 'siteorigin.php',
|
11 |
+
'check_type' => 'constant',
|
12 |
+
'check_value' => 'SITEORIGIN_PANELS_VERSION',
|
13 |
+
],
|
14 |
+
[
|
15 |
+
'file' => 'elementor.php',
|
16 |
+
'check_type' => 'constant',
|
17 |
+
'check_value' => 'ELEMENTOR_VERSION',
|
18 |
+
],
|
19 |
+
[
|
20 |
+
'file' => 'beaver-builder.php',
|
21 |
+
'check_type' => 'constant',
|
22 |
+
'check_value' => 'FL_BUILDER_VERSION',
|
23 |
+
],
|
24 |
+
[
|
25 |
+
'file' => 'theme-my-login.php',
|
26 |
+
'check_type' => 'class',
|
27 |
+
'check_value' => 'Theme_My_Login',
|
28 |
+
],
|
29 |
+
[
|
30 |
+
'file' => 'woocommerce.php',
|
31 |
+
'check_type' => 'constant',
|
32 |
+
'check_value' => 'WC_PLUGIN_FILE',
|
33 |
+
],
|
34 |
+
[
|
35 |
+
'file' => 'wp-engine.php',
|
36 |
+
'check_type' => 'function',
|
37 |
+
'check_value' => 'wpe_filter_site_url',
|
38 |
+
],
|
39 |
+
[
|
40 |
+
'file' => 'divi.php',
|
41 |
+
'check_type' => 'constant',
|
42 |
+
'check_value' => 'ET_BUILDER_PLUGIN_DIR',
|
43 |
+
],
|
44 |
+
[
|
45 |
+
'file' => 'jetpack.php',
|
46 |
+
'check_type' => 'class',
|
47 |
+
'check_value' => 'Jetpack',
|
48 |
+
],
|
49 |
+
];
|
50 |
+
|
51 |
+
foreach ( $compat_checks as $value ) {
|
52 |
+
if ( pmpro_compatibility_checker_is_requirement_met( $value ) ) {
|
53 |
+
include_once( PMPRO_DIR . '/includes/compatibility/' . $value['file'] ) ;
|
54 |
+
}
|
55 |
+
}
|
56 |
+
}
|
57 |
+
add_action( 'plugins_loaded', 'pmpro_compatibility_checker' );
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Check whether the requirement is met.
|
61 |
+
*
|
62 |
+
* @since 2.6.4
|
63 |
+
*
|
64 |
+
* @param array $requirement The requirement config (check_type, check_value, check_constant_true).
|
65 |
+
*
|
66 |
+
* @return bool Whether the requirement is met.
|
67 |
+
*/
|
68 |
+
function pmpro_compatibility_checker_is_requirement_met( $requirement ) {
|
69 |
+
// Make sure we have the keys that we expect.
|
70 |
+
if ( ! isset( $requirement['check_type'], $requirement['check_value'] ) ) {
|
71 |
+
return false;
|
72 |
+
}
|
73 |
+
|
74 |
+
// Check for a constant and maybe check if the constant is true-ish.
|
75 |
+
if ( 'constant' === $requirement['check_type'] ) {
|
76 |
+
return (
|
77 |
+
defined( $requirement['check_value'] )
|
78 |
+
&& (
|
79 |
+
empty( $requirement['check_constant_true'] )
|
80 |
+
|| constant( $requirement['check_value'] )
|
81 |
+
)
|
82 |
+
);
|
83 |
+
}
|
84 |
+
|
85 |
+
// Check for a function.
|
86 |
+
if ( 'function' === $requirement['check_type'] ) {
|
87 |
+
return function_exists( $requirement['check_value'] );
|
88 |
+
}
|
89 |
+
|
90 |
+
// Check for a class.
|
91 |
+
if ( 'class' === $requirement['check_type'] ) {
|
92 |
+
return class_exists( $requirement['check_value'] );
|
93 |
+
}
|
94 |
+
|
95 |
+
return false;
|
96 |
+
}
|
97 |
+
|
98 |
+
function pmpro_compatibility_checker_themes(){
|
99 |
+
|
100 |
+
$compat_checks = array(
|
101 |
array(
|
102 |
+
'file' => 'divi.php',
|
103 |
'check_type' => 'constant',
|
104 |
+
'check_value' => 'ET_BUILDER_THEME' //Adds support for the Divi theme.
|
|
|
|
|
|
|
|
|
|
|
105 |
)
|
106 |
+
);
|
107 |
+
|
108 |
+
foreach ( $compat_checks as $key => $value ) {
|
109 |
+
if ( pmpro_compatibility_checker_is_requirement_met( $value ) ) {
|
110 |
+
include_once( PMPRO_DIR . '/includes/compatibility/' . $value['file'] ) ;
|
111 |
+
}
|
112 |
+
}
|
113 |
+
|
114 |
+
|
115 |
}
|
116 |
+
add_action( 'after_setup_theme', 'pmpro_compatibility_checker_themes' );
|
includes/compatibility/beaver-builder.php
CHANGED
@@ -26,9 +26,11 @@ function pmpro_beaver_builder_settings_form( $form, $id ) {
|
|
26 |
}
|
27 |
global $membership_levels;
|
28 |
$levels = array();
|
|
|
29 |
foreach ( $membership_levels as $level ) {
|
30 |
$levels[ $level->id ] = $level->name;
|
31 |
}
|
|
|
32 |
$row_settings_pmpro = array(
|
33 |
'title' => __( 'PMPro', 'paid-memberships-pro' ),
|
34 |
'sections' => array(
|
@@ -83,6 +85,7 @@ function pmpro_beaver_builder_check_field_connections( $is_visible, $node ) {
|
|
83 |
if ( ! defined( 'PMPRO_VERSION' ) ) {
|
84 |
return $is_visible;
|
85 |
}
|
|
|
86 |
if ( 'row' === $node->type ) {
|
87 |
if ( isset( $node->settings->pmpro_enable ) && 'yes' === $node->settings->pmpro_enable ) {
|
88 |
if ( pmpro_hasMembershipLevel( $node->settings->pmpro_memberships ) || empty( $node->settings->pmpro_memberships ) ) {
|
@@ -120,6 +123,7 @@ function pmpro_beaver_builder_add_custom_tab_all_modules( $form, $slug ) {
|
|
120 |
if ( in_array( $slug, $modules, true ) ) {
|
121 |
global $membership_levels;
|
122 |
$levels = array();
|
|
|
123 |
foreach ( $membership_levels as $level ) {
|
124 |
$levels[ $level->id ] = $level->name;
|
125 |
}
|
26 |
}
|
27 |
global $membership_levels;
|
28 |
$levels = array();
|
29 |
+
$levels[0] = __( 'Non-members', 'paid-memberships-pro' );
|
30 |
foreach ( $membership_levels as $level ) {
|
31 |
$levels[ $level->id ] = $level->name;
|
32 |
}
|
33 |
+
|
34 |
$row_settings_pmpro = array(
|
35 |
'title' => __( 'PMPro', 'paid-memberships-pro' ),
|
36 |
'sections' => array(
|
85 |
if ( ! defined( 'PMPRO_VERSION' ) ) {
|
86 |
return $is_visible;
|
87 |
}
|
88 |
+
|
89 |
if ( 'row' === $node->type ) {
|
90 |
if ( isset( $node->settings->pmpro_enable ) && 'yes' === $node->settings->pmpro_enable ) {
|
91 |
if ( pmpro_hasMembershipLevel( $node->settings->pmpro_memberships ) || empty( $node->settings->pmpro_memberships ) ) {
|
123 |
if ( in_array( $slug, $modules, true ) ) {
|
124 |
global $membership_levels;
|
125 |
$levels = array();
|
126 |
+
$levels[0] = __( 'Non-members', 'paid-memberships-pro' );
|
127 |
foreach ( $membership_levels as $level ) {
|
128 |
$levels[ $level->id ] = $level->name;
|
129 |
}
|
includes/compatibility/divi.php
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class PMProDivi{
|
4 |
+
|
5 |
+
function __construct(){
|
6 |
+
|
7 |
+
if ( empty( $_GET['page'] ) || 'et_divi_role_editor' !== $_GET['page'] ) {
|
8 |
+
add_filter( 'et_builder_get_parent_modules', array( $this, 'toggle' ) );
|
9 |
+
add_filter( 'et_pb_module_content', array( $this, 'restrict_content' ), 10, 4 );
|
10 |
+
add_filter( 'et_pb_all_fields_unprocessed_et_pb_row', array( $this, 'row_settings' ) );
|
11 |
+
add_filter( 'et_pb_all_fields_unprocessed_et_pb_section', array( $this, 'section_settings' ) );
|
12 |
+
}
|
13 |
+
|
14 |
+
}
|
15 |
+
|
16 |
+
public function toggle( $modules ) {
|
17 |
+
|
18 |
+
if ( isset( $modules['et_pb_row'] ) && is_object( $modules['et_pb_row'] ) ) {
|
19 |
+
$modules['et_pb_row']->settings_modal_toggles['custom_css']['toggles']['paid-memberships-pro'] = __( 'Paid Memberships Pro', 'paid-memberships-pro' );
|
20 |
+
}
|
21 |
+
|
22 |
+
if ( isset( $modules['et_pb_section'] ) && is_object( $modules['et_pb_section'] ) ) {
|
23 |
+
$modules['et_pb_section']->settings_modal_toggles['custom_css']['toggles']['paid-memberships-pro'] = __( 'Paid Memberships Pro', 'paid-memberships-pro' );
|
24 |
+
}
|
25 |
+
|
26 |
+
return $modules;
|
27 |
+
|
28 |
+
}
|
29 |
+
|
30 |
+
public function row_settings( $settings ) {
|
31 |
+
|
32 |
+
$settings['paid-memberships-pro'] = array(
|
33 |
+
'tab_slug' => 'custom_css',
|
34 |
+
'label' => __( 'Restrict Row by Level', 'paid-memberships-pro' ),
|
35 |
+
'description' => __( 'Enter comma-separated level IDs.', 'paid-memberships-pro' ),
|
36 |
+
'type' => 'text',
|
37 |
+
'default' => '',
|
38 |
+
'option_category' => 'configuration',
|
39 |
+
'toggle_slug' => 'paid-memberships-pro',
|
40 |
+
);
|
41 |
+
|
42 |
+
return $settings;
|
43 |
+
|
44 |
+
}
|
45 |
+
|
46 |
+
public function section_settings( $settings ) {
|
47 |
+
|
48 |
+
$settings['paid-memberships-pro'] = array(
|
49 |
+
'tab_slug' => 'custom_css',
|
50 |
+
'label' => __( 'Restrict Section by Level', 'paid-memberships-pro' ),
|
51 |
+
'description' => __( 'Enter comma-separated level IDs.', 'paid-memberships-pro' ),
|
52 |
+
'type' => 'text',
|
53 |
+
'default' => '',
|
54 |
+
'option_category' => 'configuration',
|
55 |
+
'toggle_slug' => 'paid-memberships-pro',
|
56 |
+
);
|
57 |
+
|
58 |
+
return $settings;
|
59 |
+
|
60 |
+
}
|
61 |
+
|
62 |
+
public function restrict_content( $output, $props, $attrs, $slug ) {
|
63 |
+
|
64 |
+
if ( et_fb_is_enabled() ) {
|
65 |
+
return $output;
|
66 |
+
}
|
67 |
+
|
68 |
+
if( !isset( $props['paid-memberships-pro'] ) ){
|
69 |
+
return $output;
|
70 |
+
}
|
71 |
+
|
72 |
+
$level = $props['paid-memberships-pro'];
|
73 |
+
|
74 |
+
if ( empty( trim( $level ) ) || trim( $level ) === '0' ) {
|
75 |
+
return $output;
|
76 |
+
}
|
77 |
+
|
78 |
+
if( strpos( $level, "," ) ) {
|
79 |
+
//they specified many levels
|
80 |
+
$levels = explode( ",", $level );
|
81 |
+
} else {
|
82 |
+
//they specified just one level
|
83 |
+
$levels = array( $level );
|
84 |
+
}
|
85 |
+
|
86 |
+
if( pmpro_hasMembershipLevel( $levels ) ){
|
87 |
+
return $output;
|
88 |
+
} else {
|
89 |
+
return '';
|
90 |
+
}
|
91 |
+
}
|
92 |
+
}
|
93 |
+
new PMProDivi();
|
includes/compatibility/elementor/class-pmpro-elementor-content-restriction.php
CHANGED
@@ -54,9 +54,15 @@ class PMPro_Elementor_Content_Restriction extends PMPro_Elementor {
|
|
54 |
|
55 |
// Don't hide content in editor mode.
|
56 |
if ( \Elementor\Plugin::$instance->editor->is_edit_mode() ) {
|
57 |
-
|
58 |
-
|
59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
$should_render = $this->pmpro_elementor_has_access( $element );
|
61 |
|
62 |
return apply_filters( 'pmpro_elementor_section_access', $should_render, $element );
|
54 |
|
55 |
// Don't hide content in editor mode.
|
56 |
if ( \Elementor\Plugin::$instance->editor->is_edit_mode() ) {
|
57 |
+
return $should_render;
|
58 |
+
}
|
59 |
|
60 |
+
// Bypass if it's already hidden.
|
61 |
+
if ( $should_render === false ) {
|
62 |
+
return $should_render;
|
63 |
+
}
|
64 |
+
|
65 |
+
// Checks if the element is restricted and then if the user has access.
|
66 |
$should_render = $this->pmpro_elementor_has_access( $element );
|
67 |
|
68 |
return apply_filters( 'pmpro_elementor_section_access', $should_render, $element );
|
includes/compatibility/jetpack.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Jetpack Compatibility.
|
4 |
+
*
|
5 |
+
* @since 2.6.5
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Support Jetpack SSO login for WordPress.com.
|
10 |
+
*
|
11 |
+
* @since 2.6.4
|
12 |
+
*/
|
13 |
+
function pmpro_jetpack_sso_handle_login() {
|
14 |
+
global $pmpro_pages, $action;
|
15 |
+
|
16 |
+
// Only do this if we're on the login page.
|
17 |
+
if ( empty( $pmpro_pages['login'] ) || ! is_page( $pmpro_pages['login'] ) ) {
|
18 |
+
return;
|
19 |
+
}
|
20 |
+
|
21 |
+
// Only do this if the sso module is active.
|
22 |
+
if ( ! Jetpack::is_module_active( 'sso' ) ) {
|
23 |
+
return;
|
24 |
+
}
|
25 |
+
|
26 |
+
$action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'login';
|
27 |
+
|
28 |
+
do_action( 'login_init' );
|
29 |
+
}
|
30 |
+
|
31 |
+
add_action( 'wp', 'pmpro_jetpack_sso_handle_login', 20 );
|
includes/content.php
CHANGED
@@ -81,6 +81,9 @@ function pmpro_has_membership_access($post_id = NULL, $user_id = NULL, $return_m
|
|
81 |
}
|
82 |
else
|
83 |
{
|
|
|
|
|
|
|
84 |
//we need to see if the user has access
|
85 |
foreach($post_membership_levels as $level)
|
86 |
{
|
@@ -144,10 +147,9 @@ function pmpro_search_filter($query)
|
|
144 |
//hide pmpro pages from search results
|
145 |
if( ! $query->is_admin && $query->is_search && empty( $query->query['post_parent'] ) ) {
|
146 |
//avoiding post_parent queries for now
|
147 |
-
if( empty( $query->query_vars['post_parent'] ) ) {
|
148 |
-
$query->set('post__not_in', $pmpro_pages );
|
149 |
}
|
150 |
-
$query->set('post__not_in', $pmpro_pages ); // id of page or post
|
151 |
}
|
152 |
|
153 |
// If this is a post type query, get the queried post types into an array.
|
@@ -223,7 +225,7 @@ function pmpro_search_filter($query)
|
|
223 |
if( $hidden_page_ids ) {
|
224 |
//avoiding post_parent queries for now
|
225 |
if( empty( $query->query_vars['post_parent'] ) ) {
|
226 |
-
$query->set( 'post__not_in', $hidden_page_ids );
|
227 |
}
|
228 |
}
|
229 |
|
@@ -248,7 +250,7 @@ function pmpro_search_filter($query)
|
|
248 |
|
249 |
//make this work
|
250 |
if( $hidden_cat_ids ) {
|
251 |
-
|
252 |
|
253 |
//filter so posts in this member's categories are allowed
|
254 |
add_action( 'posts_where', 'pmpro_posts_where_unhide_cats' );
|
@@ -298,6 +300,16 @@ function pmpro_membership_content_filter( $content, $skipcheck = false ) {
|
|
298 |
$hasaccess = $hasaccess[0];
|
299 |
}
|
300 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
301 |
|
302 |
if( $hasaccess ) {
|
303 |
//all good, return content
|
@@ -313,23 +325,23 @@ function pmpro_membership_content_filter( $content, $skipcheck = false ) {
|
|
313 |
} elseif(strpos($content, "<span id=\"more-" . $post->ID . "\"></span>") !== false) {
|
314 |
//more tag
|
315 |
$pos = strpos($content, "<span id=\"more-" . $post->ID . "\"></span>");
|
316 |
-
$content =
|
317 |
} elseif(strpos($content, 'class="more-link">') !== false) {
|
318 |
//more link
|
319 |
$content = preg_replace("/\<a.*class\=\"more\-link\".*\>.*\<\/a\>/", "", $content);
|
320 |
} elseif(strpos($content, "<!-- wp:more -->") !== false) {
|
321 |
//more block
|
322 |
$pos = strpos($content, "<!-- wp:more -->");
|
323 |
-
$content =
|
324 |
} elseif(strpos($content, "<!--more-->") !== false) {
|
325 |
//more tag
|
326 |
$pos = strpos($content, "<!--more-->");
|
327 |
-
$content =
|
328 |
} else {
|
329 |
//auto generated excerpt. pulled from wp_trim_excerpt
|
330 |
$content = strip_shortcodes( $content );
|
331 |
$content = str_replace(']]>', ']]>', $content);
|
332 |
-
$content =
|
333 |
$excerpt_length = apply_filters('excerpt_length', 55);
|
334 |
$words = preg_split("/[\n\r\t ]+/", $content, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
|
335 |
if ( count($words) > $excerpt_length ) {
|
@@ -381,15 +393,11 @@ add_filter('get_the_excerpt', 'pmpro_membership_get_excerpt_filter_start', 1);
|
|
381 |
add_filter('get_the_excerpt', 'pmpro_membership_get_excerpt_filter_end', 100);
|
382 |
|
383 |
function pmpro_comments_filter($comments, $post_id = NULL) {
|
384 |
-
global $
|
385 |
-
if(!$post_id)
|
386 |
-
$post_id = $post->ID;
|
387 |
|
388 |
if(!$comments)
|
389 |
return $comments; //if they are closed anyway, we don't need to check
|
390 |
|
391 |
-
global $post, $current_user;
|
392 |
-
|
393 |
$hasaccess = pmpro_has_membership_access(NULL, NULL, true);
|
394 |
if( is_array( $hasaccess ) ) {
|
395 |
//returned an array to give us the membership level values
|
@@ -481,7 +489,9 @@ function pmpro_post_classes( $classes, $class, $post_id ) {
|
|
481 |
if( ! empty( $post_levels[1] ) ) {
|
482 |
$classes[] = 'pmpro-level-required';
|
483 |
foreach( $post_levels[1] as $post_level ) {
|
484 |
-
|
|
|
|
|
485 |
}
|
486 |
}
|
487 |
if(!empty($post_levels[0]) && $post_levels[0] == true) {
|
81 |
}
|
82 |
else
|
83 |
{
|
84 |
+
// Reorder the $post_membership_levels to match sorted order.
|
85 |
+
$post_membership_levels = pmpro_sort_levels_by_order( $post_membership_levels );
|
86 |
+
|
87 |
//we need to see if the user has access
|
88 |
foreach($post_membership_levels as $level)
|
89 |
{
|
147 |
//hide pmpro pages from search results
|
148 |
if( ! $query->is_admin && $query->is_search && empty( $query->query['post_parent'] ) ) {
|
149 |
//avoiding post_parent queries for now
|
150 |
+
if( empty( $query->query_vars['post_parent'] ) && ! empty( $pmpro_pages ) ) {
|
151 |
+
$query->set( 'post__not_in', array_merge( $query->get('post__not_in'), array_values( $pmpro_pages ) ) );
|
152 |
}
|
|
|
153 |
}
|
154 |
|
155 |
// If this is a post type query, get the queried post types into an array.
|
225 |
if( $hidden_page_ids ) {
|
226 |
//avoiding post_parent queries for now
|
227 |
if( empty( $query->query_vars['post_parent'] ) ) {
|
228 |
+
$query->set( 'post__not_in', array_merge( $query->get('post__not_in'), $hidden_page_ids ) );
|
229 |
}
|
230 |
}
|
231 |
|
250 |
|
251 |
//make this work
|
252 |
if( $hidden_cat_ids ) {
|
253 |
+
$query->set( 'category__not_in', array_merge( $query->get( 'category__not_in' ), $hidden_cat_ids ) );
|
254 |
|
255 |
//filter so posts in this member's categories are allowed
|
256 |
add_action( 'posts_where', 'pmpro_posts_where_unhide_cats' );
|
300 |
$hasaccess = $hasaccess[0];
|
301 |
}
|
302 |
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Filter to let other plugins change how PMPro filters member content.
|
306 |
+
* If anything other than false is returned, that value will overwrite
|
307 |
+
* the $content variable and no further processing is done in this function.
|
308 |
+
*/
|
309 |
+
$content_filter = apply_filters( 'pmpro_membership_content_filter', false, $content, $hasaccess );
|
310 |
+
if ( $content_filter !== false ) {
|
311 |
+
return $content_filter;
|
312 |
+
}
|
313 |
|
314 |
if( $hasaccess ) {
|
315 |
//all good, return content
|
325 |
} elseif(strpos($content, "<span id=\"more-" . $post->ID . "\"></span>") !== false) {
|
326 |
//more tag
|
327 |
$pos = strpos($content, "<span id=\"more-" . $post->ID . "\"></span>");
|
328 |
+
$content = substr($content, 0, $pos);
|
329 |
} elseif(strpos($content, 'class="more-link">') !== false) {
|
330 |
//more link
|
331 |
$content = preg_replace("/\<a.*class\=\"more\-link\".*\>.*\<\/a\>/", "", $content);
|
332 |
} elseif(strpos($content, "<!-- wp:more -->") !== false) {
|
333 |
//more block
|
334 |
$pos = strpos($content, "<!-- wp:more -->");
|
335 |
+
$content = substr($content, 0, $pos);
|
336 |
} elseif(strpos($content, "<!--more-->") !== false) {
|
337 |
//more tag
|
338 |
$pos = strpos($content, "<!--more-->");
|
339 |
+
$content = substr($content, 0, $pos);
|
340 |
} else {
|
341 |
//auto generated excerpt. pulled from wp_trim_excerpt
|
342 |
$content = strip_shortcodes( $content );
|
343 |
$content = str_replace(']]>', ']]>', $content);
|
344 |
+
$content = wp_strip_all_tags( $content );
|
345 |
$excerpt_length = apply_filters('excerpt_length', 55);
|
346 |
$words = preg_split("/[\n\r\t ]+/", $content, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
|
347 |
if ( count($words) > $excerpt_length ) {
|
393 |
add_filter('get_the_excerpt', 'pmpro_membership_get_excerpt_filter_end', 100);
|
394 |
|
395 |
function pmpro_comments_filter($comments, $post_id = NULL) {
|
396 |
+
global $current_user;
|
|
|
|
|
397 |
|
398 |
if(!$comments)
|
399 |
return $comments; //if they are closed anyway, we don't need to check
|
400 |
|
|
|
|
|
401 |
$hasaccess = pmpro_has_membership_access(NULL, NULL, true);
|
402 |
if( is_array( $hasaccess ) ) {
|
403 |
//returned an array to give us the membership level values
|
489 |
if( ! empty( $post_levels[1] ) ) {
|
490 |
$classes[] = 'pmpro-level-required';
|
491 |
foreach( $post_levels[1] as $post_level ) {
|
492 |
+
if ( isset( $post_level[0] ) ) {
|
493 |
+
$classes[] = 'pmpro-level-' . $post_level[0];
|
494 |
+
}
|
495 |
}
|
496 |
}
|
497 |
if(!empty($post_levels[0]) && $post_levels[0] == true) {
|
includes/currencies.php
CHANGED
@@ -26,7 +26,7 @@
|
|
26 |
'CNY' => __('Chinese Yuan', 'paid-memberships-pro' ),
|
27 |
'CZK' => array(
|
28 |
'name' => __('Czech Koruna', 'paid-memberships-pro' ),
|
29 |
-
'decimals' => '
|
30 |
'thousands_separator' => ' ',
|
31 |
'decimal_separator' => ',',
|
32 |
'symbol' => ' Kč',
|
@@ -99,6 +99,14 @@
|
|
99 |
'TWD' => __('Taiwan New Dollars', 'paid-memberships-pro' ),
|
100 |
'THB' => __('Thai Baht', 'paid-memberships-pro' ),
|
101 |
'TRY' => __('Turkish Lira', 'paid-memberships-pro' ),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
'VND' => array(
|
103 |
'name' => __('Vietnamese Dong', 'paid-memberships-pro' ),
|
104 |
'decimals' => 0,
|
26 |
'CNY' => __('Chinese Yuan', 'paid-memberships-pro' ),
|
27 |
'CZK' => array(
|
28 |
'name' => __('Czech Koruna', 'paid-memberships-pro' ),
|
29 |
+
'decimals' => '2',
|
30 |
'thousands_separator' => ' ',
|
31 |
'decimal_separator' => ',',
|
32 |
'symbol' => ' Kč',
|
99 |
'TWD' => __('Taiwan New Dollars', 'paid-memberships-pro' ),
|
100 |
'THB' => __('Thai Baht', 'paid-memberships-pro' ),
|
101 |
'TRY' => __('Turkish Lira', 'paid-memberships-pro' ),
|
102 |
+
'UAH' => array(
|
103 |
+
'name' => __('Ukrainian Hryvnia (₴)', 'paid-memberships-pro' ),
|
104 |
+
'decimals' => 0,
|
105 |
+
'thousands_separator' => '',
|
106 |
+
'decimal_separator' => ',',
|
107 |
+
'symbol' => '₴',
|
108 |
+
'position' => 'right'
|
109 |
+
),
|
110 |
'VND' => array(
|
111 |
'name' => __('Vietnamese Dong', 'paid-memberships-pro' ),
|
112 |
'decimals' => 0,
|
includes/deprecated.php
CHANGED
@@ -38,7 +38,7 @@ add_action( 'init', 'pmpro_init_check_for_deprecated_filters', 99 );
|
|
38 |
*
|
39 |
*/
|
40 |
function pmpro_getClassForField( $field ) {
|
41 |
-
pmpro_get_element_class( '', $field );
|
42 |
}
|
43 |
|
44 |
/**
|
@@ -52,4 +52,135 @@ function pmpro_admin_init_redirect_old_menu_items() {
|
|
52 |
exit;
|
53 |
}
|
54 |
}
|
55 |
-
add_action( 'init', 'pmpro_admin_init_redirect_old_menu_items' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
*
|
39 |
*/
|
40 |
function pmpro_getClassForField( $field ) {
|
41 |
+
return pmpro_get_element_class( '', $field );
|
42 |
}
|
43 |
|
44 |
/**
|
52 |
exit;
|
53 |
}
|
54 |
}
|
55 |
+
add_action( 'init', 'pmpro_admin_init_redirect_old_menu_items' );
|
56 |
+
|
57 |
+
// Check if installed, deactivate it and show a notice now.
|
58 |
+
function pmpro_check_for_deprecated_add_ons() {
|
59 |
+
|
60 |
+
$deprecated = array(
|
61 |
+
'pmpro-member-history' => array(
|
62 |
+
'file' => 'pmpro-member-history.php',
|
63 |
+
'label' => 'Member History'
|
64 |
+
),
|
65 |
+
'pmpro-email-templates' => array(
|
66 |
+
'file' => 'pmpro-email-templates.php',
|
67 |
+
'label' => 'Email Templates'
|
68 |
+
),
|
69 |
+
'pmpro-email-templates-addon' => array(
|
70 |
+
'file' => 'pmpro-email-templates.php',
|
71 |
+
'label' => 'Email Templates'
|
72 |
+
)
|
73 |
+
);
|
74 |
+
|
75 |
+
$deprecated = apply_filters( 'pmpro_deprecated_add_ons_list', $deprecated );
|
76 |
+
|
77 |
+
// If the list is empty or not an array, just bail.
|
78 |
+
if ( empty( $deprecated ) || ! is_array( $deprecated ) ) {
|
79 |
+
return;
|
80 |
+
}
|
81 |
+
|
82 |
+
$deprecated_active = array();
|
83 |
+
foreach( $deprecated as $key => $values ) {
|
84 |
+
$path = '/' . $key . '/' . $values['file'];
|
85 |
+
if ( file_exists( WP_PLUGIN_DIR . $path ) ) {
|
86 |
+
$deprecated_active[] = $values['label'];
|
87 |
+
|
88 |
+
// Try to deactivate it if it's enabled.
|
89 |
+
if ( is_plugin_active( plugin_basename( $path ) ) ) {
|
90 |
+
deactivate_plugins( $path );
|
91 |
+
}
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
// If any deprecated add ons are active, show warning.
|
96 |
+
if ( is_array( $deprecated_active ) && ! empty( $deprecated_active ) ) {
|
97 |
+
// Only show on certain pages.
|
98 |
+
if ( ! isset( $_REQUEST['page'] ) || strpos( $_REQUEST['page'], 'pmpro' ) === false ) {
|
99 |
+
return;
|
100 |
+
}
|
101 |
+
?>
|
102 |
+
<div class="notice notice-warning">
|
103 |
+
<p>
|
104 |
+
<?php
|
105 |
+
// translators: %s: The list of deprecated plugins that are active.
|
106 |
+
printf(
|
107 |
+
__( 'Some Add Ons are now merged into the Paid Memberships Pro core plugin. The features of the following plugins are now included in PMPro by default. You should <strong>delete these unnecessary plugins</strong> from your site: <em><strong>%s</strong></em>.', 'paid-memberships-pro' ),
|
108 |
+
implode( ', ', $deprecated_active )
|
109 |
+
);
|
110 |
+
?>
|
111 |
+
</p>
|
112 |
+
</div>
|
113 |
+
<?php
|
114 |
+
}
|
115 |
+
}
|
116 |
+
add_action( 'admin_notices', 'pmpro_check_for_deprecated_add_ons' );
|
117 |
+
|
118 |
+
/**
|
119 |
+
* The 2Checkout gateway was deprecated in v2.6.
|
120 |
+
* This code will add it back if it was the selected gateway.
|
121 |
+
* In future versions, we will remove the 2Checkout code entirely.
|
122 |
+
* And you will have to use a stand alone add on for 2Checkout support
|
123 |
+
* or choose a new gateway.
|
124 |
+
*/
|
125 |
+
function pmpro_check_for_deprecated_gateways() {
|
126 |
+
$undprepcated_gateways = (array)pmpro_getOption( 'undeprecated_gateways' );
|
127 |
+
$default_gateway = pmpro_getOption( 'gateway' );
|
128 |
+
|
129 |
+
if ( $default_gateway === 'twocheckout' || in_array( 'twocheckout', $undprepcated_gateways ) ) {
|
130 |
+
require_once( PMPRO_DIR . '/classes/gateways/class.pmprogateway_twocheckout.php' );
|
131 |
+
|
132 |
+
if ( ! in_array( 'twocheckout', $undprepcated_gateways ) ) {
|
133 |
+
$undeprecated_gateways[] = 'twocheckout';
|
134 |
+
pmpro_setOption( 'undeprecated_gateways', $undeprecated_gateways );
|
135 |
+
}
|
136 |
+
}
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Disable uninstall script for duplicates
|
141 |
+
*/
|
142 |
+
function pmpro_disable_uninstall_script_for_duplicates( $file ) {
|
143 |
+
// bail if not a duplicate
|
144 |
+
if ( ! in_array( $file, array_keys( pmpro_get_plugin_duplicates() ) ) ) {
|
145 |
+
return;
|
146 |
+
}
|
147 |
+
|
148 |
+
// disable uninstall script
|
149 |
+
if ( file_exists( WP_PLUGIN_DIR . '/' . dirname( $file ) . '/uninstall.php' ) ) {
|
150 |
+
rename(
|
151 |
+
WP_PLUGIN_DIR . '/' . dirname( $file ) . '/uninstall.php',
|
152 |
+
WP_PLUGIN_DIR . '/' . dirname( $file ) . '/uninstall-disabled.php'
|
153 |
+
);
|
154 |
+
}
|
155 |
+
}
|
156 |
+
add_action( 'pre_uninstall_plugin', 'pmpro_disable_uninstall_script_for_duplicates' );
|
157 |
+
|
158 |
+
/**
|
159 |
+
* @return array
|
160 |
+
*/
|
161 |
+
function pmpro_get_plugin_duplicates() {
|
162 |
+
$all_plugins = get_plugins();
|
163 |
+
$active_plugins_names = get_option( 'active_plugins' );
|
164 |
+
|
165 |
+
$multiple_installations = array();
|
166 |
+
foreach ( $all_plugins as $plugin_name => $plugin_headers ) {
|
167 |
+
// skip all active plugins
|
168 |
+
if ( in_array( $plugin_name, $active_plugins_names ) ) {
|
169 |
+
continue;
|
170 |
+
}
|
171 |
+
|
172 |
+
// skip plugins without a folder
|
173 |
+
if ( false === strpos( $plugin_name, '/' ) ) {
|
174 |
+
continue;
|
175 |
+
}
|
176 |
+
|
177 |
+
// check if plugin file is paid-memberships-pro.php
|
178 |
+
// or Plugin Name: Paid Memberships Pro
|
179 |
+
list( $plugin_folder, $plugin_mainfile_php ) = explode( '/', $plugin_name );
|
180 |
+
if ( 'paid-memberships-pro.php' === $plugin_mainfile_php || 'Paid Memberships Pro' === $plugin_headers['Name'] ) {
|
181 |
+
$multiple_installations[ $plugin_name ] = $plugin_headers;
|
182 |
+
}
|
183 |
+
}
|
184 |
+
|
185 |
+
return $multiple_installations;
|
186 |
+
}
|
includes/email-templates.php
ADDED
@@ -0,0 +1,536 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* File used to setup default email templates data.
|
4 |
+
*/
|
5 |
+
|
6 |
+
global $pmpro_email_templates_defaults;
|
7 |
+
/**
|
8 |
+
* Default email templates.
|
9 |
+
*/
|
10 |
+
$pmpro_email_templates_defaults = array(
|
11 |
+
'default' => array(
|
12 |
+
'subject' => __( "An email from !!sitename!!", 'paid-memberships-pro' ),
|
13 |
+
'description' => __( 'Default Email', 'paid-memberships-pro'),
|
14 |
+
'body' => __( '!!body!!', 'paid-memberships-pro' ),
|
15 |
+
'help_text' => __( 'This email is sent when there is a general message that needs to be communicated to the site administrator.', 'paid-memberships-pro' )
|
16 |
+
),
|
17 |
+
'footer' => array(
|
18 |
+
'subject' => __( '', 'paid-memberships-pro' ),
|
19 |
+
'description' => __( 'Email Footer', 'paid-memberships-pro'),
|
20 |
+
'body' => __( '<p>
|
21 |
+
Respectfully,<br />
|
22 |
+
!!sitename!!
|
23 |
+
</p>', 'paid-memberships-pro' ),
|
24 |
+
'help_text' => __( 'This is the closing message included in every email sent to members and the site administrator through Paid Memberships Pro.', 'paid-memberships-pro' )
|
25 |
+
),
|
26 |
+
'header' => array(
|
27 |
+
'subject' => __( '', 'paid-memberships-pro' ),
|
28 |
+
'description' => __( 'Email Header', 'paid-memberships-pro'),
|
29 |
+
'body' => __( '<p>Dear !!name!!,</p>', 'paid-memberships-pro' ),
|
30 |
+
'help_text' => __( 'This is the opening message included in every email sent to members and the site administrator through Paid Memberships Pro.', 'paid-memberships-pro' )
|
31 |
+
),
|
32 |
+
'admin_change' => array(
|
33 |
+
'subject' => __( "Your membership at !!sitename!! has been changed", 'paid-memberships-pro' ),
|
34 |
+
'description' => __( 'Admin Change', 'paid-memberships-pro'),
|
35 |
+
'body' => __( '<p>An administrator at !!sitename!! has changed your membership level.</p>
|
36 |
+
|
37 |
+
<p>!!membership_change!!</p>
|
38 |
+
|
39 |
+
<p>If you did not request this membership change and would like more information please contact us at !!siteemail!!</p>
|
40 |
+
|
41 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
42 |
+
'help_text' => __( 'The site administrator can manually update a user\'s membership level through the WordPress admin. This email notifies the member of the level update.', 'paid-memberships-pro' )
|
43 |
+
),
|
44 |
+
'admin_change_admin' => array(
|
45 |
+
'subject' => __( "Membership for !!user_login!! at !!sitename!! has been changed", 'paid-memberships-pro' ),
|
46 |
+
'description' => __('Admin Change (admin)', 'paid-memberships-pro'),
|
47 |
+
'body' => __( '<p>An administrator at !!sitename!! has changed a membership level for !!name!!.</p>
|
48 |
+
|
49 |
+
<p>!!membership_change!!</p>
|
50 |
+
|
51 |
+
<p>Log in to your WordPress admin here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
52 |
+
'help_text' => __( 'The site administrator can manually update a user\'s membership level through the WordPress admin. This email notifies the site administrator of the level update.', 'paid-memberships-pro' )
|
53 |
+
),
|
54 |
+
'billable_invoice' => array(
|
55 |
+
'subject' => __( 'Invoice for order #: !!order_code!!', 'paid-memberships-pro' ),
|
56 |
+
'description' => __( 'Billable Invoice', 'paid-membershps-pro' ),
|
57 |
+
'body' => __( '<p>Thank you for your membership to !!sitename!!. Below is your invoice for order #: !!order_code!!</p>
|
58 |
+
|
59 |
+
!!invoice!!
|
60 |
+
|
61 |
+
<p>Log in to your membership account here: !!login_url!!</p>
|
62 |
+
|
63 |
+
<p>To view an online version of this invoice, click here: !!invoice_url!!</p>', 'paid-memberships-pro' ),
|
64 |
+
'help_text' => __( 'The site administrator can manually send a user a copy of this invoice email via the Memberships > Orders admin page.', 'paid-memberships-pro' )
|
65 |
+
),
|
66 |
+
'billing' => array(
|
67 |
+
'subject' => __( "Your billing information has been updated at !!sitename!!", 'paid-memberships-pro' ),
|
68 |
+
'description' => __('Billing', 'paid-memberships-pro'),
|
69 |
+
'body' => __( '<p>Your billing information at !!sitename!! has been changed.</p><p>Account: !!display_name!! (!!user_email!!)</p>
|
70 |
+
<p>
|
71 |
+
Billing Information:<br />
|
72 |
+
!!billing_address!!
|
73 |
+
</p><p>
|
74 |
+
!!cardtype!!: !!accountnumber!!<br />
|
75 |
+
Expires: !!expirationmonth!!/!!expirationyear!!
|
76 |
+
</p><p>If you did not request a billing information change please contact us at !!siteemail!!</p><p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
77 |
+
'help_text' => __( 'Members can update the payment method associated with their recurring subscription. This email is sent to the member as a confirmation of a payment method update.', 'paid-memberships-pro' )
|
78 |
+
),
|
79 |
+
'billing_admin' => array(
|
80 |
+
'subject' => __( "Billing information has been updated for !!user_login!! at !!sitename!!", 'paid-memberships-pro' ),
|
81 |
+
'description' => __('Billing (admin)', 'paid-memberships-pro'),
|
82 |
+
'body' => __( '<p>The billing information for !!display_name!! at !!sitename!! has been changed.</p>
|
83 |
+
|
84 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
85 |
+
<p>
|
86 |
+
Billing Information:<br />
|
87 |
+
!!billing_name!!<br />
|
88 |
+
!!billing_street!!<br />
|
89 |
+
!!billing_city!!, !!billing_state!! !!billing_zip!! !!billing_country!!
|
90 |
+
!!billing_phone!!
|
91 |
+
</p>
|
92 |
+
|
93 |
+
<p>
|
94 |
+
!!cardtype!!: !!accountnumber!!<br />
|
95 |
+
Expires: !!expirationmonth!!/!!expirationyear!!
|
96 |
+
</p>
|
97 |
+
|
98 |
+
<p>Log in to your WordPress dashboard here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
99 |
+
'help_text' => __( 'Members can update the payment method associated with their recurring subscription. This email is sent to the site administrator as a confirmation of a payment method update.', 'paid-memberships-pro' )
|
100 |
+
),
|
101 |
+
'billing_failure' => array(
|
102 |
+
'subject' => __( "Membership payment failed at !!sitename!!", 'paid-memberships-pro' ),
|
103 |
+
'description' => __('Billing Failure', 'paid-memberships-pro'),
|
104 |
+
'body' => __( '<p>The current subscription payment for your !!sitename!! membership has failed. <strong>Please click the following link to log in and update your billing information to avoid account suspension. !!login_url!!</strong></p>
|
105 |
+
|
106 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>', 'paid-memberships-pro' ),
|
107 |
+
'help_text' => __( 'This email is sent out if a recurring payment has failed, usually due to an expired or cancelled credit card. This email is sent to the member to allowing them time to update payment information without a disruption in access to your site.', 'paid-memberships-pro' )
|
108 |
+
),
|
109 |
+
'billing_failure_admin' => array(
|
110 |
+
'subject' => __( "Membership payment failed for !!display_name!! at !!sitename!!", 'paid-memberships-pro' ),
|
111 |
+
'description' => __('Billing Failure (admin)', 'paid-memberships-pro'),
|
112 |
+
'body' => __( '<p>The subscription payment for !!user_login!! at !!sitename!! has failed.</p>
|
113 |
+
|
114 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
115 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
116 |
+
|
117 |
+
<p>Log in to your WordPress admin here: !!login_url!!</p>
|
118 |
+
', 'paid-memberships-pro' ),
|
119 |
+
'help_text' => __( 'This email is sent out if a recurring payment has failed for a member, usually due to an expired or cancelled credit card. This email is sent to the site administrator.', 'paid-memberships-pro' )
|
120 |
+
),
|
121 |
+
'cancel' => array(
|
122 |
+
'subject' => __( "Your membership at !!sitename!! has been CANCELLED", 'paid-memberships-pro' ),
|
123 |
+
'description' => __('Cancel', 'paid-memberships-pro'),
|
124 |
+
'body' => __( '<p>Your membership at !!sitename!! has been cancelled.</p>
|
125 |
+
|
126 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
127 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
128 |
+
|
129 |
+
<p>If you did not request this cancellation and would like more information please contact us at !!siteemail!!</p>', 'paid-memberships-pro' ),
|
130 |
+
'help_text' => __( 'The site administrator can manually cancel a user\'s membership through the WordPress admin or the member can cancel their own membership through your site. This email is sent to the member as confirmation of a cancelled membership.', 'paid-memberships-pro' )
|
131 |
+
),
|
132 |
+
'cancel_admin' => array(
|
133 |
+
'subject' => __( "Membership for !!user_login!! at !!sitename!! has been CANCELLED", 'paid-memberships-pro' ),
|
134 |
+
'description' => __('Cancel (admin)', 'paid-memberships-pro'),
|
135 |
+
'body' => __( '<p>The membership for !!user_login!! at !!sitename!! has been cancelled.</p>
|
136 |
+
|
137 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
138 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
139 |
+
<p>Start Date: !!startdate!!</p>
|
140 |
+
<p>End Date: !!enddate!!</p>
|
141 |
+
|
142 |
+
<p>Log in to your WordPress admin here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
143 |
+
'help_text' => __( 'The site administrator can manually cancel a user\'s membership through the WordPress admin or the member can cancel their own membership through your site. This email is sent to the site administrator as confirmation of a cancelled membership.', 'paid-memberships-pro' )
|
144 |
+
),
|
145 |
+
'checkout_check' => array(
|
146 |
+
'subject' => __( "Your membership confirmation for !!sitename!!", 'paid-memberships-pro' ),
|
147 |
+
'description' => __('Checkout - Check', 'paid-memberships-pro'),
|
148 |
+
'body' => __( '<p>Thank you for your membership to !!sitename!!. Your membership account is now active.</p>
|
149 |
+
|
150 |
+
!!membership_level_confirmation_message!!
|
151 |
+
|
152 |
+
!!instructions!!
|
153 |
+
|
154 |
+
<p>Below are details about your membership account and a receipt for your initial membership invoice.</p>
|
155 |
+
|
156 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
157 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
158 |
+
<p>Membership Fee: !!membership_cost!!</p>
|
159 |
+
!!membership_expiration!! !!discount_code!!
|
160 |
+
|
161 |
+
<p>
|
162 |
+
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
163 |
+
Total Billed: !!invoice_total!!
|
164 |
+
</p>
|
165 |
+
|
166 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
167 |
+
'help_text' => __( 'This is a membership confirmation welcome email sent to a new member or to existing members that change their level using the "Pay by Check" gateway.', 'paid-memberships-pro' )
|
168 |
+
),
|
169 |
+
'checkout_check_admin' => array(
|
170 |
+
'subject' => __( "Member checkout for !!membership_level_name!! at !!sitename!!", 'paid-memberships-pro' ),
|
171 |
+
'description' => __('Checkout - Check (admin)', 'paid-memberships-pro'),
|
172 |
+
'body' => __( '<p>There was a new member checkout at !!sitename!!.</p>
|
173 |
+
|
174 |
+
<p><strong>They have chosen to pay by check.</strong></p>
|
175 |
+
|
176 |
+
<p>Below are details about the new membership account and a receipt for the initial membership invoice.</p>
|
177 |
+
|
178 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
179 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
180 |
+
<p>Membership Fee: !!membership_cost!!</p>
|
181 |
+
!!membership_expiration!! !!discount_code!!
|
182 |
+
|
183 |
+
<p>
|
184 |
+
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
185 |
+
Total Billed: !!invoice_total!!
|
186 |
+
</p>
|
187 |
+
|
188 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
189 |
+
'help_text' => __( 'This is the membership confirmation email sent to the site administrator for every membership checkout using the "Pay by Check" gateway.', 'paid-memberships-pro' )
|
190 |
+
),
|
191 |
+
'checkout_express' => array(
|
192 |
+
'subject' => __( "Your membership confirmation for !!sitename!!", 'paid-memberships-pro' ),
|
193 |
+
'description' => __('Checkout - PayPal Express', 'paid-memberships-pro'),
|
194 |
+
'body' => __( '<p>Thank you for your membership to !!sitename!!. Your membership account is now active.</p>
|
195 |
+
!!membership_level_confirmation_message!!
|
196 |
+
<p>Below are details about your membership account and a receipt for your initial membership invoice.</p>
|
197 |
+
|
198 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
199 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
200 |
+
<p>Membership Fee: !!membership_cost!!</p>
|
201 |
+
!!membership_expiration!! !!discount_code!!
|
202 |
+
|
203 |
+
<p>
|
204 |
+
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
205 |
+
Total Billed: !!invoice_total!!
|
206 |
+
</p>
|
207 |
+
|
208 |
+
<p>Log in to your membership account here: !!login_url!!</p>
|
209 |
+
', 'paid-memberships-pro' ),
|
210 |
+
'help_text' => __( 'This is a membership confirmation welcome email sent to a new member or to existing members that change their level using the "PayPal Express" gateway.', 'paid-memberships-pro' )
|
211 |
+
|
212 |
+
),
|
213 |
+
'checkout_express_admin' => array(
|
214 |
+
'subject' => __( "Member checkout for !!membership_level_name!! at !!sitename!!", 'paid-memberships-pro' ),
|
215 |
+
'description' => __('Checkout - PayPal Express (admin)', 'paid-memberships-pro'),
|
216 |
+
'body' => __( '<p>There was a new member checkout at !!sitename!!.</p>
|
217 |
+
<p>Below are details about the new membership account and a receipt for the initial membership invoice.</p>
|
218 |
+
|
219 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
220 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
221 |
+
<p>Membership Fee: !!membership_cost!!</p>
|
222 |
+
!!membership_expiration!! !!discount_code!!
|
223 |
+
|
224 |
+
<p>
|
225 |
+
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
226 |
+
Total Billed: !!invoice_total!!
|
227 |
+
</p>
|
228 |
+
|
229 |
+
<p>Log in to your membership account here: !!login_url!!</p>
|
230 |
+
', 'paid-memberships-pro' ),
|
231 |
+
'help_text' => __( 'This is the membership confirmation email sent to the site administrator for every membership checkout using the "PayPal Express" gateway.', 'paid-memberships-pro' )
|
232 |
+
),
|
233 |
+
'checkout_free' => array(
|
234 |
+
'subject' => __( "Your membership confirmation for !!sitename!!", 'paid-memberships-pro' ),
|
235 |
+
'description' => __('Checkout - Free', 'paid-memberships-pro'),
|
236 |
+
'body' => __( '<p>Thank you for your membership to !!sitename!!. Your membership account is now active.</p>
|
237 |
+
!!membership_level_confirmation_message!!
|
238 |
+
<p>Below are details about your membership account.</p>
|
239 |
+
|
240 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
241 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
242 |
+
!!membership_expiration!! !!discount_code!!
|
243 |
+
|
244 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
245 |
+
'help_text' => __( 'This is a membership confirmation welcome email sent to a new member or to existing members that change their level when the level has no charge.', 'paid-memberships-pro' )
|
246 |
+
),
|
247 |
+
'checkout_free_admin' => array(
|
248 |
+
'subject' => __( "Member checkout for !!membership_level_name!! at !!sitename!!", 'paid-memberships-pro' ),
|
249 |
+
'description' => __('Checkout - Free (admin)', 'paid-memberships-pro'),
|
250 |
+
'body' => __( '<p>There was a new member checkout at !!sitename!!.</p>
|
251 |
+
<p>Below are details about the new membership account.</p>
|
252 |
+
|
253 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
254 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
255 |
+
!!membership_expiration!! !!discount_code!!
|
256 |
+
|
257 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
258 |
+
'help_text' => __( 'This is the membership confirmation email sent to the site administrator for every membership checkout that has no charge.', 'paid-memberships-pro' )
|
259 |
+
),
|
260 |
+
'checkout_freetrial' => array(
|
261 |
+
'subject' => __( "Your membership confirmation for !!sitename!!", 'paid-memberships-pro' ),
|
262 |
+
'description' => __('Checkout - Free Trial', 'paid-memberships-pro'),
|
263 |
+
'body' => __( '<p>Thank you for your membership to !!sitename!!. Your membership account is now active.</p>
|
264 |
+
!!membership_level_confirmation_message!!
|
265 |
+
<p>Below are details about your membership account.</p>
|
266 |
+
|
267 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
268 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
269 |
+
<p>Membership Fee: !!membership_cost!!</p>
|
270 |
+
!!membership_expiration!! !!discount_code!!
|
271 |
+
|
272 |
+
<p>
|
273 |
+
Billing Information on File:<br />
|
274 |
+
!!billing_address!!
|
275 |
+
</p>
|
276 |
+
|
277 |
+
<p>
|
278 |
+
!!cardtype!!: !!accountnumber!!<br />
|
279 |
+
Expires: !!expirationmonth!!/!!expirationyear!!
|
280 |
+
</p>
|
281 |
+
|
282 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
283 |
+
'help_text' => __( 'This is a membership confirmation welcome email sent to a new member or to existing members that change their level with a trial period.', 'paid-memberships-pro' )
|
284 |
+
),
|
285 |
+
'checkout_freetrial_admin' => array(
|
286 |
+
'subject' => __( "Member checkout for !!membership_level_name!! at !!sitename!!", 'paid-memberships-pro' ),
|
287 |
+
'description' => __('Checkout - Free Trial (admin)', 'paid-memberships-pro'),
|
288 |
+
'body' => __( '<p>There was a new member checkout at !!sitename!!.</p>
|
289 |
+
<p>Below are details about the new membership account and a receipt for the initial membership invoice.</p>
|
290 |
+
|
291 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
292 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
293 |
+
<p>Membership Fee: !!membership_cost!!</p>
|
294 |
+
!!membership_expiration!! !!discount_code!!
|
295 |
+
|
296 |
+
<p>
|
297 |
+
Billing Information on File:<br />
|
298 |
+
!!billing_address!!
|
299 |
+
</p>
|
300 |
+
|
301 |
+
<p>
|
302 |
+
!!cardtype!!: !!accountnumber!!<br />
|
303 |
+
Expires: !!expirationmonth!!/!!expirationyear!!
|
304 |
+
</p>
|
305 |
+
|
306 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
307 |
+
'help_text' => __( 'This is the membership confirmation email sent to the site administrator for every membership checkout with a trial period.', 'paid-memberships-pro' )
|
308 |
+
),
|
309 |
+
'checkout_paid' => array(
|
310 |
+
'subject' => __( "Your membership confirmation for !!sitename!!", 'paid-memberships-pro' ),
|
311 |
+
'description' => __('Checkout - Paid', 'paid-memberships-pro'),
|
312 |
+
'body' => __( '<p>Thank you for your membership to !!sitename!!. Your membership account is now active.</p>
|
313 |
+
!!membership_level_confirmation_message!!
|
314 |
+
<p>Below are details about your membership account and a receipt for your initial membership invoice.</p>
|
315 |
+
|
316 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
317 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
318 |
+
<p>Membership Fee: !!membership_cost!!</p>
|
319 |
+
!!membership_expiration!! !!discount_code!!
|
320 |
+
|
321 |
+
<p>
|
322 |
+
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
323 |
+
Total Billed: !!invoice_total!!
|
324 |
+
</p>
|
325 |
+
<p>
|
326 |
+
Billing Information:<br />
|
327 |
+
!!billing_address!!
|
328 |
+
</p>
|
329 |
+
|
330 |
+
<p>
|
331 |
+
!!cardtype!!: !!accountnumber!!<br />
|
332 |
+
Expires: !!expirationmonth!!/!!expirationyear!!
|
333 |
+
</p>
|
334 |
+
|
335 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
336 |
+
'help_text' => __( 'This is a membership confirmation welcome email sent to a new member or to existing members that change their level and complete a paid checkout on the site.', 'paid-memberships-pro' )
|
337 |
+
),
|
338 |
+
'checkout_paid_admin' => array(
|
339 |
+
'subject' => __( "Member checkout for !!membership_level_name!! at !!sitename!!", 'paid-memberships-pro' ),
|
340 |
+
'description' => __('Checkout - Paid (admin)', 'paid-memberships-pro'),
|
341 |
+
'body' => __( '<p>There was a new member checkout at !!sitename!!.</p>
|
342 |
+
<p>Below are details about the new membership account and a receipt for the initial membership invoice.</p>
|
343 |
+
|
344 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
345 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
346 |
+
<p>Membership Fee: !!membership_cost!!</p>
|
347 |
+
!!membership_expiration!! !!discount_code!!
|
348 |
+
|
349 |
+
<p>
|
350 |
+
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
351 |
+
Total Billed: !!invoice_total!!
|
352 |
+
</p>
|
353 |
+
<p>
|
354 |
+
Billing Information:<br />
|
355 |
+
!!billing_address!!
|
356 |
+
</p>
|
357 |
+
|
358 |
+
<p>
|
359 |
+
!!cardtype!!: !!accountnumber!!<br />
|
360 |
+
Expires: !!expirationmonth!!/!!expirationyear!!
|
361 |
+
</p>
|
362 |
+
|
363 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
364 |
+
'help_text' => __( 'This is the membership confirmation email sent to the site administrator for every paid membership checkout on the site.', 'paid-memberships-pro' )
|
365 |
+
),
|
366 |
+
'checkout_trial' => array(
|
367 |
+
'subject' => __( "Your membership confirmation for !!sitename!!", 'paid-memberships-pro' ),
|
368 |
+
'description' => __('Checkout - Trial', 'paid-memberships-pro'),
|
369 |
+
'body' => __( '<p>Thank you for your membership to !!sitename!!. Your membership account is now active.</p>
|
370 |
+
!!membership_level_confirmation_message!!
|
371 |
+
<p>Below are details about your membership account and a receipt for your initial membership invoice.</p>
|
372 |
+
|
373 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
374 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
375 |
+
<p>Membership Fee: !!membership_cost!!</p>
|
376 |
+
!!membership_expiration!! !!discount_code!!
|
377 |
+
|
378 |
+
<p>
|
379 |
+
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
380 |
+
Total Billed: !!invoice_total!!
|
381 |
+
</p>
|
382 |
+
<p>
|
383 |
+
Billing Information:<br />
|
384 |
+
!!billing_address!!
|
385 |
+
</p>
|
386 |
+
|
387 |
+
<p>
|
388 |
+
!!cardtype!!: !!accountnumber!!<br />
|
389 |
+
Expires: !!expirationmonth!!/!!expirationyear!!
|
390 |
+
</p>
|
391 |
+
|
392 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
393 |
+
'help_text' => __( 'This is a membership confirmation welcome email sent to a new member or to existing members that change their level with a trial period.', 'paid-memberships-pro' )
|
394 |
+
),
|
395 |
+
'checkout_trial_admin' => array(
|
396 |
+
'subject' => __( "Member checkout for !!membership_level_name!! at !!sitename!!", 'paid-memberships-pro' ),
|
397 |
+
'description' => __('Checkout - Trial (admin)', 'paid-memberships-pro'),
|
398 |
+
'body' => __( '<p>There was a new member checkout at !!sitename!!.</p>
|
399 |
+
<p>Below are details about the new membership account and a receipt for the initial membership invoice.</p>
|
400 |
+
|
401 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
402 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
403 |
+
<p>Membership Fee: !!membership_cost!!</p>
|
404 |
+
!!membership_expiration!! !!discount_code!!
|
405 |
+
|
406 |
+
<p>
|
407 |
+
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
408 |
+
Total Billed: !!invoice_total!!
|
409 |
+
</p>
|
410 |
+
<p>
|
411 |
+
Billing Information:<br />
|
412 |
+
!!billing_address!!
|
413 |
+
</p>
|
414 |
+
|
415 |
+
<p>
|
416 |
+
!!cardtype!!: !!accountnumber!!<br />
|
417 |
+
Expires: !!expirationmonth!!/!!expirationyear!!
|
418 |
+
</p>
|
419 |
+
|
420 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
421 |
+
'help_text' => __( 'This is the membership confirmation email sent to the site administrator for every membership checkout with a trial period.', 'paid-memberships-pro' )
|
422 |
+
),
|
423 |
+
'credit_card_expiring' => array(
|
424 |
+
'subject' => __( "Credit card on file expiring soon at !!sitename!!", 'paid-memberships-pro' ),
|
425 |
+
'description' => __('Credit Card Expiring', 'paid-memberships-pro'),
|
426 |
+
'body' => __( '<p>The payment method used for your membership at !!sitename!! will expire soon. <strong>Please click the following link to log in and update your billing information to avoid account suspension. !!login_url!!</strong></p>
|
427 |
+
|
428 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
429 |
+
<p>The most recent account information we have on file is:</p>
|
430 |
+
|
431 |
+
<p>!!billing_name!!</br />
|
432 |
+
!!billing_address!!
|
433 |
+
</p>
|
434 |
+
|
435 |
+
<p>
|
436 |
+
!!cardtype!!: !!accountnumber!!<br />
|
437 |
+
Expires: !!expirationmonth!!/!!expirationyear!!
|
438 |
+
</p>', 'paid-memberships-pro' ),
|
439 |
+
'help_text' => __( 'This email is sent when a member\'s payment method will be expiring soon. This allows the member to update their payment method before a payment failure, which may result in lost access to member features.', 'paid-memberships-pro' )
|
440 |
+
),
|
441 |
+
'invoice' => array(
|
442 |
+
'subject' => __( "Invoice for !!sitename!! membership", 'paid-memberships-pro' ),
|
443 |
+
'description' => __('Invoice', 'paid-memberships-pro'),
|
444 |
+
'body' => __( '<p>Thank you for your membership to !!sitename!!. Below is a receipt for your most recent membership invoice.</p>
|
445 |
+
|
446 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
447 |
+
<p>
|
448 |
+
Invoice #!!invoice_id!! on !!invoice_date!!<br />
|
449 |
+
Total Billed: !!invoice_total!!
|
450 |
+
</p>
|
451 |
+
<p>
|
452 |
+
Billing Information:<br />
|
453 |
+
!!billing_address!!
|
454 |
+
</p>
|
455 |
+
|
456 |
+
<p>
|
457 |
+
!!cardtype!!: !!accountnumber!!<br />
|
458 |
+
Expires: !!expirationmonth!!/!!expirationyear!!
|
459 |
+
</p>
|
460 |
+
|
461 |
+
<p>Log in to your membership account here: !!login_url!!</p>
|
462 |
+
<p>To view an online version of this invoice, click here: !!invoice_url!!</p>', 'paid-memberships-pro' ),
|
463 |
+
'help_text' => __( 'This email is sent to the member each time a new subscription payment is made.', 'paid-memberships-pro' )
|
464 |
+
),
|
465 |
+
'membership_expired' => array(
|
466 |
+
'subject' => __( "Your membership at !!sitename!! has ended", 'paid-memberships-pro' ),
|
467 |
+
'description' => __('Membership Expired', 'paid-memberships-pro'),
|
468 |
+
'body' => __( '<p>Your membership at !!sitename!! has ended.</p>
|
469 |
+
|
470 |
+
<p>Thank you for your support.</p>
|
471 |
+
|
472 |
+
<p>View our current membership offerings here: !!levels_url!!</p>
|
473 |
+
|
474 |
+
<p>Log in to manage your account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
475 |
+
'help_text' => __( 'This email is sent to the member when their membership expires.', 'paid-memberships-pro' )
|
476 |
+
),
|
477 |
+
'membership_expiring' => array(
|
478 |
+
'subject' => __( "Your membership at !!sitename!! will end soon", 'paid-memberships-pro' ),
|
479 |
+
'description' => __('Membership Expiring', 'paid-memberships-pro'),
|
480 |
+
'body' => __( '<p>Thank you for your membership to !!sitename!!. This is just a reminder that your membership will end on !!enddate!!.</p>
|
481 |
+
|
482 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
483 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
484 |
+
|
485 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
486 |
+
'help_text' => __( 'This email is sent to the member when their expiration date is approaching, at an interval based on the term of the membership.', 'paid-memberships-pro' )
|
487 |
+
),
|
488 |
+
'trial_ending' => array(
|
489 |
+
'subject' => __( "Your trial at !!sitename!! is ending soon", 'paid-memberships-pro' ),
|
490 |
+
'description' => __('Trial Ending', 'paid-memberships-pro'),
|
491 |
+
'body' => __( '<p>Thank you for your membership to !!sitename!!. Your trial period is ending on !!trial_end!!.</p>
|
492 |
+
|
493 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
494 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
495 |
+
|
496 |
+
<p>Your fee will be changing from !!trial_amount!! to !!billing_amount!! every !!cycle_number!! !!cycle_period!!(s).</p>
|
497 |
+
|
498 |
+
<p>Log in to your membership account here: !!login_url!!</p>', 'paid-memberships-pro' ),
|
499 |
+
'help_text' => __( 'This email is sent to the member when the trial portion of their membership level is approaching, at an interval based on the term of the trial.', 'paid-memberships-pro' )
|
500 |
+
),
|
501 |
+
|
502 |
+
);
|
503 |
+
|
504 |
+
// add SCA payment action required emails if we're using PMPro 2.1 or later
|
505 |
+
if( defined( 'PMPRO_VERSION' ) && version_compare( PMPRO_VERSION, '2.1' ) >= 0 ) {
|
506 |
+
$pmpro_email_templates_defaults = array_merge( $pmpro_email_templates_defaults, array(
|
507 |
+
'payment_action' => array(
|
508 |
+
'subject' => __( "Payment action required for your !!sitename!! membership", 'paid-memberships-pro' ),
|
509 |
+
'description' => __('Payment Action Required', 'paid-memberships-pro' ),
|
510 |
+
'body' => __( '<p>Customer authentication is required to finish setting up your subscription at !!sitename!!.</p>
|
511 |
+
|
512 |
+
<p>Please complete the verification steps issued by your payment provider at the following link:</p>
|
513 |
+
<p>!!invoice_url!!</p>', 'paid-memberships-pro' ),
|
514 |
+
'help_text' => __( 'This email is sent to the user when an attempted membership checkout requires additional customer authentication.', 'paid-memberships-pro' )
|
515 |
+
),
|
516 |
+
'payment_action_admin' => array(
|
517 |
+
'subject' => __( "Payment action required: membership for !!user_login!! at !!sitename!!", 'paid-memberships-pro' ),
|
518 |
+
'description' => __('Payment Action Required (admin)', 'paid-memberships-pro'),
|
519 |
+
'body' => __( '<p>A payment at !!sitename!! for !!user_login!! requires additional customer authentication to complete.</p>
|
520 |
+
<p>Below is a copy of the email we sent to !!user_email!! to notify them that they need to complete their payment:</p>
|
521 |
+
|
522 |
+
<p>Customer authentication is required to finish setting up your subscription at !!sitename!!.</p>
|
523 |
+
|
524 |
+
<p>Please complete the verification steps issued by your payment provider at the following link:</p>
|
525 |
+
<p>!!invoice_url!!</p>', 'paid-memberships-pro' ),
|
526 |
+
'help_text' => __( 'This email is sent to the site administrator when an attempted membership checkout requires additional customer authentication.', 'paid-memberships-pro' )
|
527 |
+
)
|
528 |
+
));
|
529 |
+
}
|
530 |
+
|
531 |
+
/**
|
532 |
+
* Filter default template settings and add new templates.
|
533 |
+
*
|
534 |
+
* @since 0.5.7
|
535 |
+
*/
|
536 |
+
$pmpro_email_templates_defaults = apply_filters( 'pmproet_templates', $pmpro_email_templates_defaults );
|
includes/email.php
CHANGED
@@ -1,4 +1,7 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
2 |
/**
|
3 |
* The default name for WP emails is WordPress.
|
4 |
* Use our setting instead.
|
@@ -6,15 +9,15 @@
|
|
6 |
function pmpro_wp_mail_from_name($from_name)
|
7 |
{
|
8 |
$default_from_name = 'WordPress';
|
9 |
-
|
10 |
//make sure it's the default from name
|
11 |
if($from_name == $default_from_name)
|
12 |
-
{
|
13 |
$pmpro_from_name = pmpro_getOption("from_name");
|
14 |
if ($pmpro_from_name)
|
15 |
$from_name = stripslashes($pmpro_from_name);
|
16 |
}
|
17 |
-
|
18 |
return $from_name;
|
19 |
}
|
20 |
|
@@ -30,15 +33,15 @@ function pmpro_wp_mail_from($from_email)
|
|
30 |
$sitename = substr( $sitename, 4 );
|
31 |
}
|
32 |
$default_from_email = 'wordpress@' . $sitename;
|
33 |
-
|
34 |
//make sure it's the default email address
|
35 |
if($from_email == $default_from_email)
|
36 |
-
{
|
37 |
$pmpro_from_email = pmpro_getOption("from_email");
|
38 |
if ($pmpro_from_email && is_email( $pmpro_from_email ) )
|
39 |
$from_email = $pmpro_from_email;
|
40 |
}
|
41 |
-
|
42 |
return $from_email;
|
43 |
}
|
44 |
|
@@ -63,22 +66,22 @@ if(empty($email_member_notification))
|
|
63 |
* Adds template files and changes content type to html if using PHPMailer directly.
|
64 |
*/
|
65 |
function pmpro_send_html( $phpmailer ) {
|
66 |
-
|
67 |
//to check if we should wpautop later
|
68 |
$original_body = $phpmailer->Body;
|
69 |
-
|
70 |
// Set the original plain text message
|
71 |
$phpmailer->AltBody = wp_specialchars_decode($phpmailer->Body, ENT_QUOTES);
|
72 |
// Clean < and > around text links in WP 3.1
|
73 |
-
$phpmailer->Body = preg_replace('#<(https?://[^*]+)>#', '$1', $phpmailer->Body);
|
74 |
-
|
75 |
-
// If there is no HTML, run through wpautop
|
76 |
if($phpmailer->Body == strip_tags($phpmailer->Body))
|
77 |
$phpmailer->Body = wpautop($phpmailer->Body);
|
78 |
-
|
79 |
// Convert line breaks & make links clickable
|
80 |
$phpmailer->Body = make_clickable ($phpmailer->Body);
|
81 |
-
|
82 |
// Get header for message if found
|
83 |
if(file_exists(get_stylesheet_directory() . "/email_header.html"))
|
84 |
$header = file_get_contents(get_stylesheet_directory() . "/email_header.html");
|
@@ -86,11 +89,11 @@ function pmpro_send_html( $phpmailer ) {
|
|
86 |
$header = file_get_contents(get_template_directory() . "/email_header.html");
|
87 |
else
|
88 |
$header = "";
|
89 |
-
|
90 |
//wpautop header if needed
|
91 |
if(!empty($header) && $header == strip_tags($header))
|
92 |
$header = wpautop($header);
|
93 |
-
|
94 |
// Get footer for message if found
|
95 |
if(file_exists(get_stylesheet_directory() . "/email_footer.html"))
|
96 |
$footer = file_get_contents(get_stylesheet_directory() . "/email_footer.html");
|
@@ -98,7 +101,7 @@ function pmpro_send_html( $phpmailer ) {
|
|
98 |
$footer = file_get_contents(get_template_directory() . "/email_footer.html");
|
99 |
else
|
100 |
$footer = "";
|
101 |
-
|
102 |
//wpautop header if needed
|
103 |
if(!empty($footer) && $footer == strip_tags($footer))
|
104 |
$footer = wpautop($footer);
|
@@ -111,13 +114,14 @@ function pmpro_send_html( $phpmailer ) {
|
|
111 |
$phpmailer->Body = $header . "\n" . $phpmailer->Body;
|
112 |
if(!empty($footer))
|
113 |
$phpmailer->Body = $phpmailer->Body . "\n" . $footer;
|
114 |
-
|
115 |
// Replace variables in email
|
116 |
global $current_user;
|
117 |
$data = array(
|
118 |
"name" => $current_user->display_name,
|
119 |
"sitename" => get_option("blogname"),
|
120 |
"login_link" => pmpro_url("account"),
|
|
|
121 |
"display_name" => $current_user->display_name,
|
122 |
"user_email" => $current_user->user_email,
|
123 |
"subject" => $phpmailer->Subject
|
@@ -125,8 +129,8 @@ function pmpro_send_html( $phpmailer ) {
|
|
125 |
foreach($data as $key => $value)
|
126 |
{
|
127 |
$phpmailer->Body = str_replace("!!" . $key . "!!", $value, $phpmailer->Body);
|
128 |
-
}
|
129 |
-
|
130 |
do_action("pmpro_after_phpmailer_init", $phpmailer);
|
131 |
do_action("pmpro_after_pmpmailer_init", $phpmailer); //typo left in for backwards compatibility
|
132 |
}
|
@@ -134,14 +138,14 @@ function pmpro_send_html( $phpmailer ) {
|
|
134 |
/**
|
135 |
* Change the content type of emails to HTML.
|
136 |
*/
|
137 |
-
function pmpro_wp_mail_content_type( $content_type ) {
|
138 |
add_action('phpmailer_init', 'pmpro_send_html');
|
139 |
|
140 |
// Change to html if not already.
|
141 |
-
if( $content_type == 'text/plain') {
|
142 |
$content_type = 'text/html';
|
143 |
}
|
144 |
-
|
145 |
return $content_type;
|
146 |
}
|
147 |
add_filter('wp_mail_content_type', 'pmpro_wp_mail_content_type');
|
@@ -152,15 +156,442 @@ add_filter('wp_mail_content_type', 'pmpro_wp_mail_content_type');
|
|
152 |
* We check if there are already <br /> tags before running nl2br.
|
153 |
* Running make_clickable() multiple times has no effect.
|
154 |
*/
|
155 |
-
function pmpro_retrieve_password_message( $message ) {
|
156 |
-
if ( has_filter( 'wp_mail_content_type', 'pmpro_wp_mail_content_type' ) ) {
|
157 |
$message = make_clickable( $message );
|
158 |
-
|
159 |
-
if ( strpos( '<br
|
160 |
$message = nl2br( $message );
|
161 |
-
}
|
162 |
-
}
|
163 |
|
164 |
return $message;
|
165 |
}
|
166 |
-
add_filter( 'retrieve_password_message', 'pmpro_retrieve_password_message', 10, 1 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<?php
|
2 |
+
// Sanitize all PMPro email bodies. @since 2.6.1
|
3 |
+
add_filter( 'pmpro_email_body', 'pmpro_kses', 11 );
|
4 |
+
|
5 |
/**
|
6 |
* The default name for WP emails is WordPress.
|
7 |
* Use our setting instead.
|
9 |
function pmpro_wp_mail_from_name($from_name)
|
10 |
{
|
11 |
$default_from_name = 'WordPress';
|
12 |
+
|
13 |
//make sure it's the default from name
|
14 |
if($from_name == $default_from_name)
|
15 |
+
{
|
16 |
$pmpro_from_name = pmpro_getOption("from_name");
|
17 |
if ($pmpro_from_name)
|
18 |
$from_name = stripslashes($pmpro_from_name);
|
19 |
}
|
20 |
+
|
21 |
return $from_name;
|
22 |
}
|
23 |
|
33 |
$sitename = substr( $sitename, 4 );
|
34 |
}
|
35 |
$default_from_email = 'wordpress@' . $sitename;
|
36 |
+
|
37 |
//make sure it's the default email address
|
38 |
if($from_email == $default_from_email)
|
39 |
+
{
|
40 |
$pmpro_from_email = pmpro_getOption("from_email");
|
41 |
if ($pmpro_from_email && is_email( $pmpro_from_email ) )
|
42 |
$from_email = $pmpro_from_email;
|
43 |
}
|
44 |
+
|
45 |
return $from_email;
|
46 |
}
|
47 |
|
66 |
* Adds template files and changes content type to html if using PHPMailer directly.
|
67 |
*/
|
68 |
function pmpro_send_html( $phpmailer ) {
|
69 |
+
|
70 |
//to check if we should wpautop later
|
71 |
$original_body = $phpmailer->Body;
|
72 |
+
|
73 |
// Set the original plain text message
|
74 |
$phpmailer->AltBody = wp_specialchars_decode($phpmailer->Body, ENT_QUOTES);
|
75 |
// Clean < and > around text links in WP 3.1
|
76 |
+
$phpmailer->Body = preg_replace('#<(https?://[^*]+)>#', '$1', $phpmailer->Body);
|
77 |
+
|
78 |
+
// If there is no HTML, run through wpautop
|
79 |
if($phpmailer->Body == strip_tags($phpmailer->Body))
|
80 |
$phpmailer->Body = wpautop($phpmailer->Body);
|
81 |
+
|
82 |
// Convert line breaks & make links clickable
|
83 |
$phpmailer->Body = make_clickable ($phpmailer->Body);
|
84 |
+
|
85 |
// Get header for message if found
|
86 |
if(file_exists(get_stylesheet_directory() . "/email_header.html"))
|
87 |
$header = file_get_contents(get_stylesheet_directory() . "/email_header.html");
|
89 |
$header = file_get_contents(get_template_directory() . "/email_header.html");
|
90 |
else
|
91 |
$header = "";
|
92 |
+
|
93 |
//wpautop header if needed
|
94 |
if(!empty($header) && $header == strip_tags($header))
|
95 |
$header = wpautop($header);
|
96 |
+
|
97 |
// Get footer for message if found
|
98 |
if(file_exists(get_stylesheet_directory() . "/email_footer.html"))
|
99 |
$footer = file_get_contents(get_stylesheet_directory() . "/email_footer.html");
|
101 |
$footer = file_get_contents(get_template_directory() . "/email_footer.html");
|
102 |
else
|
103 |
$footer = "";
|
104 |
+
|
105 |
//wpautop header if needed
|
106 |
if(!empty($footer) && $footer == strip_tags($footer))
|
107 |
$footer = wpautop($footer);
|
114 |
$phpmailer->Body = $header . "\n" . $phpmailer->Body;
|
115 |
if(!empty($footer))
|
116 |
$phpmailer->Body = $phpmailer->Body . "\n" . $footer;
|
117 |
+
|
118 |
// Replace variables in email
|
119 |
global $current_user;
|
120 |
$data = array(
|
121 |
"name" => $current_user->display_name,
|
122 |
"sitename" => get_option("blogname"),
|
123 |
"login_link" => pmpro_url("account"),
|
124 |
+
"login_url" => pmpro_url("account"),
|
125 |
"display_name" => $current_user->display_name,
|
126 |
"user_email" => $current_user->user_email,
|
127 |
"subject" => $phpmailer->Subject
|
129 |
foreach($data as $key => $value)
|
130 |
{
|
131 |
$phpmailer->Body = str_replace("!!" . $key . "!!", $value, $phpmailer->Body);
|
132 |
+
}
|
133 |
+
|
134 |
do_action("pmpro_after_phpmailer_init", $phpmailer);
|
135 |
do_action("pmpro_after_pmpmailer_init", $phpmailer); //typo left in for backwards compatibility
|
136 |
}
|
138 |
/**
|
139 |
* Change the content type of emails to HTML.
|
140 |
*/
|
141 |
+
function pmpro_wp_mail_content_type( $content_type ) {
|
142 |
add_action('phpmailer_init', 'pmpro_send_html');
|
143 |
|
144 |
// Change to html if not already.
|
145 |
+
if( $content_type == 'text/plain') {
|
146 |
$content_type = 'text/html';
|
147 |
}
|
148 |
+
|
149 |
return $content_type;
|
150 |
}
|
151 |
add_filter('wp_mail_content_type', 'pmpro_wp_mail_content_type');
|
156 |
* We check if there are already <br /> tags before running nl2br.
|
157 |
* Running make_clickable() multiple times has no effect.
|
158 |
*/
|
159 |
+
function pmpro_retrieve_password_message( $message ) {
|
160 |
+
if ( has_filter( 'wp_mail_content_type', 'pmpro_wp_mail_content_type' ) ) {
|
161 |
$message = make_clickable( $message );
|
162 |
+
|
163 |
+
if ( strpos( '<br', strtolower( $message ) ) === false ) {
|
164 |
$message = nl2br( $message );
|
165 |
+
}
|
166 |
+
}
|
167 |
|
168 |
return $message;
|
169 |
}
|
170 |
+
add_filter( 'retrieve_password_message', 'pmpro_retrieve_password_message', 10, 1 );
|
171 |
+
|
172 |
+
//get template data
|
173 |
+
function pmpro_email_templates_get_template_data() {
|
174 |
+
|
175 |
+
check_ajax_referer('pmproet', 'security');
|
176 |
+
|
177 |
+
if ( ! current_user_can( 'pmpro_emailtemplates' ) ) {
|
178 |
+
die( __( 'You do not have permissions to perform this action.', 'paid-memberships-pro' ) );
|
179 |
+
}
|
180 |
+
|
181 |
+
global $pmpro_email_templates_defaults;
|
182 |
+
|
183 |
+
$template = sanitize_text_field( $_REQUEST['template'] );
|
184 |
+
|
185 |
+
//get template data
|
186 |
+
$template_data['body'] = pmpro_getOption('email_' . $template . '_body');
|
187 |
+
$template_data['subject'] = pmpro_getOption('email_' . $template . '_subject');
|
188 |
+
$template_data['disabled'] = pmpro_getOption('email_' . $template . '_disabled');
|
189 |
+
|
190 |
+
if (empty($template_data['body'])) {
|
191 |
+
//if not found, load template
|
192 |
+
$template_data['body'] = pmpro_email_templates_get_template_body($template);
|
193 |
+
}
|
194 |
+
|
195 |
+
if (empty($template_data['subject']) && $template != "header" && $template != "footer") {
|
196 |
+
$template_data['subject'] = $pmpro_email_templates_defaults[$template]['subject'];
|
197 |
+
}
|
198 |
+
|
199 |
+
// Get template help text from defaults.
|
200 |
+
$template_data['help_text'] = $pmpro_email_templates_defaults[$template]['help_text'];
|
201 |
+
|
202 |
+
echo json_encode($template_data);
|
203 |
+
|
204 |
+
exit;
|
205 |
+
}
|
206 |
+
add_action('wp_ajax_pmpro_email_templates_get_template_data', 'pmpro_email_templates_get_template_data');
|
207 |
+
|
208 |
+
//save template data
|
209 |
+
function pmpro_email_templates_save_template_data() {
|
210 |
+
|
211 |
+
check_ajax_referer('pmproet', 'security');
|
212 |
+
|
213 |
+
if ( ! current_user_can( 'pmpro_emailtemplates' ) ) {
|
214 |
+
die( __( 'You do not have permissions to perform this action.', 'paid-memberships-pro' ) );
|
215 |
+
}
|
216 |
+
|
217 |
+
$template = sanitize_text_field( $_REQUEST['template'] );
|
218 |
+
$subject = sanitize_text_field( wp_unslash( $_REQUEST['subject'] ) );
|
219 |
+
$body = pmpro_kses( wp_unslash( $_REQUEST['body'] ), 'email' );
|
220 |
+
|
221 |
+
//update this template's settings
|
222 |
+
pmpro_setOption( 'email_' . $template . '_subject', $subject );
|
223 |
+
pmpro_setOption( 'email_' . $template . '_body', $body );
|
224 |
+
delete_transient( 'pmproet_' . $template );
|
225 |
+
esc_html_e( 'Template Saved', 'paid-memberships-pro' );
|
226 |
+
|
227 |
+
exit;
|
228 |
+
}
|
229 |
+
add_action('wp_ajax_pmpro_email_templates_save_template_data', 'pmpro_email_templates_save_template_data');
|
230 |
+
|
231 |
+
//reset template data
|
232 |
+
function pmpro_email_templates_reset_template_data() {
|
233 |
+
|
234 |
+
check_ajax_referer('pmproet', 'security');
|
235 |
+
|
236 |
+
if ( ! current_user_can( 'pmpro_emailtemplates' ) ) {
|
237 |
+
die( __( 'You do not have permissions to perform this action.', 'paid-memberships-pro' ) );
|
238 |
+
}
|
239 |
+
|
240 |
+
global $pmpro_email_templates_defaults;
|
241 |
+
|
242 |
+
$template = sanitize_text_field( $_REQUEST['template'] );
|
243 |
+
|
244 |
+
delete_option('pmpro_email_' . $template . '_subject');
|
245 |
+
delete_option('pmpro_email_' . $template . '_body');
|
246 |
+
delete_transient( 'pmproet_' . $template );
|
247 |
+
|
248 |
+
$template_data['subject'] = $pmpro_email_templates_defaults[$template]['subject'];
|
249 |
+
$template_data['body'] = pmpro_email_templates_get_template_body($template);
|
250 |
+
|
251 |
+
echo json_encode($template_data);
|
252 |
+
exit;
|
253 |
+
}
|
254 |
+
add_action('wp_ajax_pmpro_email_templates_reset_template_data', 'pmpro_email_templates_reset_template_data');
|
255 |
+
|
256 |
+
// disable template
|
257 |
+
function pmpro_email_templates_disable_template() {
|
258 |
+
|
259 |
+
check_ajax_referer('pmproet', 'security');
|
260 |
+
|
261 |
+
if ( ! current_user_can( 'pmpro_emailtemplates' ) ) {
|
262 |
+
die( __( 'You do not have permissions to perform this action.', 'paid-memberships-pro' ) );
|
263 |
+
}
|
264 |
+
|
265 |
+
$template = sanitize_text_field( $_REQUEST['template'] );
|
266 |
+
$disabled = sanitize_text_field( $_REQUEST['disabled'] );
|
267 |
+
$response['result'] = update_option('pmpro_email_' . $template . '_disabled', $disabled );
|
268 |
+
$response['status'] = $disabled;
|
269 |
+
echo json_encode($response);
|
270 |
+
exit;
|
271 |
+
}
|
272 |
+
add_action('wp_ajax_pmpro_email_templates_disable_template', 'pmpro_email_templates_disable_template');
|
273 |
+
|
274 |
+
//send test email
|
275 |
+
function pmpro_email_templates_send_test() {
|
276 |
+
|
277 |
+
check_ajax_referer('pmproet', 'security');
|
278 |
+
|
279 |
+
if ( ! current_user_can( 'pmpro_emailtemplates' ) ) {
|
280 |
+
die( __( 'You do not have permissions to perform this action.', 'paid-memberships-pro' ) );
|
281 |
+
}
|
282 |
+
|
283 |
+
global $current_user;
|
284 |
+
|
285 |
+
//setup test email
|
286 |
+
$test_email = new PMProEmail();
|
287 |
+
$test_email->to = sanitize_email( $_REQUEST['email'] );
|
288 |
+
$test_email->template = sanitize_text_field( str_replace('email_', '', $_REQUEST['template']) );
|
289 |
+
|
290 |
+
//add filter to change recipient
|
291 |
+
add_filter('pmpro_email_recipient', 'pmpro_email_templates_test_recipient', 10, 2);
|
292 |
+
|
293 |
+
//load test order
|
294 |
+
$test_order = new MemberOrder();
|
295 |
+
$test_order->get_test_order();
|
296 |
+
|
297 |
+
$test_user = $current_user;
|
298 |
+
|
299 |
+
// Grab the first membership level defined as a "test level" to use
|
300 |
+
$all_levels = pmpro_getAllLevels( true);
|
301 |
+
$test_user->membership_level = array_pop( $all_levels );
|
302 |
+
|
303 |
+
//add notice to email body
|
304 |
+
add_filter('pmpro_email_body', 'pmpro_email_templates_test_body', 10, 2);
|
305 |
+
|
306 |
+
//force the template
|
307 |
+
add_filter('pmpro_email_filter', 'pmpro_email_templates_test_template', 5, 1);
|
308 |
+
|
309 |
+
//figure out how to send the email
|
310 |
+
switch($test_email->template) {
|
311 |
+
case 'cancel':
|
312 |
+
$send_email = 'sendCancelEmail';
|
313 |
+
$params = array($test_user);
|
314 |
+
break;
|
315 |
+
case 'cancel_admin':
|
316 |
+
$send_email = 'sendCancelAdminEmail';
|
317 |
+
$params = array($current_user, $current_user->membership_level->id);
|
318 |
+
break;
|
319 |
+
case 'checkout_check':
|
320 |
+
case 'checkout_express':
|
321 |
+
case 'checkout_free':
|
322 |
+
case 'checkout_freetrial':
|
323 |
+
case 'checkout_paid':
|
324 |
+
case 'checkout_trial':
|
325 |
+
$send_email = 'sendCheckoutEmail';
|
326 |
+
$params = array($test_user, $test_order);
|
327 |
+
break;
|
328 |
+
case 'checkout_check_admin':
|
329 |
+
case 'checkout_express_admin':
|
330 |
+
case 'checkout_free_admin':
|
331 |
+
case 'checkout_freetrial_admin':
|
332 |
+
case 'checkout_paid_admin':
|
333 |
+
case 'checkout_trial_admin':
|
334 |
+
$send_email = 'sendCheckoutAdminEmail';
|
335 |
+
$params = array($test_user, $test_order);
|
336 |
+
break;
|
337 |
+
case 'billing':
|
338 |
+
$send_email = 'sendBillingEmail';
|
339 |
+
$params = array($test_user, $test_order);
|
340 |
+
break;
|
341 |
+
case 'billing_admin':
|
342 |
+
$send_email = 'sendBillingAdminEmail';
|
343 |
+
$params = array($test_user, $test_order);
|
344 |
+
break;
|
345 |
+
case 'billing_failure':
|
346 |
+
$send_email = 'sendBillingFailureEmail';
|
347 |
+
$params = array($test_user, $test_order);
|
348 |
+
break;
|
349 |
+
case 'billing_failure_admin':
|
350 |
+
$send_email = 'sendBillingFailureAdminEmail';
|
351 |
+
$params = array($test_user->user_email, $test_order);
|
352 |
+
break;
|
353 |
+
case 'credit_card_expiring':
|
354 |
+
$send_email = 'sendCreditCardExpiringEmail';
|
355 |
+
$params = array($test_user, $test_order);
|
356 |
+
break;
|
357 |
+
case 'invoice':
|
358 |
+
$send_email = 'sendInvoiceEmail';
|
359 |
+
$params = array($test_user, $test_order);
|
360 |
+
break;
|
361 |
+
case 'trial_ending':
|
362 |
+
$send_email = 'sendTrialEndingEmail';
|
363 |
+
$params = array($test_user);
|
364 |
+
break;
|
365 |
+
case 'membership_expired';
|
366 |
+
$send_email = 'sendMembershipExpiredEmail';
|
367 |
+
$params = array($test_user);
|
368 |
+
break;
|
369 |
+
case 'membership_expiring';
|
370 |
+
$send_email = 'sendMembershipExpiringEmail';
|
371 |
+
$params = array($test_user);
|
372 |
+
break;
|
373 |
+
case 'payment_action':
|
374 |
+
$send_email = 'sendPaymentActionRequiredEmail';
|
375 |
+
$params = array($test_user, $test_order, "http://www.example-notification-url.com/not-a-real-site");
|
376 |
+
break;
|
377 |
+
case 'payment_action_admin':
|
378 |
+
$send_email = 'sendPaymentActionRequiredAdminEmail';
|
379 |
+
$params = array($test_user, $test_order, "http://www.example-notification-url.com/not-a-real-site");
|
380 |
+
break;
|
381 |
+
default:
|
382 |
+
$send_email = 'sendEmail';
|
383 |
+
$params = array();
|
384 |
+
}
|
385 |
+
|
386 |
+
//send the email
|
387 |
+
$response = call_user_func_array(array($test_email, $send_email), $params);
|
388 |
+
|
389 |
+
//return the response
|
390 |
+
echo $response;
|
391 |
+
exit;
|
392 |
+
}
|
393 |
+
add_action('wp_ajax_pmpro_email_templates_send_test', 'pmpro_email_templates_send_test');
|
394 |
+
|
395 |
+
function pmpro_email_templates_test_recipient($email) {
|
396 |
+
if(!empty($_REQUEST['email']))
|
397 |
+
$email = sanitize_email( $_REQUEST['email'] );
|
398 |
+
return $email;
|
399 |
+
}
|
400 |
+
|
401 |
+
//for test emails
|
402 |
+
function pmpro_email_templates_test_body($body, $email = null) {
|
403 |
+
$body .= '<br /><br /><b>-- ' . __('THIS IS A TEST EMAIL', 'paid-memberships-pro') . ' --</b>';
|
404 |
+
return $body;
|
405 |
+
}
|
406 |
+
|
407 |
+
function pmpro_email_templates_test_template($email)
|
408 |
+
{
|
409 |
+
if( ! empty( $_REQUEST['template'] ) ) {
|
410 |
+
$email->template = sanitize_text_field( str_replace('email_', '', $_REQUEST['template']) );
|
411 |
+
}
|
412 |
+
|
413 |
+
return $email;
|
414 |
+
}
|
415 |
+
|
416 |
+
/* Filter for Variables */
|
417 |
+
function pmpro_email_templates_email_data($data, $email) {
|
418 |
+
|
419 |
+
global $pmpro_currency_symbol;
|
420 |
+
|
421 |
+
if ( ! empty( $data ) && ! empty( $data['user_login'] ) ) {
|
422 |
+
$user = get_user_by( 'login', $data['user_login'] );
|
423 |
+
} elseif ( ! empty( $email ) ) {
|
424 |
+
$user = get_user_by( 'email', $email->email );
|
425 |
+
} else {
|
426 |
+
$user = wp_get_current_user();
|
427 |
+
}
|
428 |
+
|
429 |
+
// Make sure we have the current membership level data.
|
430 |
+
if ( $user instanceof WP_User ) {
|
431 |
+
$user->membership_level = pmpro_getMembershipLevelForUser(
|
432 |
+
$user->ID,
|
433 |
+
true
|
434 |
+
);
|
435 |
+
}
|
436 |
+
|
437 |
+
//make sure data is an array
|
438 |
+
if(!is_array($data))
|
439 |
+
$data = array();
|
440 |
+
|
441 |
+
//general data
|
442 |
+
$new_data['sitename'] = get_option("blogname");
|
443 |
+
$new_data['siteemail'] = pmpro_getOption("from_email");
|
444 |
+
if(empty($new_data['login_link'])) {
|
445 |
+
$new_data['login_link'] = wp_login_url();
|
446 |
+
$new_data['login_url'] = wp_login_url();
|
447 |
+
}
|
448 |
+
$new_data['levels_link'] = pmpro_url("levels");
|
449 |
+
|
450 |
+
// User Data.
|
451 |
+
if ( ! empty( $user ) ) {
|
452 |
+
$new_data['name'] = $user->display_name;
|
453 |
+
$new_data['user_login'] = $user->user_login;
|
454 |
+
$new_data['display_name'] = $user->display_name;
|
455 |
+
$new_data['user_email'] = $user->user_email;
|
456 |
+
|
457 |
+
// Membership Information.
|
458 |
+
$new_data['membership_expiration'] = '';
|
459 |
+
$new_data["membership_change"] = __("Your membership has been cancelled.", "paid-memberships-pro");
|
460 |
+
if ( empty( $user->membership_level ) ) {
|
461 |
+
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID, true);
|
462 |
+
}
|
463 |
+
if ( ! empty( $user->membership_level ) ) {
|
464 |
+
if ( ! empty( $user->membership_level->name ) ) {
|
465 |
+
$new_data["membership_change"] = sprintf(__("The new level is %s.", "paid-memberships-pro"), $user->membership_level->name);
|
466 |
+
}
|
467 |
+
if ( ! empty($user->membership_level->startdate) ) {
|
468 |
+
$new_data['startdate'] = date_i18n( get_option( 'date_format' ), $user->membership_level->startdate );
|
469 |
+
}
|
470 |
+
if ( ! empty($user->membership_level->enddate) ) {
|
471 |
+
$new_data['enddate'] = date_i18n( get_option( 'date_format' ), $user->membership_level->enddate );
|
472 |
+
$new_data['membership_expiration'] = "<p>" . sprintf( __("This membership will expire on %s.", "paid-memberships-pro"), date_i18n( get_option( 'date_format' ), $user->membership_level->enddate ) ) . "</p>\n";
|
473 |
+
$new_data["membership_change"] .= " " . sprintf(__("This membership will expire on %s.", "paid-memberships-pro"), date_i18n( get_option( 'date_format' ), $user->membership_level->enddate ) );
|
474 |
+
} else if ( ! empty( $email->expiration_changed ) ) {
|
475 |
+
$new_data["membership_change"] .= " " . __("This membership does not expire.", "paid-memberships-pro");
|
476 |
+
}
|
477 |
+
}
|
478 |
+
}
|
479 |
+
|
480 |
+
//invoice data
|
481 |
+
if(!empty($data['invoice_id']))
|
482 |
+
{
|
483 |
+
$invoice = new MemberOrder($data['invoice_id']);
|
484 |
+
if(!empty($invoice) && !empty($invoice->code))
|
485 |
+
{
|
486 |
+
$new_data['billing_name'] = $invoice->billing->name;
|
487 |
+
$new_data['billing_street'] = $invoice->billing->street;
|
488 |
+
$new_data['billing_city'] = $invoice->billing->city;
|
489 |
+
$new_data['billing_state'] = $invoice->billing->state;
|
490 |
+
$new_data['billing_zip'] = $invoice->billing->zip;
|
491 |
+
$new_data['billing_country'] = $invoice->billing->country;
|
492 |
+
$new_data['billing_phone'] = $invoice->billing->phone;
|
493 |
+
$new_data['cardtype'] = $invoice->cardtype;
|
494 |
+
$new_data['accountnumber'] = hideCardNumber($invoice->accountnumber);
|
495 |
+
$new_data['expirationmonth'] = $invoice->expirationmonth;
|
496 |
+
$new_data['expirationyear'] = $invoice->expirationyear;
|
497 |
+
$new_data['instructions'] = wpautop(pmpro_getOption('instructions'));
|
498 |
+
$new_data['invoice_id'] = $invoice->code;
|
499 |
+
$new_data['invoice_total'] = $pmpro_currency_symbol . number_format($invoice->total, 2);
|
500 |
+
$new_data['invoice_date'] = date_i18n( get_option( 'date_format' ), $invoice->getTimestamp() );
|
501 |
+
$new_data['invoice_link'] = pmpro_url('invoice', '?invoice=' . $invoice->code);
|
502 |
+
|
503 |
+
//billing address
|
504 |
+
$new_data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
505 |
+
$invoice->billing->street,
|
506 |
+
"", //address 2
|
507 |
+
$invoice->billing->city,
|
508 |
+
$invoice->billing->state,
|
509 |
+
$invoice->billing->zip,
|
510 |
+
$invoice->billing->country,
|
511 |
+
$invoice->billing->phone);
|
512 |
+
}
|
513 |
+
}
|
514 |
+
|
515 |
+
//if others are used in the email look in usermeta
|
516 |
+
$et_body = pmpro_getOption('email_' . $email->template . '_body');
|
517 |
+
$templates_in_email = preg_match_all("/!!([^!]+)!!/", $et_body, $matches);
|
518 |
+
if ( ! empty( $templates_in_email ) && ! empty( $user->ID ) ) {
|
519 |
+
$matches = $matches[1];
|
520 |
+
foreach($matches as $match) {
|
521 |
+
if ( empty( $new_data[ $match ] ) ) {
|
522 |
+
$usermeta = get_user_meta($user->ID, $match, true);
|
523 |
+
if ( ! empty( $usermeta ) ) {
|
524 |
+
if( is_array( $usermeta ) && ! empty( $usermeta['fullurl'] ) ) {
|
525 |
+
$new_data[$match] = $usermeta['fullurl'];
|
526 |
+
} elseif( is_array($usermeta ) ) {
|
527 |
+
$new_data[$match] = implode(", ", $usermeta);
|
528 |
+
} else {
|
529 |
+
$new_data[$match] = $usermeta;
|
530 |
+
}
|
531 |
+
}
|
532 |
+
}
|
533 |
+
}
|
534 |
+
}
|
535 |
+
|
536 |
+
//now replace any new_data not already in data
|
537 |
+
foreach($new_data as $key => $value)
|
538 |
+
{
|
539 |
+
if(!isset($data[$key]))
|
540 |
+
$data[$key] = $value;
|
541 |
+
}
|
542 |
+
|
543 |
+
return $data;
|
544 |
+
}
|
545 |
+
add_filter('pmpro_email_data', 'pmpro_email_templates_email_data', 10, 2);
|
546 |
+
|
547 |
+
|
548 |
+
/**
|
549 |
+
* Load the default email template.
|
550 |
+
*
|
551 |
+
* Checks theme, then template, then PMPro directory.
|
552 |
+
*
|
553 |
+
* @since 0.6
|
554 |
+
*
|
555 |
+
* @param $template string
|
556 |
+
*
|
557 |
+
* @return string
|
558 |
+
*/
|
559 |
+
function pmpro_email_templates_get_template_body($template) {
|
560 |
+
|
561 |
+
global $pmpro_email_templates_defaults;
|
562 |
+
|
563 |
+
// Defaults
|
564 |
+
$body = "";
|
565 |
+
$file = false;
|
566 |
+
|
567 |
+
|
568 |
+
// Load the template.
|
569 |
+
if ( get_transient( 'pmproet_' . $template ) === false ) {
|
570 |
+
// Load template
|
571 |
+
if ( ! empty( pmpro_getOption('email_' . $template . '_body') ) ) {
|
572 |
+
$body = pmpro_getOption('email_' . $template . '_body');
|
573 |
+
}elseif( ! empty($pmpro_email_templates_defaults[$template]['body'])) {
|
574 |
+
$body = $pmpro_email_templates_defaults[$template]['body'];
|
575 |
+
} elseif ( file_exists( get_stylesheet_directory() . '/paid-memberships-pro/email/' . $template . '.html' ) ) {
|
576 |
+
$file = get_stylesheet_directory() . '/paid-memberships-pro/email/' . $template . '.html';
|
577 |
+
} elseif ( file_exists( get_template_directory() . '/paid-memberships-pro/email/' . $template . '.html') ) {
|
578 |
+
$file = get_template_directory() . '/paid-memberships-pro/email/' . $template . '.html';
|
579 |
+
}
|
580 |
+
|
581 |
+
if( $file && ! $body ) {
|
582 |
+
ob_start();
|
583 |
+
require_once( $file );
|
584 |
+
$body = ob_get_contents();
|
585 |
+
ob_end_clean();
|
586 |
+
}
|
587 |
+
|
588 |
+
if ( ! empty( $body ) ) {
|
589 |
+
set_transient( 'pmproet_' . $template, $body, 300 );
|
590 |
+
}
|
591 |
+
} else {
|
592 |
+
$body = get_transient( 'pmproet_' . $template );
|
593 |
+
}
|
594 |
+
|
595 |
+
|
596 |
+
return $body;
|
597 |
+
}
|
includes/functions.php
CHANGED
@@ -39,6 +39,7 @@ function pmpro_setDBTables() {
|
|
39 |
$wpdb->pmpro_discount_codes_levels = $wpdb->prefix . 'pmpro_discount_codes_levels';
|
40 |
$wpdb->pmpro_discount_codes_uses = $wpdb->prefix . 'pmpro_discount_codes_uses';
|
41 |
$wpdb->pmpro_membership_levelmeta = $wpdb->prefix . 'pmpro_membership_levelmeta';
|
|
|
42 |
}
|
43 |
pmpro_setDBTables();
|
44 |
|
@@ -83,7 +84,7 @@ function pmpro_getOption( $s, $force = false ) {
|
|
83 |
}
|
84 |
}
|
85 |
|
86 |
-
function pmpro_setOption( $s, $v = null, $sanitize_function = 'sanitize_text_field' ) {
|
87 |
// no value is given, set v to the p var
|
88 |
if ( $v === null && isset( $_POST[ $s ] ) ) {
|
89 |
if ( is_array( $_POST[ $s ] ) ) {
|
@@ -99,7 +100,7 @@ function pmpro_setOption( $s, $v = null, $sanitize_function = 'sanitize_text_fie
|
|
99 |
$v = trim( $v );
|
100 |
}
|
101 |
|
102 |
-
return update_option( 'pmpro_' . $s, $v );
|
103 |
}
|
104 |
|
105 |
function pmpro_get_slug( $post_id ) {
|
@@ -131,15 +132,19 @@ function pmpro_url( $page = null, $querystring = '', $scheme = null ) {
|
|
131 |
|
132 |
global $pmpro_pages;
|
133 |
|
134 |
-
|
135 |
-
|
|
|
136 |
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
|
|
142 |
}
|
|
|
|
|
143 |
}
|
144 |
|
145 |
// figure out querystring
|
@@ -155,7 +160,7 @@ function pmpro_url( $page = null, $querystring = '', $scheme = null ) {
|
|
155 |
$url = str_replace( 'http:', 'https:', $url );
|
156 |
}
|
157 |
}
|
158 |
-
|
159 |
/**
|
160 |
* Filter the URL before returning.
|
161 |
*/
|
@@ -170,7 +175,7 @@ function pmpro_isLevelFree( &$level ) {
|
|
170 |
} else {
|
171 |
$r = false;
|
172 |
}
|
173 |
-
|
174 |
$r = apply_filters( 'pmpro_is_level_free', $r, $level );
|
175 |
return $r;
|
176 |
}
|
@@ -196,7 +201,7 @@ function pmpro_areLevelsFree( $levelarr ) {
|
|
196 |
function pmpro_onlyFreeLevels() {
|
197 |
// Get levels that are available for checkout only.
|
198 |
$levels = pmpro_getAllLevels( false, true );
|
199 |
-
|
200 |
return apply_filters( 'pmpro_only_free_levels', pmpro_areLevelsFree( $levels ) );
|
201 |
}
|
202 |
|
@@ -206,7 +211,7 @@ function pmpro_isLevelRecurring( &$level ) {
|
|
206 |
} else {
|
207 |
$r = false;
|
208 |
}
|
209 |
-
|
210 |
$r = apply_filters( 'pmpro_is_level_recurring', $r, $level );
|
211 |
return $r;
|
212 |
}
|
@@ -219,26 +224,26 @@ function pmpro_isLevelRecurring( &$level ) {
|
|
219 |
*/
|
220 |
function pmpro_has_recurring_level( $user_id = null ) {
|
221 |
global $current_user;
|
222 |
-
|
223 |
if ( empty( $user_id ) ) {
|
224 |
$user_id = $current_user->ID;
|
225 |
}
|
226 |
-
|
227 |
if ( empty( $user_id ) ) {
|
228 |
return false;
|
229 |
}
|
230 |
|
231 |
-
$levels = pmpro_getMembershipLevelsForUser( $user_id );
|
232 |
-
|
233 |
if ( empty( $levels ) ) {
|
234 |
return false;
|
235 |
}
|
236 |
-
|
237 |
-
foreach( $levels as $level ) {
|
238 |
if ( pmpro_isLevelRecurring( $level ) ) {
|
239 |
return true;
|
240 |
}
|
241 |
-
}
|
242 |
|
243 |
return false;
|
244 |
}
|
@@ -249,18 +254,19 @@ function pmpro_isLevelTrial( &$level ) {
|
|
249 |
} else {
|
250 |
$r = false;
|
251 |
}
|
252 |
-
|
253 |
$r = apply_filters( 'pmpro_is_level_trial', $r, $level );
|
254 |
return $r;
|
255 |
}
|
256 |
|
257 |
function pmpro_isLevelExpiring( &$level ) {
|
258 |
if ( ! empty( $level ) && ( ! empty( $level->expiration_number ) && $level->expiration_number > 0 ) || ! empty( $level->enddate ) ) {
|
|
|
259 |
$r = true;
|
260 |
} else {
|
261 |
$r = false;
|
262 |
}
|
263 |
-
|
264 |
$r = apply_filters( 'pmpro_is_level_expiring', $r, $level );
|
265 |
return $r;
|
266 |
}
|
@@ -280,7 +286,9 @@ function pmpro_isLevelExpiringSoon( &$level ) {
|
|
280 |
$standard = pmpro_getLevel( $level->id );
|
281 |
|
282 |
if ( ! empty( $standard->expiration_number ) ) {
|
283 |
-
if ( $standard->expiration_period == '
|
|
|
|
|
284 |
$days = $level->expiration_number;
|
285 |
} elseif ( $standard->expiration_period == 'Week' ) {
|
286 |
$days = $level->expiration_number * 7;
|
@@ -296,7 +304,13 @@ function pmpro_isLevelExpiringSoon( &$level ) {
|
|
296 |
// are we within the days til expiration?
|
297 |
$now = current_time( 'timestamp' );
|
298 |
|
299 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
$r = true;
|
301 |
} else {
|
302 |
$r = false;
|
@@ -378,11 +392,15 @@ function pmpro_getLevelCost( &$level, $tags = true, $short = false ) {
|
|
378 |
if ( ! $short ) {
|
379 |
$r = sprintf( __( 'The price for membership is <strong>%s</strong> now', 'paid-memberships-pro' ), pmpro_formatPrice( $level->initial_payment ) );
|
380 |
} else {
|
381 |
-
|
|
|
|
|
|
|
|
|
382 |
}
|
383 |
|
384 |
// recurring part
|
385 |
-
if ( $level->billing_amount
|
386 |
if ( $level->billing_limit > 1 ) {
|
387 |
if ( $level->cycle_number == '1' ) {
|
388 |
$r .= sprintf( __( ' and then <strong>%1$s per %2$s for %3$d more %4$s</strong>.', 'paid-memberships-pro' ), pmpro_formatPrice( $level->billing_amount ), pmpro_translate_billing_period( $level->cycle_period ), $level->billing_limit, pmpro_translate_billing_period( $level->cycle_period, $level->billing_limit ) );
|
@@ -423,7 +441,7 @@ function pmpro_getLevelCost( &$level, $tags = true, $short = false ) {
|
|
423 |
|
424 |
// trial part
|
425 |
if ( $level->trial_limit ) {
|
426 |
-
if ( $level->trial_amount
|
427 |
if ( $level->trial_limit == '1' ) {
|
428 |
$r .= ' ' . __( 'After your initial payment, your first payment is Free.', 'paid-memberships-pro' );
|
429 |
} else {
|
@@ -463,7 +481,7 @@ function pmpro_getLevelsCost( &$levels, $tags = true, $short = false ) {
|
|
463 |
$trialperiods = 0;
|
464 |
foreach ( $levels as $curlevel ) {
|
465 |
$initpmt += $curlevel->initial_payment;
|
466 |
-
if ( $curlevel->billing_amount
|
467 |
if ( array_key_exists( $curlevel->cycle_period, $recurpmts ) ) {
|
468 |
if ( array_key_exists( $curlevel->cycle_number, $recurpmts[ $curlevel->cycle_period ] ) ) {
|
469 |
if ( array_key_exists( $curlevel->billing_limit, $recurpmts[ $curlevel->cycle_period ][ $curlevel->cycle_number ] ) ) {
|
@@ -559,6 +577,7 @@ function pmpro_getLevelsCost( &$levels, $tags = true, $short = false ) {
|
|
559 |
}
|
560 |
|
561 |
function pmpro_getLevelExpiration( &$level ) {
|
|
|
562 |
if ( $level->expiration_number ) {
|
563 |
$expiration_text = sprintf( __( 'Membership expires after %1$d %2$s.', 'paid-memberships-pro' ), $level->expiration_number, pmpro_translate_billing_period( $level->expiration_period, $level->expiration_number ) );
|
564 |
} else {
|
@@ -607,7 +626,7 @@ function pmpro_getLevelsExpiration( &$levels ) {
|
|
607 |
* Filter the levels expiration text. Note the s in levels. Similar to pmpro_levels_expiration_text
|
608 |
*/
|
609 |
$expiration_text = apply_filters( 'pmpro_levels_expiration_text', $expiration_text, $levels );
|
610 |
-
|
611 |
// Backwards compatible
|
612 |
if ( ! empty( $levels ) ) {
|
613 |
$first_level = reset($levels);
|
@@ -615,7 +634,7 @@ function pmpro_getLevelsExpiration( &$levels ) {
|
|
615 |
$first_level = false;
|
616 |
}
|
617 |
$expiration_text = apply_filters( 'pmpro_level_expiration_text', $expiration_text, $first_level );
|
618 |
-
|
619 |
return $expiration_text;
|
620 |
}
|
621 |
|
@@ -628,7 +647,7 @@ function add_pmpro_membership_level_meta( $level_id, $meta_key, $meta_value, $un
|
|
628 |
return add_metadata( 'pmpro_membership_level', $level_id, $meta_key, $meta_value, $unique );
|
629 |
}
|
630 |
|
631 |
-
function get_pmpro_membership_level_meta( $level_id, $key, $single = false ) {
|
632 |
return get_metadata( 'pmpro_membership_level', $level_id, $key, $single );
|
633 |
}
|
634 |
|
@@ -640,6 +659,25 @@ function delete_pmpro_membership_level_meta( $level_id, $meta_key, $meta_value =
|
|
640 |
return delete_metadata( 'pmpro_membership_level', $level_id, $meta_key, $meta_value );
|
641 |
}
|
642 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
643 |
function pmpro_hideAds() {
|
644 |
global $pmpro_display_ads;
|
645 |
return ! $pmpro_display_ads;
|
@@ -922,11 +960,12 @@ function pmpro_cancelMembershipLevel( $cancel_level, $user_id = null, $old_level
|
|
922 |
* @param int $level ID of level to set as new level, use 0 to cancel membership
|
923 |
* @param int $user_id ID of the user to change levels for
|
924 |
* @param string $old_level_status The status to set for the row in the memberships users table. (e.g. inactive, cancelled, admin_cancelled, expired) Defaults to 'inactive'.
|
925 |
-
*
|
926 |
*
|
927 |
* Return values:
|
928 |
* Success returns boolean true.
|
929 |
* Failure returns boolean false.
|
|
|
930 |
*/
|
931 |
function pmpro_changeMembershipLevel( $level, $user_id = null, $old_level_status = 'inactive', $cancel_level = null ) {
|
932 |
global $wpdb;
|
@@ -944,6 +983,12 @@ function pmpro_changeMembershipLevel( $level, $user_id = null, $old_level_status
|
|
944 |
// make sure user id is int for security
|
945 |
$user_id = intval( $user_id );
|
946 |
|
|
|
|
|
|
|
|
|
|
|
|
|
947 |
if ( empty( $level ) ) {
|
948 |
$level = 0;
|
949 |
} else if ( is_array( $level ) ) {
|
@@ -974,14 +1019,21 @@ function pmpro_changeMembershipLevel( $level, $user_id = null, $old_level_status
|
|
974 |
if ( ! is_array( $level ) ) {
|
975 |
// are they even changing?
|
976 |
if ( pmpro_hasMembershipLevel( $level, $user_id ) ) {
|
977 |
-
|
978 |
-
return false; // not changing
|
979 |
}
|
980 |
}
|
981 |
|
982 |
// get all active membershipships for this user
|
983 |
$old_levels = pmpro_getMembershipLevelsForUser( $user_id );
|
984 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
985 |
// get level id
|
986 |
if ( is_array( $level ) ) {
|
987 |
$level_id = $level['membership_id']; // custom level
|
@@ -995,7 +1047,7 @@ function pmpro_changeMembershipLevel( $level, $user_id = null, $old_level_status
|
|
995 |
* @param int $level_id ID of the level changed to.
|
996 |
* @param int $user_id ID of the user changed.
|
997 |
* @param array $old_levels array of prior levels the user belonged to.
|
998 |
-
*
|
999 |
*/
|
1000 |
do_action( 'pmpro_before_change_membership_level', $level_id, $user_id, $old_levels, $cancel_level );
|
1001 |
|
@@ -1074,10 +1126,10 @@ function pmpro_changeMembershipLevel( $level, $user_id = null, $old_level_status
|
|
1074 |
|
1075 |
if ( ! empty( $c_order->error ) ) {
|
1076 |
$pmpro_error = $c_order->error;
|
1077 |
-
}
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
}
|
1082 |
}
|
1083 |
}
|
@@ -1139,15 +1191,48 @@ function pmpro_changeMembershipLevel( $level, $user_id = null, $old_level_status
|
|
1139 |
$pmpro_error = sprintf( __( 'Error interacting with database: %s', 'paid-memberships-pro' ), ( ! empty( $wpdb->last_error ) ? $wpdb->last_error : 'unavailable' ) );
|
1140 |
return false;
|
1141 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1142 |
}
|
1143 |
|
1144 |
// remove cached level
|
1145 |
global $all_membership_levels;
|
1146 |
unset( $all_membership_levels[ $user_id ] );
|
1147 |
-
|
1148 |
// remove levels cache for user
|
1149 |
$cache_key = 'user_' . $user_id . '_levels';
|
1150 |
wp_cache_delete( $cache_key, 'pmpro' );
|
|
|
|
|
1151 |
|
1152 |
// update user data and call action
|
1153 |
pmpro_set_current_user();
|
@@ -1157,12 +1242,44 @@ function pmpro_changeMembershipLevel( $level, $user_id = null, $old_level_status
|
|
1157 |
*
|
1158 |
* @param int $level_id ID of the level changed to.
|
1159 |
* @param int $user_id ID of the user changed.
|
1160 |
-
*
|
1161 |
*/
|
1162 |
do_action( 'pmpro_after_change_membership_level', $level_id, $user_id, $cancel_level );
|
1163 |
return true;
|
1164 |
}
|
1165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1166 |
/**
|
1167 |
* Function to list WordPress categories in hierarchical format.
|
1168 |
*
|
@@ -1200,8 +1317,9 @@ function pmpro_listCategories( $parent_id = 0, $level_categories = array() ) {
|
|
1200 |
/*
|
1201 |
pmpro_toggleMembershipCategory() creates or deletes a linking entry between the membership level and post category tables.
|
1202 |
*
|
1203 |
-
* $level may either be the ID or name of the desired membership_level.
|
1204 |
-
* $category must be a valid post category ID.
|
|
|
1205 |
*
|
1206 |
* Return values:
|
1207 |
* Success returns boolean true.
|
@@ -1239,8 +1357,8 @@ function pmpro_toggleMembershipCategory( $level, $category, $value ) {
|
|
1239 |
pmpro_updateMembershipCategories() ensures that all those and only those categories given
|
1240 |
* are associated with the given membership level.
|
1241 |
*
|
1242 |
-
* $level is a valid membership level ID or name
|
1243 |
-
* $categories is an array of post category IDs
|
1244 |
*
|
1245 |
* Return values:
|
1246 |
* Success returns boolean true.
|
@@ -1278,7 +1396,7 @@ function pmpro_updateMembershipCategories( $level, $categories ) {
|
|
1278 |
/*
|
1279 |
pmpro_getMembershipCategories() returns the categories for a given level
|
1280 |
*
|
1281 |
-
* $level_id is a valid membership level ID
|
1282 |
*
|
1283 |
* Return values:
|
1284 |
* Success returns boolean true.
|
@@ -1291,7 +1409,7 @@ function pmpro_getMembershipCategories( $level_id ) {
|
|
1291 |
$categories = $wpdb->get_col(
|
1292 |
"SELECT c.category_id
|
1293 |
FROM {$wpdb->pmpro_memberships_categories} AS c
|
1294 |
-
WHERE c.membership_id = '" . $level_id . "'"
|
1295 |
);
|
1296 |
|
1297 |
return $categories;
|
@@ -1299,7 +1417,7 @@ function pmpro_getMembershipCategories( $level_id ) {
|
|
1299 |
|
1300 |
|
1301 |
function pmpro_isAdmin( $user_id = null ) {
|
1302 |
-
global $current_user
|
1303 |
if ( ! $user_id ) {
|
1304 |
$user_id = $current_user->ID;
|
1305 |
}
|
@@ -1355,7 +1473,7 @@ function pmpro_getMetavalues( $query ) {
|
|
1355 |
}
|
1356 |
|
1357 |
// function to return the pagination string
|
1358 |
-
function pmpro_getPaginationString( $page = 1, $totalitems, $limit = 15, $adjacents = 1, $targetpage = '/', $pagestring = '&pn=' ) {
|
1359 |
// defaults
|
1360 |
if ( ! $adjacents ) {
|
1361 |
$adjacents = 1;
|
@@ -1515,6 +1633,8 @@ function pmpro_calculateRecurringRevenue( $s, $l ) {
|
|
1515 |
UNION
|
1516 |
SELECT SUM((365/cycle_number)*billing_amount) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND cycle_period = 'Day' AND cycle_number <> 365 $user_ids_query
|
1517 |
UNION
|
|
|
|
|
1518 |
SELECT SUM((52/cycle_number)*billing_amount) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND cycle_period = 'Week' AND cycle_number <> 52 $user_ids_query
|
1519 |
UNION
|
1520 |
SELECT SUM(billing_amount) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND cycle_period = 'Year' $user_ids_query
|
@@ -1560,7 +1680,7 @@ function pmpro_generateUsername( $firstname = '', $lastname = '', $email = '' )
|
|
1560 |
$username = $lastname;
|
1561 |
}
|
1562 |
|
1563 |
-
// If no username yet or one based on name
|
1564 |
// try to create username using email address.
|
1565 |
if ( ( empty( $username ) || username_exists( $username ) )
|
1566 |
&& ! empty( $email ) && is_email( $email ) ) {
|
@@ -1605,8 +1725,12 @@ function pmpro_generateUsername( $firstname = '', $lastname = '', $email = '' )
|
|
1605 |
function pmpro_getDiscountCode( $seed = null ) {
|
1606 |
global $wpdb;
|
1607 |
|
|
|
|
|
|
|
|
|
1608 |
while ( empty( $code ) ) {
|
1609 |
-
$scramble = md5( AUTH_KEY .
|
1610 |
$code = substr( $scramble, 0, 10 );
|
1611 |
$check = $wpdb->get_var( "SELECT code FROM $wpdb->pmpro_discount_codes WHERE code = '" . esc_sql( $code ) . "' LIMIT 1" );
|
1612 |
if ( $check || is_numeric( $code ) ) {
|
@@ -1646,7 +1770,7 @@ function pmpro_checkDiscountCode( $code, $level_id = null, $return_errors = fals
|
|
1646 |
$dbcode->expires = strtotime( date_i18n( 'm/d/Y', $dbcode->expires ) );
|
1647 |
|
1648 |
// today
|
1649 |
-
$today = strtotime( date_i18n( 'm/d/Y
|
1650 |
|
1651 |
// has this code started yet?
|
1652 |
if ( ! empty( $dbcode->starts ) && $dbcode->starts > $today ) {
|
@@ -1664,7 +1788,7 @@ function pmpro_checkDiscountCode( $code, $level_id = null, $return_errors = fals
|
|
1664 |
// have we run out of uses?
|
1665 |
if ( ! $error ) {
|
1666 |
if ( $dbcode->uses > 0 ) {
|
1667 |
-
$used = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->pmpro_discount_codes_uses WHERE code_id = '" . $dbcode->id . "'" );
|
1668 |
if ( $used >= $dbcode->uses ) {
|
1669 |
$error = __( 'This discount code is no longer valid.', 'paid-memberships-pro' );
|
1670 |
}
|
@@ -1682,7 +1806,7 @@ function pmpro_checkDiscountCode( $code, $level_id = null, $return_errors = fals
|
|
1682 |
} else {
|
1683 |
$level_id = intval( $level_id );
|
1684 |
}
|
1685 |
-
$code_level = $wpdb->get_row( "SELECT l.id, cl.*, l.name, l.description, l.allow_signups FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id WHERE cl.code_id = '" . $dbcode->id . "' AND cl.level_id IN (" . $level_id . ") LIMIT 1" );
|
1686 |
|
1687 |
if ( empty( $code_level ) ) {
|
1688 |
$error = __( 'This discount code does not apply to this membership level.', 'paid-memberships-pro' );
|
@@ -1697,7 +1821,7 @@ function pmpro_checkDiscountCode( $code, $level_id = null, $return_errors = fals
|
|
1697 |
*
|
1698 |
* @param bool $okay true if code check is okay or false if there was an error
|
1699 |
* @param object $dbcode Object containing code data from the database row
|
1700 |
-
* @param int $level_id ID of the level the user is checking out for.
|
1701 |
* @param string $code Discount code string.
|
1702 |
*
|
1703 |
* @return mixed $okay true if okay, false or error message string if not okay
|
@@ -1907,7 +2031,7 @@ function pmpro_getMembershipLevelForUser( $user_id = null, $force = false ) {
|
|
1907 |
if ( empty( $all_membership_levels[ $user_id ] ) ) {
|
1908 |
$all_membership_levels[ $user_id ] = false;
|
1909 |
}
|
1910 |
-
|
1911 |
// Round off prices
|
1912 |
if ( ! empty( $all_membership_levels[$user_id] ) ) {
|
1913 |
if ( isset( $all_membership_levels[$user_id]->initial_payment ) ) {
|
@@ -1960,19 +2084,19 @@ function pmpro_getMembershipLevelsForUser( $user_id = null, $include_inactive =
|
|
1960 |
$user_id = intval( $user_id );
|
1961 |
|
1962 |
global $wpdb;
|
1963 |
-
|
1964 |
/**
|
1965 |
* We are going to see if cache is set before doing the query and use that if it is.
|
1966 |
-
*
|
1967 |
* In a default environment with no external object cache, the value is cached in that request and
|
1968 |
* reduces future MySQL requests. If there is an external object cache like Redis then it will be
|
1969 |
* persisted until the user level changes.
|
1970 |
**/
|
1971 |
-
$cache_key = 'user_' . $user_id . '_levels';
|
1972 |
$levels = wp_cache_get( $cache_key, 'pmpro' );
|
1973 |
-
|
1974 |
if ( $levels === false ) {
|
1975 |
-
|
1976 |
$levels = $wpdb->get_results(
|
1977 |
"SELECT
|
1978 |
l.id AS ID,
|
@@ -2000,7 +2124,7 @@ function pmpro_getMembershipLevelsForUser( $user_id = null, $include_inactive =
|
|
2000 |
);
|
2001 |
wp_cache_set( $cache_key, $levels, 'pmpro', 3600 );
|
2002 |
}
|
2003 |
-
|
2004 |
// Round off prices
|
2005 |
if ( ! empty( $levels ) ) {
|
2006 |
foreach( $levels as $key => $level ) {
|
@@ -2009,7 +2133,7 @@ function pmpro_getMembershipLevelsForUser( $user_id = null, $include_inactive =
|
|
2009 |
$levels[$key]->trial_amount = pmpro_round_price( $level->trial_amount );
|
2010 |
}
|
2011 |
}
|
2012 |
-
|
2013 |
/**
|
2014 |
* pmpro_get_membership_levels_for_user filter.
|
2015 |
*
|
@@ -2028,7 +2152,7 @@ function pmpro_getMembershipLevelsForUser( $user_id = null, $include_inactive =
|
|
2028 |
* Get a specific membership level for a user if they have that level.
|
2029 |
* This is better to use when MMPU is enabled on the site.
|
2030 |
*
|
2031 |
-
* If $user_id is
|
2032 |
*
|
2033 |
* Return values:
|
2034 |
* Success returns the level object.
|
@@ -2037,7 +2161,7 @@ function pmpro_getMembershipLevelsForUser( $user_id = null, $include_inactive =
|
|
2037 |
* @param int $user_id User ID to check for
|
2038 |
* @param int $level_id Level ID to check for.
|
2039 |
*/
|
2040 |
-
function pmpro_getSpecificMembershipLevelForUser( $user_id
|
2041 |
if ( empty( $user_id ) ) {
|
2042 |
global $current_user;
|
2043 |
$user_id = $current_user->ID;
|
@@ -2061,7 +2185,7 @@ function pmpro_getSpecificMembershipLevelForUser( $user_id = null, $level_id ) {
|
|
2061 |
/*
|
2062 |
pmpro_getLevel() returns the level object for a level
|
2063 |
*
|
2064 |
-
* $level may be the level id or name
|
2065 |
*
|
2066 |
* Return values:
|
2067 |
* Success returns the level object.
|
@@ -2081,7 +2205,7 @@ function pmpro_getLevel( $level ) {
|
|
2081 |
return $pmpro_levels[ $level_id ];
|
2082 |
} else {
|
2083 |
global $wpdb;
|
2084 |
-
$pmpro_levels[ $level_id ] = $wpdb->get_row( "SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . $level_id . "' LIMIT 1" );
|
2085 |
}
|
2086 |
} else {
|
2087 |
global $wpdb;
|
@@ -2093,22 +2217,22 @@ function pmpro_getLevel( $level ) {
|
|
2093 |
return false;
|
2094 |
}
|
2095 |
|
2096 |
-
$pmpro_levels[ $level_id ] = $level_obj;
|
2097 |
}
|
2098 |
-
|
2099 |
// Round prices
|
2100 |
if ( ! empty( $pmpro_levels[ $level_id ] ) ) {
|
2101 |
$pmpro_levels[ $level_id ]->initial_payment = pmpro_round_price( $pmpro_levels[ $level_id ]->initial_payment );
|
2102 |
$pmpro_levels[ $level_id ]->billing_amount = pmpro_round_price( $pmpro_levels[ $level_id ]->billing_amount );
|
2103 |
$pmpro_levels[ $level_id ]->trial_amount = pmpro_round_price( $pmpro_levels[ $level_id ]->trial_amount );
|
2104 |
}
|
2105 |
-
|
2106 |
return $pmpro_levels[ $level_id ];
|
2107 |
}
|
2108 |
|
2109 |
/*
|
2110 |
Get all PMPro membership levels.
|
2111 |
-
|
2112 |
@param bool $include_hidden Include levels marked as hidden/inactive.
|
2113 |
@param bool $use_cache If false, use $pmpro_levels global. If true use other caches.
|
2114 |
@param bool $force Resets the static var caches as well.
|
@@ -2155,7 +2279,7 @@ function pmpro_getAllLevels( $include_hidden = false, $use_cache = false, $force
|
|
2155 |
$raw_level->trial_amount = pmpro_round_price( $raw_level->trial_amount );
|
2156 |
$pmpro_levels[ $raw_level->id ] = $raw_level;
|
2157 |
}
|
2158 |
-
|
2159 |
// Store an extra cache specific to the include_hidden param.
|
2160 |
if ( $include_hidden ) {
|
2161 |
$pmpro_all_levels = $pmpro_levels;
|
@@ -2184,6 +2308,10 @@ function pmpro_are_any_visible_levels() {
|
|
2184 |
|
2185 |
/**
|
2186 |
* Get level at checkout and place into $pmpro_level global.
|
|
|
|
|
|
|
|
|
2187 |
*/
|
2188 |
function pmpro_getLevelAtCheckout( $level_id = null, $discount_code = null ) {
|
2189 |
global $pmpro_level, $wpdb, $post;
|
@@ -2205,11 +2333,15 @@ function pmpro_getLevelAtCheckout( $level_id = null, $discount_code = null ) {
|
|
2205 |
if ( empty( $level_id ) ) {
|
2206 |
$all_levels = pmpro_getAllLevels( false, false );
|
2207 |
|
2208 |
-
|
2209 |
-
|
|
|
|
|
|
|
|
|
2210 |
|
2211 |
$level_id = apply_filters( 'pmpro_default_level', intval( $default_level ) );
|
2212 |
-
|
2213 |
// Bail back to levels page if level ID is empty or less than 1.
|
2214 |
if ( empty( $level_id ) || $level_id < 1 || ! is_int( $level_id ) ) {
|
2215 |
return;
|
@@ -2224,17 +2356,22 @@ function pmpro_getLevelAtCheckout( $level_id = null, $discount_code = null ) {
|
|
2224 |
|
2225 |
// what level are they purchasing? (discount code passed)
|
2226 |
if ( ! empty( $level_id ) && ! empty( $discount_code ) ) {
|
2227 |
-
$discount_code_id = $wpdb->get_var( "SELECT id FROM $wpdb->pmpro_discount_codes WHERE code = '" . $discount_code . "' LIMIT 1" );
|
2228 |
|
2229 |
// check code
|
2230 |
-
$
|
|
|
|
|
|
|
|
|
|
|
2231 |
if ( $code_check[0] != false ) {
|
2232 |
-
$sqlQuery = "SELECT l.id, cl.*, l.name, l.description, l.allow_signups FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id LEFT JOIN $wpdb->pmpro_discount_codes dc ON dc.id = cl.code_id WHERE dc.code = '" . $discount_code . "' AND cl.level_id = '" . $level_id . "' LIMIT 1";
|
2233 |
$pmpro_level = $wpdb->get_row( $sqlQuery );
|
2234 |
|
2235 |
// if the discount code doesn't adjust the level, let's just get the straight level
|
2236 |
if ( empty( $pmpro_level ) ) {
|
2237 |
-
$pmpro_level = $wpdb->get_row( "SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . $level_id . "' LIMIT 1" );
|
2238 |
}
|
2239 |
|
2240 |
// filter adjustments to the level
|
@@ -2257,18 +2394,52 @@ function pmpro_getLevelAtCheckout( $level_id = null, $discount_code = null ) {
|
|
2257 |
return $pmpro_level;
|
2258 |
}
|
2259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2260 |
function pmpro_getCheckoutButton( $level_id, $button_text = null, $classes = null ) {
|
2261 |
if ( ! empty( $level_id ) ) {
|
2262 |
// get level
|
2263 |
$level = pmpro_getLevel( $level_id );
|
2264 |
|
2265 |
if( ! empty( $level ) ) {
|
2266 |
-
|
2267 |
// default button text with name field for replacement
|
2268 |
if ( empty( $button_text ) ) {
|
2269 |
$button_text = __( 'Sign Up for !!name!! Now', 'paid-memberships-pro' );
|
2270 |
}
|
2271 |
-
|
2272 |
// replace vars
|
2273 |
$replacements = array(
|
2274 |
'!!id!!' => $level->id,
|
@@ -2288,21 +2459,21 @@ function pmpro_getCheckoutButton( $level_id, $button_text = null, $classes = nul
|
|
2288 |
$button_text = str_replace( array_keys( $replacements ), $replacements, $button_text );
|
2289 |
}
|
2290 |
}
|
2291 |
-
|
2292 |
if ( empty( $button_text ) ) {
|
2293 |
$button_text = __( 'Sign Up Now', 'paid-memberships-pro' );
|
2294 |
}
|
2295 |
-
|
2296 |
if ( empty( $classes ) ) {
|
2297 |
$classes = 'pmpro_btn';
|
2298 |
}
|
2299 |
-
|
2300 |
if ( ! empty( $level_id ) ) {
|
2301 |
$r = '<a href="' . pmpro_url( 'checkout', '?level=' . $level_id ) . '" class="' . $classes . '">' . $button_text . '</a>';
|
2302 |
} else {
|
2303 |
$r = '<a href="' . pmpro_url( 'checkout' ) . '" class="' . $classes . '">' . $button_text . '</a>';
|
2304 |
}
|
2305 |
-
|
2306 |
return $r;
|
2307 |
}
|
2308 |
|
@@ -2361,7 +2532,7 @@ if ( ! function_exists( 'pmpro_getMemberStartdate' ) ) {
|
|
2361 |
if ( ! empty( $level_id ) ) {
|
2362 |
$sqlQuery = "SELECT UNIX_TIMESTAMP(CONVERT_TZ(startdate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND membership_id IN(" . esc_sql( $level_id ) . ") AND user_id = '" . $user_id . "' ORDER BY id LIMIT 1";
|
2363 |
} else {
|
2364 |
-
$sqlQuery = "SELECT UNIX_TIMESTAMP(CONVERT_TZ(startdate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND user_id = '" . $user_id . "' ORDER BY id LIMIT 1";
|
2365 |
}
|
2366 |
|
2367 |
$startdate = apply_filters( 'pmpro_member_startdate', $wpdb->get_var( $sqlQuery ), $user_id, $level_id );
|
@@ -2588,21 +2759,22 @@ function pmpro_is_ready() {
|
|
2588 |
// no paid membership level now or attached to a user. we don't need the gateway setup
|
2589 |
$pmpro_gateway_ready = true;
|
2590 |
} else {
|
2591 |
-
$gateway
|
|
|
2592 |
if ( $gateway == 'authorizenet' ) {
|
2593 |
-
if (
|
2594 |
$pmpro_gateway_ready = true;
|
2595 |
} else {
|
2596 |
$pmpro_gateway_ready = false;
|
2597 |
}
|
2598 |
} elseif ( $gateway == 'paypal' || $gateway == 'paypalexpress' ) {
|
2599 |
-
if (
|
2600 |
$pmpro_gateway_ready = true;
|
2601 |
} else {
|
2602 |
$pmpro_gateway_ready = false;
|
2603 |
}
|
2604 |
} elseif ( $gateway == 'paypalstandard' ) {
|
2605 |
-
if (
|
2606 |
$pmpro_gateway_ready = true;
|
2607 |
} else {
|
2608 |
$pmpro_gateway_ready = false;
|
@@ -2614,25 +2786,29 @@ function pmpro_is_ready() {
|
|
2614 |
$pmpro_gateway_ready = false;
|
2615 |
}
|
2616 |
} elseif ( $gateway == 'stripe' ) {
|
2617 |
-
if (
|
|
|
|
|
|
|
|
|
2618 |
$pmpro_gateway_ready = true;
|
2619 |
} else {
|
2620 |
$pmpro_gateway_ready = false;
|
2621 |
}
|
2622 |
} elseif ( $gateway == 'braintree' ) {
|
2623 |
-
if (
|
2624 |
$pmpro_gateway_ready = true;
|
2625 |
} else {
|
2626 |
$pmpro_gateway_ready = false;
|
2627 |
}
|
2628 |
} elseif ( $gateway == 'twocheckout' ) {
|
2629 |
-
if (
|
2630 |
$pmpro_gateway_ready = true;
|
2631 |
} else {
|
2632 |
$pmpro_gateway_ready = false;
|
2633 |
}
|
2634 |
} elseif ( $gateway == 'cybersource' ) {
|
2635 |
-
if (
|
2636 |
$pmpro_gateway_ready = true;
|
2637 |
} else {
|
2638 |
$pmpro_gateway_ready = false;
|
@@ -2680,6 +2856,97 @@ function pmpro_is_ready() {
|
|
2680 |
return $r;
|
2681 |
}
|
2682 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2683 |
/**
|
2684 |
* Format a price per the currency settings.
|
2685 |
*
|
@@ -2724,6 +2991,35 @@ function pmpro_formatPrice( $price ) {
|
|
2724 |
return apply_filters( 'pmpro_format_price', $formatted, $price, $pmpro_currency, $pmpro_currency_symbol );
|
2725 |
}
|
2726 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2727 |
|
2728 |
/**
|
2729 |
* Function to trim trailing zeros from an amount.
|
@@ -2808,18 +3104,18 @@ function pmpro_round_price( $price, $currency = '' ) {
|
|
2808 |
}
|
2809 |
|
2810 |
if ( ! empty( $pmpro_currencies[ $currency ] )
|
2811 |
-
&& is_array( $pmpro_currencies[ $
|
2812 |
-
&&
|
2813 |
$decimals = intval( $pmpro_currencies[ $currency ]['decimals'] );
|
2814 |
}
|
2815 |
|
2816 |
$rounded = round( (double) $price, $decimals );
|
2817 |
-
|
2818 |
/**
|
2819 |
* Filter for result of pmpro_round_price.
|
2820 |
*/
|
2821 |
$rounded = apply_filters( 'pmpro_round_price', $rounded );
|
2822 |
-
|
2823 |
return $rounded;
|
2824 |
}
|
2825 |
|
@@ -2942,7 +3238,7 @@ function pmpro_isDateThisWeek( $str ) {
|
|
2942 |
return false;
|
2943 |
}
|
2944 |
}
|
2945 |
-
|
2946 |
/**
|
2947 |
* Does the dave provided fall within the current year?
|
2948 |
* Merged in from the Better Logins Report Add On.
|
@@ -3010,7 +3306,7 @@ function pmpro_generatePages( $pages ) {
|
|
3010 |
if ( ! in_array( $name, $top_level_pages ) ) {
|
3011 |
$insert['post_parent'] = $pmpro_pages['account'];
|
3012 |
}
|
3013 |
-
|
3014 |
// tweak the login slug
|
3015 |
if ( $name == 'login' ) {
|
3016 |
$insert['post_name'] = 'login';
|
@@ -3184,7 +3480,7 @@ function pmpro_is_checkout() {
|
|
3184 |
function pmpro_show_discount_code() {
|
3185 |
global $wpdb;
|
3186 |
static $show;
|
3187 |
-
|
3188 |
// check DB if we haven't yet
|
3189 |
if ( !isset( $show ) ) {
|
3190 |
if ( $wpdb->get_var( "SELECT id FROM $wpdb->pmpro_discount_codes LIMIT 1" ) ) {
|
@@ -3193,9 +3489,9 @@ function pmpro_show_discount_code() {
|
|
3193 |
$show = false;
|
3194 |
}
|
3195 |
}
|
3196 |
-
|
3197 |
$show = apply_filters( "pmpro_show_discount_code", $show );
|
3198 |
-
|
3199 |
return $show;
|
3200 |
}
|
3201 |
|
@@ -3208,35 +3504,35 @@ function pmpro_show_discount_code() {
|
|
3208 |
function pmpro_was_checkout_form_submitted() {
|
3209 |
// Default to false.
|
3210 |
$submit = false;
|
3211 |
-
|
3212 |
// Basic check for a field called submit-checkout.
|
3213 |
if ( isset( $_REQUEST['submit-checkout'] ) ) {
|
3214 |
$submit = true;
|
3215 |
}
|
3216 |
-
|
3217 |
// _x stuff in case they clicked on the image button with their mouse
|
3218 |
if ( empty( $submit ) && isset( $_REQUEST['submit-checkout_x'] ) ) {
|
3219 |
$submit = true;
|
3220 |
}
|
3221 |
-
|
3222 |
return $submit;
|
3223 |
}
|
3224 |
-
|
3225 |
/**
|
3226 |
* Build the order object used at checkout.
|
3227 |
* @since 2.1
|
3228 |
* @return mixed $order Order object.
|
3229 |
*/
|
3230 |
-
function pmpro_build_order_for_checkout() {
|
3231 |
global $post, $gateway, $wpdb, $besecure, $discount_code, $discount_code_id, $pmpro_level, $pmpro_levels, $pmpro_msg, $pmpro_msgt, $pmpro_review, $skip_account_fields, $pmpro_paypal_token, $pmpro_show_discount_code, $pmpro_error_fields, $pmpro_required_billing_fields, $pmpro_required_user_fields, $wp_version, $current_user, $pmpro_requirebilling, $tospage, $username, $password, $password2, $bfirstname, $blastname, $baddress1, $baddress2, $bcity, $bstate, $bzipcode, $bcountry, $bphone, $bemail, $bconfirmemail, $CardType, $AccountNumber, $ExpirationMonth, $ExpirationYear, $pmpro_states, $recaptcha, $recaptcha_privatekey, $CVV;
|
3232 |
-
|
3233 |
$morder = new MemberOrder();
|
3234 |
$morder->membership_id = $pmpro_level->id;
|
3235 |
$morder->membership_name = $pmpro_level->name;
|
3236 |
$morder->discount_code = $discount_code;
|
3237 |
$morder->InitialPayment = pmpro_round_price( $pmpro_level->initial_payment );
|
3238 |
$morder->PaymentAmount = pmpro_round_price( $pmpro_level->billing_amount );
|
3239 |
-
$morder->ProfileStartDate = date_i18n( "Y-m-d", current_time( "timestamp" ) )
|
3240 |
$morder->BillingPeriod = $pmpro_level->cycle_period;
|
3241 |
$morder->BillingFrequency = $pmpro_level->cycle_number;
|
3242 |
if ( $pmpro_level->billing_limit ) {
|
@@ -3248,7 +3544,7 @@ function pmpro_show_discount_code() {
|
|
3248 |
$morder->TrialBillingCycles = $pmpro_level->trial_limit;
|
3249 |
$morder->TrialAmount = pmpro_round_price( $pmpro_level->trial_amount );
|
3250 |
}
|
3251 |
-
|
3252 |
// Credit card values.
|
3253 |
$morder->cardtype = $CardType;
|
3254 |
$morder->accountnumber = $AccountNumber;
|
@@ -3257,21 +3553,21 @@ function pmpro_show_discount_code() {
|
|
3257 |
$morder->ExpirationDate = $ExpirationMonth . $ExpirationYear;
|
3258 |
$morder->ExpirationDate_YdashM = $ExpirationYear . "-" . $ExpirationMonth;
|
3259 |
$morder->CVV2 = $CVV;
|
3260 |
-
|
3261 |
// Not saving email in order table, but the sites need it.
|
3262 |
$morder->Email = $bemail;
|
3263 |
-
|
3264 |
// Save the user ID if logged in.
|
3265 |
if ( $current_user->ID ) {
|
3266 |
$morder->user_id = $current_user->ID;
|
3267 |
}
|
3268 |
-
|
3269 |
// Sometimes we need these split up.
|
3270 |
$morder->FirstName = $bfirstname;
|
3271 |
$morder->LastName = $blastname;
|
3272 |
$morder->Address1 = $baddress1;
|
3273 |
$morder->Address2 = $baddress2;
|
3274 |
-
|
3275 |
// Set other values.
|
3276 |
$morder->billing = new stdClass();
|
3277 |
$morder->billing->name = $bfirstname . " " . $blastname;
|
@@ -3280,24 +3576,24 @@ function pmpro_show_discount_code() {
|
|
3280 |
$morder->billing->state = $bstate;
|
3281 |
$morder->billing->country = $bcountry;
|
3282 |
$morder->billing->zip = $bzipcode;
|
3283 |
-
$morder->billing->phone = $bphone;
|
3284 |
$morder->gateway = $gateway;
|
3285 |
$morder->setGateway();
|
3286 |
-
|
3287 |
// Set up level var.
|
3288 |
$morder->getMembershipLevelAtCheckout();
|
3289 |
-
|
3290 |
// Set tax.
|
3291 |
$initial_tax = $morder->getTaxForPrice( $morder->InitialPayment );
|
3292 |
$recurring_tax = $morder->getTaxForPrice( $morder->PaymentAmount );
|
3293 |
-
|
3294 |
// Set amounts.
|
3295 |
$morder->initial_amount = pmpro_round_price((float)$morder->InitialPayment + (float)$initial_tax);
|
3296 |
$morder->subscription_amount = pmpro_round_price((float)$morder->PaymentAmount + (float)$recurring_tax);
|
3297 |
-
|
3298 |
// Filter for order, since v1.8
|
3299 |
$morder = apply_filters( 'pmpro_checkout_order', $morder );
|
3300 |
-
|
3301 |
return $morder;
|
3302 |
}
|
3303 |
|
@@ -3319,7 +3615,7 @@ function pmpro_check_plugin_version( $plugin_file, $comparison, $version ) {
|
|
3319 |
$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin_file, false, true );
|
3320 |
|
3321 |
// Return false if there is no plugin data.
|
3322 |
-
if ( empty( $plugin_data ) ) {
|
3323 |
return false;
|
3324 |
}
|
3325 |
|
@@ -3340,7 +3636,7 @@ function pmpro_check_plugin_version( $plugin_file, $comparison, $version ) {
|
|
3340 |
* @param string $operator Operator to use, e.g. >, <, >=, <=, =.
|
3341 |
* @return bool true or false based on the operator passed in. Returns null for invalid operators.
|
3342 |
*/
|
3343 |
-
function pmpro_int_compare( $a, $b, $operator ) {
|
3344 |
switch ( $operator ) {
|
3345 |
case '>':
|
3346 |
$r = (int)$a > (int)$b;
|
@@ -3355,13 +3651,13 @@ function pmpro_int_compare( $a, $b, $operator ) {
|
|
3355 |
$r = (int)$a <= (int)$b;
|
3356 |
break;
|
3357 |
case '=':
|
3358 |
-
case '==':
|
3359 |
$r = (int)$a == (int)$b;
|
3360 |
break;
|
3361 |
default:
|
3362 |
$r = null;
|
3363 |
}
|
3364 |
-
|
3365 |
return $r;
|
3366 |
}
|
3367 |
|
@@ -3375,7 +3671,7 @@ function pmpro_int_compare( $a, $b, $operator ) {
|
|
3375 |
*/
|
3376 |
function pmpro_insert_or_replace( $table, $data, $format, $primary_key = 'id' ) {
|
3377 |
global $wpdb;
|
3378 |
-
|
3379 |
if ( empty( $data[$primary_key] ) ) {
|
3380 |
// Insert. Remove keys first.
|
3381 |
$index = array_search( $primary_key, array_keys( $data ) );
|
@@ -3386,6 +3682,285 @@ function pmpro_insert_or_replace( $table, $data, $format, $primary_key = 'id' )
|
|
3386 |
return $wpdb->insert( $table, $data, $format );
|
3387 |
} else {
|
3388 |
// Replace.
|
3389 |
-
|
3390 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3391 |
}
|
39 |
$wpdb->pmpro_discount_codes_levels = $wpdb->prefix . 'pmpro_discount_codes_levels';
|
40 |
$wpdb->pmpro_discount_codes_uses = $wpdb->prefix . 'pmpro_discount_codes_uses';
|
41 |
$wpdb->pmpro_membership_levelmeta = $wpdb->prefix . 'pmpro_membership_levelmeta';
|
42 |
+
$wpdb->pmpro_membership_ordermeta = $wpdb->prefix . 'pmpro_membership_ordermeta';
|
43 |
}
|
44 |
pmpro_setDBTables();
|
45 |
|
84 |
}
|
85 |
}
|
86 |
|
87 |
+
function pmpro_setOption( $s, $v = null, $sanitize_function = 'sanitize_text_field', $autoload = false ) {
|
88 |
// no value is given, set v to the p var
|
89 |
if ( $v === null && isset( $_POST[ $s ] ) ) {
|
90 |
if ( is_array( $_POST[ $s ] ) ) {
|
100 |
$v = trim( $v );
|
101 |
}
|
102 |
|
103 |
+
return update_option( 'pmpro_' . $s, $v, $autoload );
|
104 |
}
|
105 |
|
106 |
function pmpro_get_slug( $post_id ) {
|
132 |
|
133 |
global $pmpro_pages;
|
134 |
|
135 |
+
if ( ! empty( $pmpro_pages[ $page ] ) ) {
|
136 |
+
// start with the permalink
|
137 |
+
$url = get_permalink( $pmpro_pages[ $page ] );
|
138 |
|
139 |
+
// WPML/etc support
|
140 |
+
if ( function_exists( 'icl_object_id' ) && defined( 'ICL_LANGUAGE_CODE' ) ) {
|
141 |
+
$trans_id = icl_object_id( $pmpro_pages[ $page ], 'page', false, ICL_LANGUAGE_CODE );
|
142 |
+
if ( ! empty( $trans_id ) ) {
|
143 |
+
$url = get_permalink( $trans_id );
|
144 |
+
}
|
145 |
}
|
146 |
+
} else {
|
147 |
+
$url = '';
|
148 |
}
|
149 |
|
150 |
// figure out querystring
|
160 |
$url = str_replace( 'http:', 'https:', $url );
|
161 |
}
|
162 |
}
|
163 |
+
|
164 |
/**
|
165 |
* Filter the URL before returning.
|
166 |
*/
|
175 |
} else {
|
176 |
$r = false;
|
177 |
}
|
178 |
+
|
179 |
$r = apply_filters( 'pmpro_is_level_free', $r, $level );
|
180 |
return $r;
|
181 |
}
|
201 |
function pmpro_onlyFreeLevels() {
|
202 |
// Get levels that are available for checkout only.
|
203 |
$levels = pmpro_getAllLevels( false, true );
|
204 |
+
|
205 |
return apply_filters( 'pmpro_only_free_levels', pmpro_areLevelsFree( $levels ) );
|
206 |
}
|
207 |
|
211 |
} else {
|
212 |
$r = false;
|
213 |
}
|
214 |
+
|
215 |
$r = apply_filters( 'pmpro_is_level_recurring', $r, $level );
|
216 |
return $r;
|
217 |
}
|
224 |
*/
|
225 |
function pmpro_has_recurring_level( $user_id = null ) {
|
226 |
global $current_user;
|
227 |
+
|
228 |
if ( empty( $user_id ) ) {
|
229 |
$user_id = $current_user->ID;
|
230 |
}
|
231 |
+
|
232 |
if ( empty( $user_id ) ) {
|
233 |
return false;
|
234 |
}
|
235 |
|
236 |
+
$levels = pmpro_getMembershipLevelsForUser( $user_id );
|
237 |
+
|
238 |
if ( empty( $levels ) ) {
|
239 |
return false;
|
240 |
}
|
241 |
+
|
242 |
+
foreach( $levels as $level ) {
|
243 |
if ( pmpro_isLevelRecurring( $level ) ) {
|
244 |
return true;
|
245 |
}
|
246 |
+
}
|
247 |
|
248 |
return false;
|
249 |
}
|
254 |
} else {
|
255 |
$r = false;
|
256 |
}
|
257 |
+
|
258 |
$r = apply_filters( 'pmpro_is_level_trial', $r, $level );
|
259 |
return $r;
|
260 |
}
|
261 |
|
262 |
function pmpro_isLevelExpiring( &$level ) {
|
263 |
if ( ! empty( $level ) && ( ! empty( $level->expiration_number ) && $level->expiration_number > 0 ) || ! empty( $level->enddate ) ) {
|
264 |
+
|
265 |
$r = true;
|
266 |
} else {
|
267 |
$r = false;
|
268 |
}
|
269 |
+
|
270 |
$r = apply_filters( 'pmpro_is_level_expiring', $r, $level );
|
271 |
return $r;
|
272 |
}
|
286 |
$standard = pmpro_getLevel( $level->id );
|
287 |
|
288 |
if ( ! empty( $standard->expiration_number ) ) {
|
289 |
+
if ( $standard->expiration_period == 'Hour' ) {
|
290 |
+
$days = $level->expiration_number;
|
291 |
+
} else if ( $standard->expiration_period == 'Day' ) {
|
292 |
$days = $level->expiration_number;
|
293 |
} elseif ( $standard->expiration_period == 'Week' ) {
|
294 |
$days = $level->expiration_number * 7;
|
304 |
// are we within the days til expiration?
|
305 |
$now = current_time( 'timestamp' );
|
306 |
|
307 |
+
if( $standard->expiration_period == 'Hour' ){
|
308 |
+
if( $now + ( $days * 60 ) >= $level->enddate ){
|
309 |
+
$r = true;
|
310 |
+
} else {
|
311 |
+
$r = false;
|
312 |
+
}
|
313 |
+
} else if ( $now + ( $days * 3600 * 24 ) >= $level->enddate ) {
|
314 |
$r = true;
|
315 |
} else {
|
316 |
$r = false;
|
392 |
if ( ! $short ) {
|
393 |
$r = sprintf( __( 'The price for membership is <strong>%s</strong> now', 'paid-memberships-pro' ), pmpro_formatPrice( $level->initial_payment ) );
|
394 |
} else {
|
395 |
+
if ( pmpro_isLevelFree( $level ) ) {
|
396 |
+
$r = '<strong>' . __('Free', 'paid-memberships-pro' ) . '</strong>';
|
397 |
+
} else {
|
398 |
+
$r = sprintf( __( '<strong>%s</strong> now', 'paid-memberships-pro' ), pmpro_formatPrice( $level->initial_payment ) );
|
399 |
+
}
|
400 |
}
|
401 |
|
402 |
// recurring part
|
403 |
+
if ( (float)$level->billing_amount > 0 ) {
|
404 |
if ( $level->billing_limit > 1 ) {
|
405 |
if ( $level->cycle_number == '1' ) {
|
406 |
$r .= sprintf( __( ' and then <strong>%1$s per %2$s for %3$d more %4$s</strong>.', 'paid-memberships-pro' ), pmpro_formatPrice( $level->billing_amount ), pmpro_translate_billing_period( $level->cycle_period ), $level->billing_limit, pmpro_translate_billing_period( $level->cycle_period, $level->billing_limit ) );
|
441 |
|
442 |
// trial part
|
443 |
if ( $level->trial_limit ) {
|
444 |
+
if ( (float)$level->trial_amount > 0 ) {
|
445 |
if ( $level->trial_limit == '1' ) {
|
446 |
$r .= ' ' . __( 'After your initial payment, your first payment is Free.', 'paid-memberships-pro' );
|
447 |
} else {
|
481 |
$trialperiods = 0;
|
482 |
foreach ( $levels as $curlevel ) {
|
483 |
$initpmt += $curlevel->initial_payment;
|
484 |
+
if ( (float)$curlevel->billing_amount > 0 ) {
|
485 |
if ( array_key_exists( $curlevel->cycle_period, $recurpmts ) ) {
|
486 |
if ( array_key_exists( $curlevel->cycle_number, $recurpmts[ $curlevel->cycle_period ] ) ) {
|
487 |
if ( array_key_exists( $curlevel->billing_limit, $recurpmts[ $curlevel->cycle_period ][ $curlevel->cycle_number ] ) ) {
|
577 |
}
|
578 |
|
579 |
function pmpro_getLevelExpiration( &$level ) {
|
580 |
+
|
581 |
if ( $level->expiration_number ) {
|
582 |
$expiration_text = sprintf( __( 'Membership expires after %1$d %2$s.', 'paid-memberships-pro' ), $level->expiration_number, pmpro_translate_billing_period( $level->expiration_period, $level->expiration_number ) );
|
583 |
} else {
|
626 |
* Filter the levels expiration text. Note the s in levels. Similar to pmpro_levels_expiration_text
|
627 |
*/
|
628 |
$expiration_text = apply_filters( 'pmpro_levels_expiration_text', $expiration_text, $levels );
|
629 |
+
|
630 |
// Backwards compatible
|
631 |
if ( ! empty( $levels ) ) {
|
632 |
$first_level = reset($levels);
|
634 |
$first_level = false;
|
635 |
}
|
636 |
$expiration_text = apply_filters( 'pmpro_level_expiration_text', $expiration_text, $first_level );
|
637 |
+
|
638 |
return $expiration_text;
|
639 |
}
|
640 |
|
647 |
return add_metadata( 'pmpro_membership_level', $level_id, $meta_key, $meta_value, $unique );
|
648 |
}
|
649 |
|
650 |
+
function get_pmpro_membership_level_meta( $level_id, $key = '', $single = false ) {
|
651 |
return get_metadata( 'pmpro_membership_level', $level_id, $key, $single );
|
652 |
}
|
653 |
|
659 |
return delete_metadata( 'pmpro_membership_level', $level_id, $meta_key, $meta_value );
|
660 |
}
|
661 |
|
662 |
+
/**
|
663 |
+
* pmpro_membership_order Meta Functions
|
664 |
+
*/
|
665 |
+
function add_pmpro_membership_order_meta( $order_id, $meta_key, $meta_value, $unique = false ) {
|
666 |
+
return add_metadata( 'pmpro_membership_order', $order_id, $meta_key, $meta_value, $unique );
|
667 |
+
}
|
668 |
+
|
669 |
+
function get_pmpro_membership_order_meta( $order_id, $key = '', $single = false ) {
|
670 |
+
return get_metadata( 'pmpro_membership_order', $order_id, $key, $single );
|
671 |
+
}
|
672 |
+
|
673 |
+
function update_pmpro_membership_order_meta( $order_id, $meta_key, $meta_value, $prev_value = '' ) {
|
674 |
+
return update_metadata( 'pmpro_membership_order', $order_id, $meta_key, $meta_value, $prev_value );
|
675 |
+
}
|
676 |
+
|
677 |
+
function delete_pmpro_membership_order_meta( $order_id, $meta_key, $meta_value = '' ) {
|
678 |
+
return delete_metadata( 'pmpro_membership_order', $order_id, $meta_key, $meta_value );
|
679 |
+
}
|
680 |
+
|
681 |
function pmpro_hideAds() {
|
682 |
global $pmpro_display_ads;
|
683 |
return ! $pmpro_display_ads;
|
960 |
* @param int $level ID of level to set as new level, use 0 to cancel membership
|
961 |
* @param int $user_id ID of the user to change levels for
|
962 |
* @param string $old_level_status The status to set for the row in the memberships users table. (e.g. inactive, cancelled, admin_cancelled, expired) Defaults to 'inactive'.
|
963 |
+
* @param int $cancel_level If set cancel just this one level instead of all active levels (to support Multiple Memberships per User)
|
964 |
*
|
965 |
* Return values:
|
966 |
* Success returns boolean true.
|
967 |
* Failure returns boolean false.
|
968 |
+
* No change returns null.
|
969 |
*/
|
970 |
function pmpro_changeMembershipLevel( $level, $user_id = null, $old_level_status = 'inactive', $cancel_level = null ) {
|
971 |
global $wpdb;
|
983 |
// make sure user id is int for security
|
984 |
$user_id = intval( $user_id );
|
985 |
|
986 |
+
/**
|
987 |
+
* Filter the level passed in.
|
988 |
+
* @since 2.5.8
|
989 |
+
*/
|
990 |
+
$level = apply_filters( 'pmpro_change_level', $level, $user_id, $old_level_status, $cancel_level );
|
991 |
+
|
992 |
if ( empty( $level ) ) {
|
993 |
$level = 0;
|
994 |
} else if ( is_array( $level ) ) {
|
1019 |
if ( ! is_array( $level ) ) {
|
1020 |
// are they even changing?
|
1021 |
if ( pmpro_hasMembershipLevel( $level, $user_id ) ) {
|
1022 |
+
return;
|
|
|
1023 |
}
|
1024 |
}
|
1025 |
|
1026 |
// get all active membershipships for this user
|
1027 |
$old_levels = pmpro_getMembershipLevelsForUser( $user_id );
|
1028 |
|
1029 |
+
global $pmpro_old_user_levels;
|
1030 |
+
if ( empty( $pmpro_old_user_levels ) ) {
|
1031 |
+
$pmpro_old_user_levels = array();
|
1032 |
+
}
|
1033 |
+
if ( ! array_key_exists( $user_id, $pmpro_old_user_levels ) ) {
|
1034 |
+
$pmpro_old_user_levels[$user_id] = empty( $old_levels ) ? array() : $old_levels;
|
1035 |
+
}
|
1036 |
+
|
1037 |
// get level id
|
1038 |
if ( is_array( $level ) ) {
|
1039 |
$level_id = $level['membership_id']; // custom level
|
1047 |
* @param int $level_id ID of the level changed to.
|
1048 |
* @param int $user_id ID of the user changed.
|
1049 |
* @param array $old_levels array of prior levels the user belonged to.
|
1050 |
+
* @param int $cancel_level ID of the level being cancelled if specified
|
1051 |
*/
|
1052 |
do_action( 'pmpro_before_change_membership_level', $level_id, $user_id, $old_levels, $cancel_level );
|
1053 |
|
1126 |
|
1127 |
if ( ! empty( $c_order->error ) ) {
|
1128 |
$pmpro_error = $c_order->error;
|
1129 |
+
}
|
1130 |
+
|
1131 |
+
if( $old_level_status == 'error' ) {
|
1132 |
+
$c_order->updateStatus("error");
|
1133 |
}
|
1134 |
}
|
1135 |
}
|
1191 |
$pmpro_error = sprintf( __( 'Error interacting with database: %s', 'paid-memberships-pro' ), ( ! empty( $wpdb->last_error ) ? $wpdb->last_error : 'unavailable' ) );
|
1192 |
return false;
|
1193 |
}
|
1194 |
+
|
1195 |
+
/**
|
1196 |
+
* Allow filtering whether to remove duplicate "active" memberships by setting them to "changed".
|
1197 |
+
*
|
1198 |
+
* @since 2.6.6
|
1199 |
+
*
|
1200 |
+
* @param bool $remove_duplicate_memberships Whether to remove duplicate "active" memberships by setting them to "changed".
|
1201 |
+
*/
|
1202 |
+
$remove_duplicate_memberships = apply_filters( 'pmpro_remove_duplicate_membership_entries', true );
|
1203 |
+
|
1204 |
+
if ( $remove_duplicate_memberships ) {
|
1205 |
+
$wpdb->query(
|
1206 |
+
$wpdb->prepare(
|
1207 |
+
"
|
1208 |
+
UPDATE {$wpdb->pmpro_memberships_users}
|
1209 |
+
SET status = %s,
|
1210 |
+
enddate = %s
|
1211 |
+
WHERE user_id = %d
|
1212 |
+
AND membership_id = %d
|
1213 |
+
AND status = %s
|
1214 |
+
AND id != %d
|
1215 |
+
",
|
1216 |
+
'changed',
|
1217 |
+
current_time( 'mysql' ),
|
1218 |
+
$user_id,
|
1219 |
+
$level_id,
|
1220 |
+
'active',
|
1221 |
+
$wpdb->insert_id // Ignore the membership that we just added.
|
1222 |
+
)
|
1223 |
+
);
|
1224 |
+
}
|
1225 |
}
|
1226 |
|
1227 |
// remove cached level
|
1228 |
global $all_membership_levels;
|
1229 |
unset( $all_membership_levels[ $user_id ] );
|
1230 |
+
|
1231 |
// remove levels cache for user
|
1232 |
$cache_key = 'user_' . $user_id . '_levels';
|
1233 |
wp_cache_delete( $cache_key, 'pmpro' );
|
1234 |
+
wp_cache_delete( $cache_key . '_all', 'pmpro' );
|
1235 |
+
wp_cache_delete( $cache_key . '_active', 'pmpro' );
|
1236 |
|
1237 |
// update user data and call action
|
1238 |
pmpro_set_current_user();
|
1242 |
*
|
1243 |
* @param int $level_id ID of the level changed to.
|
1244 |
* @param int $user_id ID of the user changed.
|
1245 |
+
* @param int $cancel_level ID of the level being cancelled if specified.
|
1246 |
*/
|
1247 |
do_action( 'pmpro_after_change_membership_level', $level_id, $user_id, $cancel_level );
|
1248 |
return true;
|
1249 |
}
|
1250 |
|
1251 |
+
/**
|
1252 |
+
* Runs after all membership level changes have been performed.
|
1253 |
+
*
|
1254 |
+
* @param mixed $filter_contents to not break the wp_redirect filter.
|
1255 |
+
*/
|
1256 |
+
function pmpro_do_action_after_all_membership_level_changes( $filter_contents = null ) {
|
1257 |
+
global $pmpro_old_user_levels;
|
1258 |
+
if ( empty( $pmpro_old_user_levels ) ) {
|
1259 |
+
// No level changes occured, return.
|
1260 |
+
return $filter_contents;
|
1261 |
+
}
|
1262 |
+
|
1263 |
+
// Clear global so that we don't run twice for same level changes
|
1264 |
+
$pmpro_old_user_levels_copy = $pmpro_old_user_levels;
|
1265 |
+
$pmpro_old_user_levels = null;
|
1266 |
+
|
1267 |
+
/**
|
1268 |
+
* Run code after all membership level changes have occured. Users who have had changes
|
1269 |
+
* will be stored in the global $pmpro_old_user_levels array.
|
1270 |
+
*
|
1271 |
+
* @since 2.6
|
1272 |
+
* @param array $pmpro_old_user_levels_copy array of user_id => array( old_level_objs )
|
1273 |
+
*/
|
1274 |
+
do_action( 'pmpro_after_all_membership_level_changes', $pmpro_old_user_levels_copy );
|
1275 |
+
|
1276 |
+
return $filter_contents;
|
1277 |
+
}
|
1278 |
+
add_action( 'template_redirect', 'pmpro_do_action_after_all_membership_level_changes', 2 );
|
1279 |
+
add_filter( 'wp_redirect', 'pmpro_do_action_after_all_membership_level_changes', 100 );
|
1280 |
+
add_action( 'pmpro_membership_post_membership_expiry', 'pmpro_do_action_after_all_membership_level_changes' );
|
1281 |
+
add_action( 'shutdown', 'pmpro_do_action_after_all_membership_level_changes' );
|
1282 |
+
|
1283 |
/**
|
1284 |
* Function to list WordPress categories in hierarchical format.
|
1285 |
*
|
1317 |
/*
|
1318 |
pmpro_toggleMembershipCategory() creates or deletes a linking entry between the membership level and post category tables.
|
1319 |
*
|
1320 |
+
* @param $level may either be the ID or name of the desired membership_level.
|
1321 |
+
* @param $category must be a valid post category ID.
|
1322 |
+
* @param $value
|
1323 |
*
|
1324 |
* Return values:
|
1325 |
* Success returns boolean true.
|
1357 |
pmpro_updateMembershipCategories() ensures that all those and only those categories given
|
1358 |
* are associated with the given membership level.
|
1359 |
*
|
1360 |
+
* @param $level is a valid membership level ID or name
|
1361 |
+
* @param $categories is an array of post category IDs
|
1362 |
*
|
1363 |
* Return values:
|
1364 |
* Success returns boolean true.
|
1396 |
/*
|
1397 |
pmpro_getMembershipCategories() returns the categories for a given level
|
1398 |
*
|
1399 |
+
* @param $level_id is a valid membership level ID
|
1400 |
*
|
1401 |
* Return values:
|
1402 |
* Success returns boolean true.
|
1409 |
$categories = $wpdb->get_col(
|
1410 |
"SELECT c.category_id
|
1411 |
FROM {$wpdb->pmpro_memberships_categories} AS c
|
1412 |
+
WHERE c.membership_id = '" . esc_sql( $level_id ) . "'"
|
1413 |
);
|
1414 |
|
1415 |
return $categories;
|
1417 |
|
1418 |
|
1419 |
function pmpro_isAdmin( $user_id = null ) {
|
1420 |
+
global $current_user;
|
1421 |
if ( ! $user_id ) {
|
1422 |
$user_id = $current_user->ID;
|
1423 |
}
|
1473 |
}
|
1474 |
|
1475 |
// function to return the pagination string
|
1476 |
+
function pmpro_getPaginationString( $page = 1, $totalitems = 0, $limit = 15, $adjacents = 1, $targetpage = '/', $pagestring = '&pn=' ) {
|
1477 |
// defaults
|
1478 |
if ( ! $adjacents ) {
|
1479 |
$adjacents = 1;
|
1633 |
UNION
|
1634 |
SELECT SUM((365/cycle_number)*billing_amount) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND cycle_period = 'Day' AND cycle_number <> 365 $user_ids_query
|
1635 |
UNION
|
1636 |
+
SELECT SUM((24/cycle_number)*billing_amount) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND cycle_period = 'Hour' AND cycle_number <> 24 $user_ids_query
|
1637 |
+
UNION
|
1638 |
SELECT SUM((52/cycle_number)*billing_amount) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND cycle_period = 'Week' AND cycle_number <> 52 $user_ids_query
|
1639 |
UNION
|
1640 |
SELECT SUM(billing_amount) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND cycle_period = 'Year' $user_ids_query
|
1680 |
$username = $lastname;
|
1681 |
}
|
1682 |
|
1683 |
+
// If no username yet or one based on name exists,
|
1684 |
// try to create username using email address.
|
1685 |
if ( ( empty( $username ) || username_exists( $username ) )
|
1686 |
&& ! empty( $email ) && is_email( $email ) ) {
|
1725 |
function pmpro_getDiscountCode( $seed = null ) {
|
1726 |
global $wpdb;
|
1727 |
|
1728 |
+
// We mix this with the seed to make sure we get unique codes.
|
1729 |
+
static $count = 0;
|
1730 |
+
$count++;
|
1731 |
+
|
1732 |
while ( empty( $code ) ) {
|
1733 |
+
$scramble = md5( AUTH_KEY . microtime() . $seed . SECURE_AUTH_KEY . $count );
|
1734 |
$code = substr( $scramble, 0, 10 );
|
1735 |
$check = $wpdb->get_var( "SELECT code FROM $wpdb->pmpro_discount_codes WHERE code = '" . esc_sql( $code ) . "' LIMIT 1" );
|
1736 |
if ( $check || is_numeric( $code ) ) {
|
1770 |
$dbcode->expires = strtotime( date_i18n( 'm/d/Y', $dbcode->expires ) );
|
1771 |
|
1772 |
// today
|
1773 |
+
$today = strtotime( date_i18n( 'm/d/Y H:i:00', current_time( 'timestamp' ) ) );
|
1774 |
|
1775 |
// has this code started yet?
|
1776 |
if ( ! empty( $dbcode->starts ) && $dbcode->starts > $today ) {
|
1788 |
// have we run out of uses?
|
1789 |
if ( ! $error ) {
|
1790 |
if ( $dbcode->uses > 0 ) {
|
1791 |
+
$used = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->pmpro_discount_codes_uses WHERE code_id = '" . esc_sql( $dbcode->id ) . "'" );
|
1792 |
if ( $used >= $dbcode->uses ) {
|
1793 |
$error = __( 'This discount code is no longer valid.', 'paid-memberships-pro' );
|
1794 |
}
|
1806 |
} else {
|
1807 |
$level_id = intval( $level_id );
|
1808 |
}
|
1809 |
+
$code_level = $wpdb->get_row( "SELECT l.id, cl.*, l.name, l.description, l.allow_signups FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id WHERE cl.code_id = '" . esc_sql( $dbcode->id ) . "' AND cl.level_id IN (" . esc_sql( $level_id ) . ") LIMIT 1" );
|
1810 |
|
1811 |
if ( empty( $code_level ) ) {
|
1812 |
$error = __( 'This discount code does not apply to this membership level.', 'paid-memberships-pro' );
|
1821 |
*
|
1822 |
* @param bool $okay true if code check is okay or false if there was an error
|
1823 |
* @param object $dbcode Object containing code data from the database row
|
1824 |
+
* @param int|array $level_id ID of the level the user is checking out for.
|
1825 |
* @param string $code Discount code string.
|
1826 |
*
|
1827 |
* @return mixed $okay true if okay, false or error message string if not okay
|
2031 |
if ( empty( $all_membership_levels[ $user_id ] ) ) {
|
2032 |
$all_membership_levels[ $user_id ] = false;
|
2033 |
}
|
2034 |
+
|
2035 |
// Round off prices
|
2036 |
if ( ! empty( $all_membership_levels[$user_id] ) ) {
|
2037 |
if ( isset( $all_membership_levels[$user_id]->initial_payment ) ) {
|
2084 |
$user_id = intval( $user_id );
|
2085 |
|
2086 |
global $wpdb;
|
2087 |
+
|
2088 |
/**
|
2089 |
* We are going to see if cache is set before doing the query and use that if it is.
|
2090 |
+
*
|
2091 |
* In a default environment with no external object cache, the value is cached in that request and
|
2092 |
* reduces future MySQL requests. If there is an external object cache like Redis then it will be
|
2093 |
* persisted until the user level changes.
|
2094 |
**/
|
2095 |
+
$cache_key = 'user_' . $user_id . '_levels' . ( $include_inactive ? '_all' : '_active' );
|
2096 |
$levels = wp_cache_get( $cache_key, 'pmpro' );
|
2097 |
+
|
2098 |
if ( $levels === false ) {
|
2099 |
+
|
2100 |
$levels = $wpdb->get_results(
|
2101 |
"SELECT
|
2102 |
l.id AS ID,
|
2124 |
);
|
2125 |
wp_cache_set( $cache_key, $levels, 'pmpro', 3600 );
|
2126 |
}
|
2127 |
+
|
2128 |
// Round off prices
|
2129 |
if ( ! empty( $levels ) ) {
|
2130 |
foreach( $levels as $key => $level ) {
|
2133 |
$levels[$key]->trial_amount = pmpro_round_price( $level->trial_amount );
|
2134 |
}
|
2135 |
}
|
2136 |
+
|
2137 |
/**
|
2138 |
* pmpro_get_membership_levels_for_user filter.
|
2139 |
*
|
2152 |
* Get a specific membership level for a user if they have that level.
|
2153 |
* This is better to use when MMPU is enabled on the site.
|
2154 |
*
|
2155 |
+
* If $user_id is null, the value will be retrieved from $current_user.
|
2156 |
*
|
2157 |
* Return values:
|
2158 |
* Success returns the level object.
|
2161 |
* @param int $user_id User ID to check for
|
2162 |
* @param int $level_id Level ID to check for.
|
2163 |
*/
|
2164 |
+
function pmpro_getSpecificMembershipLevelForUser( $user_id, $level_id ) {
|
2165 |
if ( empty( $user_id ) ) {
|
2166 |
global $current_user;
|
2167 |
$user_id = $current_user->ID;
|
2185 |
/*
|
2186 |
pmpro_getLevel() returns the level object for a level
|
2187 |
*
|
2188 |
+
* @param $level may be the level id or name
|
2189 |
*
|
2190 |
* Return values:
|
2191 |
* Success returns the level object.
|
2205 |
return $pmpro_levels[ $level_id ];
|
2206 |
} else {
|
2207 |
global $wpdb;
|
2208 |
+
$pmpro_levels[ $level_id ] = $wpdb->get_row( "SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql( $level_id ) . "' LIMIT 1" );
|
2209 |
}
|
2210 |
} else {
|
2211 |
global $wpdb;
|
2217 |
return false;
|
2218 |
}
|
2219 |
|
2220 |
+
$pmpro_levels[ $level_id ] = $level_obj;
|
2221 |
}
|
2222 |
+
|
2223 |
// Round prices
|
2224 |
if ( ! empty( $pmpro_levels[ $level_id ] ) ) {
|
2225 |
$pmpro_levels[ $level_id ]->initial_payment = pmpro_round_price( $pmpro_levels[ $level_id ]->initial_payment );
|
2226 |
$pmpro_levels[ $level_id ]->billing_amount = pmpro_round_price( $pmpro_levels[ $level_id ]->billing_amount );
|
2227 |
$pmpro_levels[ $level_id ]->trial_amount = pmpro_round_price( $pmpro_levels[ $level_id ]->trial_amount );
|
2228 |
}
|
2229 |
+
|
2230 |
return $pmpro_levels[ $level_id ];
|
2231 |
}
|
2232 |
|
2233 |
/*
|
2234 |
Get all PMPro membership levels.
|
2235 |
+
|
2236 |
@param bool $include_hidden Include levels marked as hidden/inactive.
|
2237 |
@param bool $use_cache If false, use $pmpro_levels global. If true use other caches.
|
2238 |
@param bool $force Resets the static var caches as well.
|
2279 |
$raw_level->trial_amount = pmpro_round_price( $raw_level->trial_amount );
|
2280 |
$pmpro_levels[ $raw_level->id ] = $raw_level;
|
2281 |
}
|
2282 |
+
|
2283 |
// Store an extra cache specific to the include_hidden param.
|
2284 |
if ( $include_hidden ) {
|
2285 |
$pmpro_all_levels = $pmpro_levels;
|
2308 |
|
2309 |
/**
|
2310 |
* Get level at checkout and place into $pmpro_level global.
|
2311 |
+
* If no level is passed or found in the URL parameters, global vars,
|
2312 |
+
* or in the post options, then this will return the first level found.
|
2313 |
+
* @param int $level_id (optional) Pass a level ID to force that level.
|
2314 |
+
* @param string $discount_code (optional) Pass a discount code to force that code.
|
2315 |
*/
|
2316 |
function pmpro_getLevelAtCheckout( $level_id = null, $discount_code = null ) {
|
2317 |
global $pmpro_level, $wpdb, $post;
|
2333 |
if ( empty( $level_id ) ) {
|
2334 |
$all_levels = pmpro_getAllLevels( false, false );
|
2335 |
|
2336 |
+
if ( ! empty( $all_levels ) ) {
|
2337 |
+
// Get lowest level ID.
|
2338 |
+
$default_level = min( array_keys( $all_levels ) );
|
2339 |
+
} else {
|
2340 |
+
$default_level = null;
|
2341 |
+
}
|
2342 |
|
2343 |
$level_id = apply_filters( 'pmpro_default_level', intval( $default_level ) );
|
2344 |
+
|
2345 |
// Bail back to levels page if level ID is empty or less than 1.
|
2346 |
if ( empty( $level_id ) || $level_id < 1 || ! is_int( $level_id ) ) {
|
2347 |
return;
|
2356 |
|
2357 |
// what level are they purchasing? (discount code passed)
|
2358 |
if ( ! empty( $level_id ) && ! empty( $discount_code ) ) {
|
2359 |
+
$discount_code_id = $wpdb->get_var( "SELECT id FROM $wpdb->pmpro_discount_codes WHERE code = '" . esc_sql( $discount_code ) . "' LIMIT 1" );
|
2360 |
|
2361 |
// check code
|
2362 |
+
global $pmpro_checkout_level_ids; // Set by MMPU.
|
2363 |
+
if ( isset( $pmpro_checkout_level_ids ) ) {
|
2364 |
+
$code_check = pmpro_checkDiscountCode( $discount_code, $pmpro_checkout_level_ids, true );
|
2365 |
+
} else {
|
2366 |
+
$code_check = pmpro_checkDiscountCode( $discount_code, $level_id, true );
|
2367 |
+
}
|
2368 |
if ( $code_check[0] != false ) {
|
2369 |
+
$sqlQuery = "SELECT l.id, cl.*, l.name, l.description, l.allow_signups, l.confirmation FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id LEFT JOIN $wpdb->pmpro_discount_codes dc ON dc.id = cl.code_id WHERE dc.code = '" . esc_sql( $discount_code ) . "' AND cl.level_id = '" . esc_sql( $level_id ) . "' LIMIT 1";
|
2370 |
$pmpro_level = $wpdb->get_row( $sqlQuery );
|
2371 |
|
2372 |
// if the discount code doesn't adjust the level, let's just get the straight level
|
2373 |
if ( empty( $pmpro_level ) ) {
|
2374 |
+
$pmpro_level = $wpdb->get_row( "SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql( $level_id ) . "' LIMIT 1" );
|
2375 |
}
|
2376 |
|
2377 |
// filter adjustments to the level
|
2394 |
return $pmpro_level;
|
2395 |
}
|
2396 |
|
2397 |
+
/**
|
2398 |
+
* Get an ordered list of level objects or level IDs.
|
2399 |
+
*
|
2400 |
+
* @param array $pmpro_levels An array of level objects or level IDs to be reordered.
|
2401 |
+
* @return array $pmpro_levels An ordered array of level objects or level IDs.
|
2402 |
+
*
|
2403 |
+
*/
|
2404 |
+
function pmpro_sort_levels_by_order( $pmpro_levels ) {
|
2405 |
+
$pmpro_level_order = pmpro_getOption( 'level_order' );
|
2406 |
+
|
2407 |
+
// No custom sort order, just return.
|
2408 |
+
if ( empty( $pmpro_level_order ) ) {
|
2409 |
+
return $pmpro_levels;
|
2410 |
+
}
|
2411 |
+
|
2412 |
+
// Convert the level order option to an array.
|
2413 |
+
$sort_order = explode( ',',$pmpro_level_order );
|
2414 |
+
|
2415 |
+
// Reorder the array.
|
2416 |
+
$reordered_levels = array();
|
2417 |
+
foreach ( $sort_order as $level_id ) {
|
2418 |
+
foreach ( $pmpro_levels as $key => $level ) {
|
2419 |
+
if ( ! empty ( $level->id ) && $level_id == $level->id ) {
|
2420 |
+
$reordered_levels[$level_id] = $pmpro_levels[$key];
|
2421 |
+
} elseif ( ! empty( $level ) && is_string( $level ) && $level_id == $level ) {
|
2422 |
+
$reordered_levels[$level_id] = $pmpro_levels[$key];
|
2423 |
+
}
|
2424 |
+
}
|
2425 |
+
}
|
2426 |
+
$pmpro_levels = $reordered_levels;
|
2427 |
+
|
2428 |
+
return $pmpro_levels;
|
2429 |
+
}
|
2430 |
+
|
2431 |
function pmpro_getCheckoutButton( $level_id, $button_text = null, $classes = null ) {
|
2432 |
if ( ! empty( $level_id ) ) {
|
2433 |
// get level
|
2434 |
$level = pmpro_getLevel( $level_id );
|
2435 |
|
2436 |
if( ! empty( $level ) ) {
|
2437 |
+
|
2438 |
// default button text with name field for replacement
|
2439 |
if ( empty( $button_text ) ) {
|
2440 |
$button_text = __( 'Sign Up for !!name!! Now', 'paid-memberships-pro' );
|
2441 |
}
|
2442 |
+
|
2443 |
// replace vars
|
2444 |
$replacements = array(
|
2445 |
'!!id!!' => $level->id,
|
2459 |
$button_text = str_replace( array_keys( $replacements ), $replacements, $button_text );
|
2460 |
}
|
2461 |
}
|
2462 |
+
|
2463 |
if ( empty( $button_text ) ) {
|
2464 |
$button_text = __( 'Sign Up Now', 'paid-memberships-pro' );
|
2465 |
}
|
2466 |
+
|
2467 |
if ( empty( $classes ) ) {
|
2468 |
$classes = 'pmpro_btn';
|
2469 |
}
|
2470 |
+
|
2471 |
if ( ! empty( $level_id ) ) {
|
2472 |
$r = '<a href="' . pmpro_url( 'checkout', '?level=' . $level_id ) . '" class="' . $classes . '">' . $button_text . '</a>';
|
2473 |
} else {
|
2474 |
$r = '<a href="' . pmpro_url( 'checkout' ) . '" class="' . $classes . '">' . $button_text . '</a>';
|
2475 |
}
|
2476 |
+
|
2477 |
return $r;
|
2478 |
}
|
2479 |
|
2532 |
if ( ! empty( $level_id ) ) {
|
2533 |
$sqlQuery = "SELECT UNIX_TIMESTAMP(CONVERT_TZ(startdate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND membership_id IN(" . esc_sql( $level_id ) . ") AND user_id = '" . $user_id . "' ORDER BY id LIMIT 1";
|
2534 |
} else {
|
2535 |
+
$sqlQuery = "SELECT UNIX_TIMESTAMP(CONVERT_TZ(startdate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND user_id = '" . esc_sql( $user_id ) . "' ORDER BY id LIMIT 1";
|
2536 |
}
|
2537 |
|
2538 |
$startdate = apply_filters( 'pmpro_member_startdate', $wpdb->get_var( $sqlQuery ), $user_id, $level_id );
|
2759 |
// no paid membership level now or attached to a user. we don't need the gateway setup
|
2760 |
$pmpro_gateway_ready = true;
|
2761 |
} else {
|
2762 |
+
$gateway = pmpro_getOption( 'gateway' );
|
2763 |
+
$gateway_environment = pmpro_getOption( 'gateway_environment' );
|
2764 |
if ( $gateway == 'authorizenet' ) {
|
2765 |
+
if ( $gateway_environment && pmpro_getOption( 'loginname' ) && pmpro_getOption( 'transactionkey' ) ) {
|
2766 |
$pmpro_gateway_ready = true;
|
2767 |
} else {
|
2768 |
$pmpro_gateway_ready = false;
|
2769 |
}
|
2770 |
} elseif ( $gateway == 'paypal' || $gateway == 'paypalexpress' ) {
|
2771 |
+
if ( $gateway_environment && pmpro_getOption( 'gateway_email' ) && pmpro_getOption( 'apiusername' ) && pmpro_getOption( 'apipassword' ) && pmpro_getOption( 'apisignature' ) ) {
|
2772 |
$pmpro_gateway_ready = true;
|
2773 |
} else {
|
2774 |
$pmpro_gateway_ready = false;
|
2775 |
}
|
2776 |
} elseif ( $gateway == 'paypalstandard' ) {
|
2777 |
+
if ( $gateway_environment && pmpro_getOption( 'gateway_email' ) ) {
|
2778 |
$pmpro_gateway_ready = true;
|
2779 |
} else {
|
2780 |
$pmpro_gateway_ready = false;
|
2786 |
$pmpro_gateway_ready = false;
|
2787 |
}
|
2788 |
} elseif ( $gateway == 'stripe' ) {
|
2789 |
+
if ( $gateway_environment && pmpro_getOption( 'stripe_secretkey' ) && pmpro_getOption( 'stripe_publishablekey' ) ) {
|
2790 |
+
// Using legacy keys.
|
2791 |
+
$pmpro_gateway_ready = true;
|
2792 |
+
} elseif ( $gateway_environment && pmpro_getOption( $gateway_environment . '_stripe_connect_secretkey' ) && pmpro_getOption( $gateway_environment . '_stripe_connect_publishablekey' ) ) {
|
2793 |
+
// Using connect.
|
2794 |
$pmpro_gateway_ready = true;
|
2795 |
} else {
|
2796 |
$pmpro_gateway_ready = false;
|
2797 |
}
|
2798 |
} elseif ( $gateway == 'braintree' ) {
|
2799 |
+
if ( $gateway_environment && pmpro_getOption( 'braintree_merchantid' ) && pmpro_getOption( 'braintree_publickey' ) && pmpro_getOption( 'braintree_privatekey' ) ) {
|
2800 |
$pmpro_gateway_ready = true;
|
2801 |
} else {
|
2802 |
$pmpro_gateway_ready = false;
|
2803 |
}
|
2804 |
} elseif ( $gateway == 'twocheckout' ) {
|
2805 |
+
if ( $gateway_environment && pmpro_getOption( 'twocheckout_apiusername' ) && pmpro_getOption( 'twocheckout_apipassword' ) ) {
|
2806 |
$pmpro_gateway_ready = true;
|
2807 |
} else {
|
2808 |
$pmpro_gateway_ready = false;
|
2809 |
}
|
2810 |
} elseif ( $gateway == 'cybersource' ) {
|
2811 |
+
if ( $gateway_environment && pmpro_getOption( 'cybersource_merchantid' ) && pmpro_getOption( 'cybersource_securitykey' ) ) {
|
2812 |
$pmpro_gateway_ready = true;
|
2813 |
} else {
|
2814 |
$pmpro_gateway_ready = false;
|
2856 |
return $r;
|
2857 |
}
|
2858 |
|
2859 |
+
/**
|
2860 |
+
* Display Invoice Price Data with Parts
|
2861 |
+
*
|
2862 |
+
* @param object $pmpro_invoice The full order object.
|
2863 |
+
* @param string $format Format of the return value. Accepts array, span, list, or line_breaks.
|
2864 |
+
*
|
2865 |
+
* @return array|string $price_parts The array or formatted HTML string to display price parts and total.
|
2866 |
+
*
|
2867 |
+
*/
|
2868 |
+
function pmpro_get_price_parts( $pmpro_invoice, $format = 'array' ) {
|
2869 |
+
$pmpro_price_parts = array();
|
2870 |
+
|
2871 |
+
if ( ! empty( $pmpro_invoice->subtotal ) && $pmpro_invoice->subtotal != $pmpro_invoice->total ) {
|
2872 |
+
$pmpro_price_parts['subtotal'] = array(
|
2873 |
+
'label' => __( 'Subtotal', 'paid-memberships-pro' ),
|
2874 |
+
'value' => pmpro_escape_price( pmpro_formatPrice( $pmpro_invoice->subtotal ) ),
|
2875 |
+
);
|
2876 |
+
}
|
2877 |
+
|
2878 |
+
if ( ! empty( $pmpro_invoice->tax ) ) {
|
2879 |
+
$pmpro_price_parts['tax'] = array(
|
2880 |
+
'label' => __( 'Tax', 'paid-memberships-pro' ),
|
2881 |
+
'value' => pmpro_escape_price( pmpro_formatPrice( $pmpro_invoice->tax ) ),
|
2882 |
+
);
|
2883 |
+
}
|
2884 |
+
|
2885 |
+
if ( ! empty( $pmpro_invoice->couponamount ) ) {
|
2886 |
+
// We don't even use this but it is in the database so it could be shown here.
|
2887 |
+
$pmpro_price_parts['couponamount'] = array(
|
2888 |
+
'label' => __( 'Coupon', 'paid-memberships-pro' ),
|
2889 |
+
'value' => pmpro_escape_price( pmpro_formatPrice( $pmpro_invoice->couponamount ) ),
|
2890 |
+
);
|
2891 |
+
}
|
2892 |
+
|
2893 |
+
/**
|
2894 |
+
* Filter to modify the price parts, add parts, or modify the display. Does not include the order total.
|
2895 |
+
*
|
2896 |
+
* @param array $pmpro_price_parts The array of price parts not including the total.
|
2897 |
+
* @param string $format Format of the return value passed to the function.
|
2898 |
+
* @param object $pmpro_invoice The full order object.
|
2899 |
+
*
|
2900 |
+
* @return array $pmpro_price_parts Filtered array of price parts not including the total.
|
2901 |
+
*
|
2902 |
+
*/
|
2903 |
+
$pmpro_price_parts = apply_filters( 'pmpro_get_price_parts', $pmpro_price_parts, $pmpro_invoice );
|
2904 |
+
|
2905 |
+
$pmpro_price_parts_with_total = $pmpro_price_parts;
|
2906 |
+
|
2907 |
+
if ( ! empty( $pmpro_invoice->total ) ) {
|
2908 |
+
$pmpro_price_parts_with_total['total'] = array(
|
2909 |
+
'label' => __( 'Total', 'paid-memberships-pro' ),
|
2910 |
+
'value' => pmpro_escape_price( pmpro_formatPrice( $pmpro_invoice->total ) ),
|
2911 |
+
);
|
2912 |
+
}
|
2913 |
+
|
2914 |
+
/**
|
2915 |
+
* Filter including the total price to modify the price parts, add parts, or modify the display.
|
2916 |
+
*
|
2917 |
+
* @param array $pmpro_price_parts The array of price parts including the total.
|
2918 |
+
* @param string $format Format of the return value passed to the function.
|
2919 |
+
* @param object $pmpro_invoice The full order object.
|
2920 |
+
*
|
2921 |
+
* @return array $pmpro_price_parts Filtered array of price parts not including the total.
|
2922 |
+
*
|
2923 |
+
*/
|
2924 |
+
$pmpro_price_parts_with_total = apply_filters( 'pmpro_get_price_parts_with_total', $pmpro_price_parts_with_total, $pmpro_invoice );
|
2925 |
+
|
2926 |
+
if ( $format == 'array' ) {
|
2927 |
+
return $pmpro_price_parts_with_total;
|
2928 |
+
} else {
|
2929 |
+
// Start building our formatted return string.
|
2930 |
+
$pmpro_price = '';
|
2931 |
+
if ( $format == 'span' ) {
|
2932 |
+
foreach ( $pmpro_price_parts_with_total as $key => $pmpro_price_part ) {
|
2933 |
+
$pmpro_price .= '<span class="' . pmpro_get_element_class( 'pmpro_price_part_span pmpro_price_part-' . sanitize_html_class( $key ), 'pmpro_price_part-' . sanitize_html_class( $key ) ) . '"><span class="' . pmpro_get_element_class( 'pmpro_price_part_label' ) . '">' . esc_html( $pmpro_price_part['label'] ) . '</span> <span class="' . pmpro_get_element_class( 'pmpro_price_part_price' ) . '">' . esc_html( $pmpro_price_part['value'] ) . '</span></span>';
|
2934 |
+
}
|
2935 |
+
} elseif ( $format == 'list' ) {
|
2936 |
+
$pmpro_price .= '<ul class="' . pmpro_get_element_class( 'pmpro_price_part_list' ) . '">';
|
2937 |
+
foreach ( $pmpro_price_parts_with_total as $key => $pmpro_price_part ) {
|
2938 |
+
$pmpro_price .= '<li class="' . pmpro_get_element_class( 'pmpro_price_part-' . sanitize_html_class( $key ), 'pmpro_price_part-' . sanitize_html_class( $key ) ) . '"><span class="' . pmpro_get_element_class( 'pmpro_price_part_label' ) . '">' . esc_html( $pmpro_price_part['label'] ) . '</span> <span class="' . pmpro_get_element_class( 'pmpro_price_part_price' ) . '">' . esc_html( $pmpro_price_part['value'] ) . '</span></li>';
|
2939 |
+
}
|
2940 |
+
} else {
|
2941 |
+
// Default to each line separate by breaks.
|
2942 |
+
foreach ( $pmpro_price_parts_with_total as $key => $pmpro_price_part ) {
|
2943 |
+
$pmpro_price .= '<span class="' . pmpro_get_element_class( 'pmpro_price_part-' . sanitize_html_class( $key ), 'pmpro_price_part-' . sanitize_html_class( $key ) ) . '"><span class="' . pmpro_get_element_class( 'pmpro_price_part_label' ) . '">' . esc_html( $pmpro_price_part['label'] ) . '</span> <span class="' . pmpro_get_element_class( 'pmpro_price_part_price' ) . '">' . esc_html( $pmpro_price_part['value'] ) . '</span></span><br />';
|
2944 |
+
}
|
2945 |
+
}
|
2946 |
+
}
|
2947 |
+
return $pmpro_price;
|
2948 |
+
}
|
2949 |
+
|
2950 |
/**
|
2951 |
* Format a price per the currency settings.
|
2952 |
*
|
2991 |
return apply_filters( 'pmpro_format_price', $formatted, $price, $pmpro_currency, $pmpro_currency_symbol );
|
2992 |
}
|
2993 |
|
2994 |
+
/**
|
2995 |
+
* Filter a sanitized price for display with only the allowed HTML.
|
2996 |
+
*
|
2997 |
+
* @since 2.5.7
|
2998 |
+
*
|
2999 |
+
* @param string $price A price value.
|
3000 |
+
* @return string $price The escaped price with allowed HTML.
|
3001 |
+
*
|
3002 |
+
*/
|
3003 |
+
function pmpro_escape_price( $price ) {
|
3004 |
+
$allowed_price_html = apply_filters(
|
3005 |
+
'pmpro_escape_price_html',
|
3006 |
+
array(
|
3007 |
+
'div' => array (
|
3008 |
+
'class' => array(),
|
3009 |
+
'id' => array(),
|
3010 |
+
),
|
3011 |
+
'span' => array (
|
3012 |
+
'class' => array(),
|
3013 |
+
'id' => array(),
|
3014 |
+
),
|
3015 |
+
'sup' => array (
|
3016 |
+
'class' => array(),
|
3017 |
+
'id' => array(),
|
3018 |
+
),
|
3019 |
+
)
|
3020 |
+
);
|
3021 |
+
return wp_kses( $price, $allowed_price_html );
|
3022 |
+
}
|
3023 |
|
3024 |
/**
|
3025 |
* Function to trim trailing zeros from an amount.
|
3104 |
}
|
3105 |
|
3106 |
if ( ! empty( $pmpro_currencies[ $currency ] )
|
3107 |
+
&& is_array( $pmpro_currencies[ $currency ] )
|
3108 |
+
&& isset( $pmpro_currencies[ $currency ]['decimals'] ) ) {
|
3109 |
$decimals = intval( $pmpro_currencies[ $currency ]['decimals'] );
|
3110 |
}
|
3111 |
|
3112 |
$rounded = round( (double) $price, $decimals );
|
3113 |
+
|
3114 |
/**
|
3115 |
* Filter for result of pmpro_round_price.
|
3116 |
*/
|
3117 |
$rounded = apply_filters( 'pmpro_round_price', $rounded );
|
3118 |
+
|
3119 |
return $rounded;
|
3120 |
}
|
3121 |
|
3238 |
return false;
|
3239 |
}
|
3240 |
}
|
3241 |
+
|
3242 |
/**
|
3243 |
* Does the dave provided fall within the current year?
|
3244 |
* Merged in from the Better Logins Report Add On.
|
3306 |
if ( ! in_array( $name, $top_level_pages ) ) {
|
3307 |
$insert['post_parent'] = $pmpro_pages['account'];
|
3308 |
}
|
3309 |
+
|
3310 |
// tweak the login slug
|
3311 |
if ( $name == 'login' ) {
|
3312 |
$insert['post_name'] = 'login';
|
3480 |
function pmpro_show_discount_code() {
|
3481 |
global $wpdb;
|
3482 |
static $show;
|
3483 |
+
|
3484 |
// check DB if we haven't yet
|
3485 |
if ( !isset( $show ) ) {
|
3486 |
if ( $wpdb->get_var( "SELECT id FROM $wpdb->pmpro_discount_codes LIMIT 1" ) ) {
|
3489 |
$show = false;
|
3490 |
}
|
3491 |
}
|
3492 |
+
|
3493 |
$show = apply_filters( "pmpro_show_discount_code", $show );
|
3494 |
+
|
3495 |
return $show;
|
3496 |
}
|
3497 |
|
3504 |
function pmpro_was_checkout_form_submitted() {
|
3505 |
// Default to false.
|
3506 |
$submit = false;
|
3507 |
+
|
3508 |
// Basic check for a field called submit-checkout.
|
3509 |
if ( isset( $_REQUEST['submit-checkout'] ) ) {
|
3510 |
$submit = true;
|
3511 |
}
|
3512 |
+
|
3513 |
// _x stuff in case they clicked on the image button with their mouse
|
3514 |
if ( empty( $submit ) && isset( $_REQUEST['submit-checkout_x'] ) ) {
|
3515 |
$submit = true;
|
3516 |
}
|
3517 |
+
|
3518 |
return $submit;
|
3519 |
}
|
3520 |
+
|
3521 |
/**
|
3522 |
* Build the order object used at checkout.
|
3523 |
* @since 2.1
|
3524 |
* @return mixed $order Order object.
|
3525 |
*/
|
3526 |
+
function pmpro_build_order_for_checkout() {
|
3527 |
global $post, $gateway, $wpdb, $besecure, $discount_code, $discount_code_id, $pmpro_level, $pmpro_levels, $pmpro_msg, $pmpro_msgt, $pmpro_review, $skip_account_fields, $pmpro_paypal_token, $pmpro_show_discount_code, $pmpro_error_fields, $pmpro_required_billing_fields, $pmpro_required_user_fields, $wp_version, $current_user, $pmpro_requirebilling, $tospage, $username, $password, $password2, $bfirstname, $blastname, $baddress1, $baddress2, $bcity, $bstate, $bzipcode, $bcountry, $bphone, $bemail, $bconfirmemail, $CardType, $AccountNumber, $ExpirationMonth, $ExpirationYear, $pmpro_states, $recaptcha, $recaptcha_privatekey, $CVV;
|
3528 |
+
|
3529 |
$morder = new MemberOrder();
|
3530 |
$morder->membership_id = $pmpro_level->id;
|
3531 |
$morder->membership_name = $pmpro_level->name;
|
3532 |
$morder->discount_code = $discount_code;
|
3533 |
$morder->InitialPayment = pmpro_round_price( $pmpro_level->initial_payment );
|
3534 |
$morder->PaymentAmount = pmpro_round_price( $pmpro_level->billing_amount );
|
3535 |
+
$morder->ProfileStartDate = date_i18n( "Y-m-d\TH:i:s", current_time( "timestamp" ) );
|
3536 |
$morder->BillingPeriod = $pmpro_level->cycle_period;
|
3537 |
$morder->BillingFrequency = $pmpro_level->cycle_number;
|
3538 |
if ( $pmpro_level->billing_limit ) {
|
3544 |
$morder->TrialBillingCycles = $pmpro_level->trial_limit;
|
3545 |
$morder->TrialAmount = pmpro_round_price( $pmpro_level->trial_amount );
|
3546 |
}
|
3547 |
+
|
3548 |
// Credit card values.
|
3549 |
$morder->cardtype = $CardType;
|
3550 |
$morder->accountnumber = $AccountNumber;
|
3553 |
$morder->ExpirationDate = $ExpirationMonth . $ExpirationYear;
|
3554 |
$morder->ExpirationDate_YdashM = $ExpirationYear . "-" . $ExpirationMonth;
|
3555 |
$morder->CVV2 = $CVV;
|
3556 |
+
|
3557 |
// Not saving email in order table, but the sites need it.
|
3558 |
$morder->Email = $bemail;
|
3559 |
+
|
3560 |
// Save the user ID if logged in.
|
3561 |
if ( $current_user->ID ) {
|
3562 |
$morder->user_id = $current_user->ID;
|
3563 |
}
|
3564 |
+
|
3565 |
// Sometimes we need these split up.
|
3566 |
$morder->FirstName = $bfirstname;
|
3567 |
$morder->LastName = $blastname;
|
3568 |
$morder->Address1 = $baddress1;
|
3569 |
$morder->Address2 = $baddress2;
|
3570 |
+
|
3571 |
// Set other values.
|
3572 |
$morder->billing = new stdClass();
|
3573 |
$morder->billing->name = $bfirstname . " " . $blastname;
|
3576 |
$morder->billing->state = $bstate;
|
3577 |
$morder->billing->country = $bcountry;
|
3578 |
$morder->billing->zip = $bzipcode;
|
3579 |
+
$morder->billing->phone = $bphone;
|
3580 |
$morder->gateway = $gateway;
|
3581 |
$morder->setGateway();
|
3582 |
+
|
3583 |
// Set up level var.
|
3584 |
$morder->getMembershipLevelAtCheckout();
|
3585 |
+
|
3586 |
// Set tax.
|
3587 |
$initial_tax = $morder->getTaxForPrice( $morder->InitialPayment );
|
3588 |
$recurring_tax = $morder->getTaxForPrice( $morder->PaymentAmount );
|
3589 |
+
|
3590 |
// Set amounts.
|
3591 |
$morder->initial_amount = pmpro_round_price((float)$morder->InitialPayment + (float)$initial_tax);
|
3592 |
$morder->subscription_amount = pmpro_round_price((float)$morder->PaymentAmount + (float)$recurring_tax);
|
3593 |
+
|
3594 |
// Filter for order, since v1.8
|
3595 |
$morder = apply_filters( 'pmpro_checkout_order', $morder );
|
3596 |
+
|
3597 |
return $morder;
|
3598 |
}
|
3599 |
|
3615 |
$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin_file, false, true );
|
3616 |
|
3617 |
// Return false if there is no plugin data.
|
3618 |
+
if ( empty( $plugin_data ) || empty( $plugin_data['Version'] ) ) {
|
3619 |
return false;
|
3620 |
}
|
3621 |
|
3636 |
* @param string $operator Operator to use, e.g. >, <, >=, <=, =.
|
3637 |
* @return bool true or false based on the operator passed in. Returns null for invalid operators.
|
3638 |
*/
|
3639 |
+
function pmpro_int_compare( $a, $b, $operator ) {
|
3640 |
switch ( $operator ) {
|
3641 |
case '>':
|
3642 |
$r = (int)$a > (int)$b;
|
3651 |
$r = (int)$a <= (int)$b;
|
3652 |
break;
|
3653 |
case '=':
|
3654 |
+
case '==':
|
3655 |
$r = (int)$a == (int)$b;
|
3656 |
break;
|
3657 |
default:
|
3658 |
$r = null;
|
3659 |
}
|
3660 |
+
|
3661 |
return $r;
|
3662 |
}
|
3663 |
|
3671 |
*/
|
3672 |
function pmpro_insert_or_replace( $table, $data, $format, $primary_key = 'id' ) {
|
3673 |
global $wpdb;
|
3674 |
+
|
3675 |
if ( empty( $data[$primary_key] ) ) {
|
3676 |
// Insert. Remove keys first.
|
3677 |
$index = array_search( $primary_key, array_keys( $data ) );
|
3682 |
return $wpdb->insert( $table, $data, $format );
|
3683 |
} else {
|
3684 |
// Replace.
|
3685 |
+
$replaced = $wpdb->replace( $table, $data, $format );
|
3686 |
}
|
3687 |
+
}
|
3688 |
+
|
3689 |
+
/**
|
3690 |
+
* Checks if a webhook is running
|
3691 |
+
* @since 2.5
|
3692 |
+
* @param string $gateway If passed in, requires that specific gateway.
|
3693 |
+
* @param bool $set Set to true to set the constant and fire the action hook.
|
3694 |
+
* @return bool True or false if a PMPro webhook set the constant or not.
|
3695 |
+
*/
|
3696 |
+
function pmpro_doing_webhook( $gateway = null, $set = false ){
|
3697 |
+
// If second param is set, set things up.
|
3698 |
+
if ( ! empty( $set ) ) {
|
3699 |
+
define( 'PMPRO_DOING_WEBHOOK', $gateway );
|
3700 |
+
do_action( 'pmpro_doing_webhook', $gateway );
|
3701 |
+
return true;
|
3702 |
+
}
|
3703 |
+
|
3704 |
+
// Otherwise, check if we were already set up.
|
3705 |
+
if( defined( 'PMPRO_DOING_WEBHOOK' ) && !empty ( PMPRO_DOING_WEBHOOK ) ){
|
3706 |
+
if( $gateway !== null ){
|
3707 |
+
if( PMPRO_DOING_WEBHOOK == $gateway ){
|
3708 |
+
return true;
|
3709 |
+
} else {
|
3710 |
+
return false;
|
3711 |
+
}
|
3712 |
+
} else {
|
3713 |
+
return true;
|
3714 |
+
}
|
3715 |
+
} else {
|
3716 |
+
return false;
|
3717 |
+
}
|
3718 |
+
|
3719 |
+
}
|
3720 |
+
|
3721 |
+
/**
|
3722 |
+
* Sanitizing strings using wp_kses and allowing style tags.
|
3723 |
+
*
|
3724 |
+
* @param string $original_string The string to sanitize.
|
3725 |
+
* @param string $context The sanitization context.
|
3726 |
+
*
|
3727 |
+
* @return string The sanitized string.
|
3728 |
+
*
|
3729 |
+
* @since 2.6.1
|
3730 |
+
*/
|
3731 |
+
function pmpro_kses( $original_string, $context = 'email' ) {
|
3732 |
+
$context = 'pmpro_' . $context;
|
3733 |
+
|
3734 |
+
$sanitized_string = $original_string;
|
3735 |
+
|
3736 |
+
if ( 'pmpro_email' === $context ) {
|
3737 |
+
// Always remove script tags and their contents.
|
3738 |
+
$sanitized_string = preg_replace( '@<script[^>]*?>.*?</script>@si', '', $sanitized_string );
|
3739 |
+
}
|
3740 |
+
|
3741 |
+
$sanitized_string = wp_kses( $sanitized_string, $context );
|
3742 |
+
|
3743 |
+
/**
|
3744 |
+
* Allow overriding the normal pmpro_kses functionality for a context.
|
3745 |
+
*
|
3746 |
+
* @param string $sanitized_string The sanitized string.
|
3747 |
+
* @param string $original_string The original string.
|
3748 |
+
* @param string $context The sanitization context.
|
3749 |
+
*
|
3750 |
+
* @since 2.6.2
|
3751 |
+
*/
|
3752 |
+
return apply_filters( 'pmpro_kses', $sanitized_string, $original_string, $context );
|
3753 |
+
}
|
3754 |
+
|
3755 |
+
/**
|
3756 |
+
* Filter the allowed HTML tags for PMPro contexts.
|
3757 |
+
*
|
3758 |
+
* @param array[]|string $allowed_html The allowed HTML tags.
|
3759 |
+
* @param string $context The context name.
|
3760 |
+
*
|
3761 |
+
* @since 2.6.2
|
3762 |
+
*/
|
3763 |
+
function pmpro_kses_allowed_html( $allowed_html, $context ) {
|
3764 |
+
// Only override for our pmpro_* contexts.
|
3765 |
+
if ( 0 !== strpos( $context, 'pmpro_' ) ) {
|
3766 |
+
return $allowed_html;
|
3767 |
+
}
|
3768 |
+
|
3769 |
+
$custom_tags = [];
|
3770 |
+
|
3771 |
+
if ( 'pmpro_email' === $context ) {
|
3772 |
+
$custom_tags['html'] = [
|
3773 |
+
'xmlns' => true,
|
3774 |
+
'xmlns:v' => true,
|
3775 |
+
'xmlns:o' => true,
|
3776 |
+
];
|
3777 |
+
$custom_tags['head'] = [];
|
3778 |
+
$custom_tags['xml'] = [];
|
3779 |
+
$custom_tags['meta'] = [
|
3780 |
+
'name' => true,
|
3781 |
+
'content' => true,
|
3782 |
+
'charset' => true,
|
3783 |
+
'http-equiv' => true,
|
3784 |
+
];
|
3785 |
+
$custom_tags['title'] = [];
|
3786 |
+
$custom_tags['body'] = [];
|
3787 |
+
|
3788 |
+
$custom_tags['table'] = [
|
3789 |
+
'height' => true,
|
3790 |
+
'style' => true,
|
3791 |
+
];
|
3792 |
+
$custom_tags['a'] = [
|
3793 |
+
'style' => true,
|
3794 |
+
];
|
3795 |
+
$custom_tags['style'] = [
|
3796 |
+
'type' => true,
|
3797 |
+
];
|
3798 |
+
}
|
3799 |
+
|
3800 |
+
// Our default context starts with what is available for posts.
|
3801 |
+
$allowed_html = wp_kses_allowed_html( 'post' );
|
3802 |
+
|
3803 |
+
// Merge the allowed HTML tags into our custom tags in case post already has support for it + more.
|
3804 |
+
foreach ( $custom_tags as $tag => $attributes ) {
|
3805 |
+
// Maybe merge our attributes into an already defined tag's attributes.
|
3806 |
+
if ( isset( $allowed_html[ $tag ] ) && true !== $attributes ) {
|
3807 |
+
$attributes = array_merge( $allowed_html[ $tag ], $attributes );
|
3808 |
+
}
|
3809 |
+
|
3810 |
+
$allowed_html[ $tag ] = $attributes;
|
3811 |
+
}
|
3812 |
+
|
3813 |
+
return $allowed_html;
|
3814 |
+
}
|
3815 |
+
add_filter( 'wp_kses_allowed_html', 'pmpro_kses_allowed_html', 10, 2 );
|
3816 |
+
|
3817 |
+
/**
|
3818 |
+
* Show deprecation warning if calling function was called publically.
|
3819 |
+
*
|
3820 |
+
* Useful for preparing to change method visibility from public to private.
|
3821 |
+
*
|
3822 |
+
* @param string $deprecation_notice_version to show.
|
3823 |
+
* @return bool
|
3824 |
+
*/
|
3825 |
+
function pmpro_method_should_be_private( $deprecated_notice_version ) {
|
3826 |
+
$backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
|
3827 |
+
|
3828 |
+
// Check whether the caller of this function is in the same file (class)
|
3829 |
+
// as the caller of the previous function.
|
3830 |
+
if ( $backtrace[0]['file'] !== $backtrace[1]['file'] ) {
|
3831 |
+
_deprecated_function( $backtrace[1]['function'], $deprecated_notice_version );
|
3832 |
+
return true;
|
3833 |
+
}
|
3834 |
+
return false;
|
3835 |
+
}
|
3836 |
+
|
3837 |
+
/**
|
3838 |
+
* Send a 200 HTTP reponse without ending PHP execution.
|
3839 |
+
*
|
3840 |
+
* Useful to avoid issues like timeouts from gateways during
|
3841 |
+
* webhook/IPN handlers.
|
3842 |
+
*
|
3843 |
+
* Works with Apache and Nginx.
|
3844 |
+
*
|
3845 |
+
* Based on code from https://stackoverflow.com/a/42245266
|
3846 |
+
*
|
3847 |
+
* @since 2.6.4
|
3848 |
+
*/
|
3849 |
+
function pmpro_send_200_http_response() {
|
3850 |
+
/**
|
3851 |
+
* Allow filtering whether to send an early 200 HTTP response.
|
3852 |
+
*
|
3853 |
+
* @since 2.6.4
|
3854 |
+
*
|
3855 |
+
* @param bool $send_early_response Whether to send an early 200 HTTP response.
|
3856 |
+
*/
|
3857 |
+
if ( ! apply_filters( 'pmpro_send_200_http_response', false ) ) {
|
3858 |
+
return;
|
3859 |
+
}
|
3860 |
+
|
3861 |
+
// Ngnix compatibility: Check if fastcgi_finish_request is callable.
|
3862 |
+
if ( is_callable( 'fastcgi_finish_request' ) ) {
|
3863 |
+
session_write_close();
|
3864 |
+
fastcgi_finish_request();
|
3865 |
+
|
3866 |
+
return;
|
3867 |
+
}
|
3868 |
+
|
3869 |
+
ignore_user_abort(true);
|
3870 |
+
|
3871 |
+
ob_start();
|
3872 |
+
$server_protocol = filter_input( INPUT_SERVER, 'SERVER_PROTOCOL', FILTER_SANITIZE_STRING );
|
3873 |
+
if ( ! in_array( $server_protocol, array( 'HTTP/1.1', 'HTTP/2', 'HTTP/2.0' ), true ) ) {
|
3874 |
+
$server_protocol = 'HTTP/1.0';
|
3875 |
+
}
|
3876 |
+
|
3877 |
+
header( $server_protocol . ' 200 OK' );
|
3878 |
+
header( 'Content-Encoding: none' );
|
3879 |
+
header( 'Content-Length: ' . ob_get_length() );
|
3880 |
+
header( 'Connection: close' );
|
3881 |
+
|
3882 |
+
ob_end_flush();
|
3883 |
+
ob_flush();
|
3884 |
+
flush();
|
3885 |
+
}
|
3886 |
+
|
3887 |
+
/**
|
3888 |
+
* Returns formatted ISO-8601 date (Used for Zapier Native app.)
|
3889 |
+
* @since 2.6.6
|
3890 |
+
* @param $date date A valid date value.
|
3891 |
+
* @return string The date in ISO-8601 format.
|
3892 |
+
*/
|
3893 |
+
function pmpro_format_date_iso8601( $date ) {
|
3894 |
+
$datetime = new DateTime( $date );
|
3895 |
+
return $datetime->format( DateTime::ATOM );
|
3896 |
+
}
|
3897 |
+
|
3898 |
+
/**
|
3899 |
+
* Determines the user's actual IP address
|
3900 |
+
*
|
3901 |
+
* $_SERVER['REMOTE_ADDR'] cannot be used in all cases, such as when the user
|
3902 |
+
* is making their request through a proxy, or when the web server is behind
|
3903 |
+
* a proxy. In those cases, $_SERVER['REMOTE_ADDR'] is set to the proxy address rather
|
3904 |
+
* than the user's actual address.
|
3905 |
+
*
|
3906 |
+
* Modified from WP_Community_Events::get_unsafe_client_ip() in core WP.
|
3907 |
+
* Modified from https://stackoverflow.com/a/2031935/450127, MIT license.
|
3908 |
+
* Modified from https://github.com/geertw/php-ip-anonymizer, MIT license.
|
3909 |
+
*
|
3910 |
+
* SECURITY WARNING: This function is _NOT_ intended to be used in
|
3911 |
+
* circumstances where the authenticity of the IP address matters. This does
|
3912 |
+
* _NOT_ guarantee that the returned address is valid or accurate, and it can
|
3913 |
+
* be easily spoofed.
|
3914 |
+
*
|
3915 |
+
* @since 2.7
|
3916 |
+
*
|
3917 |
+
* @return string|false The ip address on success or false on failure.
|
3918 |
+
*/
|
3919 |
+
function pmpro_get_ip() {
|
3920 |
+
$client_ip = false;
|
3921 |
+
|
3922 |
+
// In order of preference, with the best ones for this purpose first.
|
3923 |
+
// Added some from JetPack's Jetpack_Protect_Module::get_headers()
|
3924 |
+
$address_headers = array(
|
3925 |
+
'GD_PHP_HANDLER',
|
3926 |
+
'HTTP_AKAMAI_ORIGIN_HOP',
|
3927 |
+
'HTTP_CF_CONNECTING_IP',
|
3928 |
+
'HTTP_CLIENT_IP',
|
3929 |
+
'HTTP_FASTLY_CLIENT_IP',
|
3930 |
+
'HTTP_FORWARDED',
|
3931 |
+
'HTTP_FORWARDED_FOR',
|
3932 |
+
'HTTP_INCAP_CLIENT_IP',
|
3933 |
+
'HTTP_TRUE_CLIENT_IP',
|
3934 |
+
'HTTP_X_CLIENTIP',
|
3935 |
+
'HTTP_X_CLUSTER_CLIENT_IP',
|
3936 |
+
'HTTP_X_FORWARDED',
|
3937 |
+
'HTTP_X_FORWARDED_FOR',
|
3938 |
+
'HTTP_X_IP_TRAIL',
|
3939 |
+
'HTTP_X_REAL_IP',
|
3940 |
+
'HTTP_X_VARNISH',
|
3941 |
+
'REMOTE_ADDR',
|
3942 |
+
);
|
3943 |
+
|
3944 |
+
foreach ( $address_headers as $header ) {
|
3945 |
+
if ( array_key_exists( $header, $_SERVER ) ) {
|
3946 |
+
/*
|
3947 |
+
* HTTP_X_FORWARDED_FOR can contain a chain of comma-separated
|
3948 |
+
* addresses. The first one is the original client. It can't be
|
3949 |
+
* trusted for authenticity, but we don't need to for this purpose.
|
3950 |
+
*/
|
3951 |
+
$address_chain = explode( ',', $_SERVER[ $header ] );
|
3952 |
+
$client_ip = trim( $address_chain[0] );
|
3953 |
+
|
3954 |
+
break;
|
3955 |
+
}
|
3956 |
+
}
|
3957 |
+
|
3958 |
+
if ( ! $client_ip ) {
|
3959 |
+
return false;
|
3960 |
+
}
|
3961 |
+
|
3962 |
+
// Sanitize the IP
|
3963 |
+
$client_ip = preg_replace( '/[^0-9a-fA-F:., ]/', '', $client_ip );
|
3964 |
+
|
3965 |
+
return $client_ip;
|
3966 |
}
|
includes/init.php
CHANGED
@@ -7,6 +7,7 @@ function pmpro_init() {
|
|
7 |
require_once(PMPRO_DIR . '/includes/countries.php');
|
8 |
require_once(PMPRO_DIR . '/includes/states.php');
|
9 |
require_once(PMPRO_DIR . '/includes/currencies.php');
|
|
|
10 |
|
11 |
global $pmpro_pages, $pmpro_core_pages, $pmpro_ready, $pmpro_currencies, $pmpro_currency, $pmpro_currency_symbol;
|
12 |
$pmpro_pages = array();
|
@@ -69,7 +70,7 @@ function pmpro_wp()
|
|
69 |
//run the appropriate preheader function
|
70 |
foreach($pmpro_core_pages as $pmpro_page_name => $pmpro_page_id)
|
71 |
{
|
72 |
-
if(!empty($post->post_content) && strpos($post->post_content, "[pmpro_" . $pmpro_page_name . "]") !== false)
|
73 |
{
|
74 |
//preheader
|
75 |
require_once(PMPRO_DIR . "/preheaders/" . $pmpro_page_name . ".php");
|
@@ -98,7 +99,7 @@ function pmpro_wp()
|
|
98 |
}
|
99 |
}
|
100 |
}
|
101 |
-
add_action("wp", "pmpro_wp",
|
102 |
|
103 |
/*
|
104 |
Add PMPro page names to the BODY class.
|
@@ -179,7 +180,6 @@ function pmpro_manage_users_columns($columns) {
|
|
179 |
|
180 |
function pmpro_sortable_column($columns)
|
181 |
{
|
182 |
-
// $columns['pmpro_membership_level'] = ['level', 'desc'];
|
183 |
$columns['pmpro_membership_level'] = array( 'level', 'desc' );
|
184 |
return $columns;
|
185 |
}
|
@@ -200,16 +200,19 @@ function pmpro_manage_users_custom_column($column_data, $column_name, $user_id)
|
|
200 |
return $column_data;
|
201 |
}
|
202 |
|
203 |
-
function pmpro_sortable_column_query($query) {
|
204 |
global $wpdb;
|
205 |
|
206 |
$vars = $query->query_vars;
|
207 |
|
208 |
-
if($vars['orderby'] == 'level'){
|
209 |
-
$
|
210 |
-
$query->query_orderby = "ORDER BY pmpro_mu.membership_id " . $vars['order'] . ", {$wpdb->prefix}users.user_registered";
|
211 |
-
}
|
212 |
|
|
|
|
|
|
|
|
|
|
|
213 |
}
|
214 |
|
215 |
add_filter('manage_users_columns', 'pmpro_manage_users_columns');
|
7 |
require_once(PMPRO_DIR . '/includes/countries.php');
|
8 |
require_once(PMPRO_DIR . '/includes/states.php');
|
9 |
require_once(PMPRO_DIR . '/includes/currencies.php');
|
10 |
+
require_once(PMPRO_DIR . '/includes/email-templates.php');
|
11 |
|
12 |
global $pmpro_pages, $pmpro_core_pages, $pmpro_ready, $pmpro_currencies, $pmpro_currency, $pmpro_currency_symbol;
|
13 |
$pmpro_pages = array();
|
70 |
//run the appropriate preheader function
|
71 |
foreach($pmpro_core_pages as $pmpro_page_name => $pmpro_page_id)
|
72 |
{
|
73 |
+
if(!empty($post->post_content) && ( strpos($post->post_content, "[pmpro_" . $pmpro_page_name . "]") !== false || has_block( 'pmpro/' . $pmpro_page_name . '-page', $post ) ) )
|
74 |
{
|
75 |
//preheader
|
76 |
require_once(PMPRO_DIR . "/preheaders/" . $pmpro_page_name . ".php");
|
99 |
}
|
100 |
}
|
101 |
}
|
102 |
+
add_action("wp", "pmpro_wp", 2);
|
103 |
|
104 |
/*
|
105 |
Add PMPro page names to the BODY class.
|
180 |
|
181 |
function pmpro_sortable_column($columns)
|
182 |
{
|
|
|
183 |
$columns['pmpro_membership_level'] = array( 'level', 'desc' );
|
184 |
return $columns;
|
185 |
}
|
200 |
return $column_data;
|
201 |
}
|
202 |
|
203 |
+
function pmpro_sortable_column_query( $query ) {
|
204 |
global $wpdb;
|
205 |
|
206 |
$vars = $query->query_vars;
|
207 |
|
208 |
+
if ( $vars['orderby'] == 'level' ){
|
209 |
+
$order = pmpro_sanitize_with_safelist( $vars['order'], array( 'asc', 'desc', 'ASC', 'DESC' ) );
|
|
|
|
|
210 |
|
211 |
+
if ( ! empty( $order ) ) {
|
212 |
+
$query->query_from .= " LEFT JOIN $wpdb->pmpro_memberships_users AS pmpro_mu ON $wpdb->users.ID = pmpro_mu.user_id AND pmpro_mu.status = 'active' LEFT JOIN $wpdb->pmpro_membership_levels AS pmpro_ml ON pmpro_mu.membership_id = pmpro_ml.id";
|
213 |
+
$query->query_orderby = "ORDER BY pmpro_ml.name " . esc_sql( $order ) . ", $wpdb->users.user_registered";
|
214 |
+
}
|
215 |
+
}
|
216 |
}
|
217 |
|
218 |
add_filter('manage_users_columns', 'pmpro_manage_users_columns');
|
includes/lib/Braintree/README.md
DELETED
@@ -1,134 +0,0 @@
|
|
1 |
-
# Braintree PHP library
|
2 |
-
|
3 |
-
The Braintree PHP library provides integration access to the Braintree Gateway.
|
4 |
-
|
5 |
-
## Please Note
|
6 |
-
> **The Payment Card Industry (PCI) Council has [mandated](https://blog.pcisecuritystandards.org/migrating-from-ssl-and-early-tls) that early versions of TLS be retired from service. All organizations that handle credit card information are required to comply with this standard. As part of this obligation, Braintree is updating its services to require TLS 1.2 for all HTTPS connections. Braintree will also require HTTP/1.1 for all connections. Please see our [technical documentation](https://github.com/paypal/tls-update) for more information.**
|
7 |
-
|
8 |
-
## Dependencies
|
9 |
-
|
10 |
-
PHP version >= 5.4.0 is required.
|
11 |
-
|
12 |
-
The following PHP extensions are required:
|
13 |
-
|
14 |
-
* curl
|
15 |
-
* dom
|
16 |
-
* hash
|
17 |
-
* openssl
|
18 |
-
* xmlwriter
|
19 |
-
|
20 |
-
## Quick Start Example
|
21 |
-
|
22 |
-
```php
|
23 |
-
<?php
|
24 |
-
|
25 |
-
require_once 'PATH_TO_BRAINTREE/lib/Braintree.php';
|
26 |
-
|
27 |
-
// Instantiate a Braintree Gateway either like this:
|
28 |
-
$gateway = new Braintree_Gateway([
|
29 |
-
'environment' => 'sandbox',
|
30 |
-
'merchantId' => 'your_merchant_id',
|
31 |
-
'publicKey' => 'your_public_key',
|
32 |
-
'privateKey' => 'your_private_key'
|
33 |
-
]);
|
34 |
-
|
35 |
-
// or like this:
|
36 |
-
$config = new Braintree_Configuration([
|
37 |
-
'environment' => 'sandbox',
|
38 |
-
'merchantId' => 'your_merchant_id',
|
39 |
-
'publicKey' => 'your_public_key',
|
40 |
-
'privateKey' => 'your_private_key'
|
41 |
-
]);
|
42 |
-
$gateway = new Braintree\Gateway($config)
|
43 |
-
|
44 |
-
// Then, create a transaction:
|
45 |
-
$result = $gateway->transaction()->sale([
|
46 |
-
'amount' => '1000.00',
|
47 |
-
'paymentMethodNonce' => 'nonceFromTheClient',
|
48 |
-
'options' => [ 'submitForSettlement' => true ]
|
49 |
-
]);
|
50 |
-
|
51 |
-
if ($result->success) {
|
52 |
-
print_r("success!: " . $result->transaction->id);
|
53 |
-
} else if ($result->transaction) {
|
54 |
-
print_r("Error processing transaction:");
|
55 |
-
print_r("\n code: " . $result->transaction->processorResponseCode);
|
56 |
-
print_r("\n text: " . $result->transaction->processorResponseText);
|
57 |
-
} else {
|
58 |
-
print_r("Validation errors: \n");
|
59 |
-
print_r($result->errors->deepAll());
|
60 |
-
}
|
61 |
-
```
|
62 |
-
|
63 |
-
Both PSR-0 and PSR-4 namespacing are supported. If you are using composer with `--classmap-authoritative` or
|
64 |
-
`--optimize-autoloader` enabled, you'll have to reference classes using PSR-4 namespacing:
|
65 |
-
|
66 |
-
```php
|
67 |
-
$gateway = new Braintree\Gateway([
|
68 |
-
'environment' => 'sandbox',
|
69 |
-
'merchantId' => 'your_merchant_id',
|
70 |
-
'publicKey' => 'your_public_key',
|
71 |
-
'privateKey' => 'your_private_key'
|
72 |
-
]);
|
73 |
-
|
74 |
-
// or
|
75 |
-
|
76 |
-
$config = new Braintree\Configuration([
|
77 |
-
'environment' => 'sandbox',
|
78 |
-
'merchantId' => 'your_merchant_id',
|
79 |
-
'publicKey' => 'your_public_key',
|
80 |
-
'privateKey' => 'your_private_key'
|
81 |
-
]);
|
82 |
-
$gateway = new Braintree\Gateway($config)
|
83 |
-
```
|
84 |
-
|
85 |
-
## HHVM Support
|
86 |
-
|
87 |
-
The Braintree PHP library will run on HHVM >= 3.4.2.
|
88 |
-
|
89 |
-
## Google App Engine Support
|
90 |
-
|
91 |
-
When using Google App Engine include the curl extention in your `php.ini` file (see [#190](https://github.com/braintree/braintree_php/issues/190) for more information):
|
92 |
-
|
93 |
-
```ini
|
94 |
-
extension = "curl.so"
|
95 |
-
```
|
96 |
-
|
97 |
-
and turn off accepting gzip responses:
|
98 |
-
|
99 |
-
```php
|
100 |
-
$gateway = new Braintree\Gateway([
|
101 |
-
'environment' => 'sandbox',
|
102 |
-
// ...
|
103 |
-
'acceptGzipEncoding' => false,
|
104 |
-
]);
|
105 |
-
```
|
106 |
-
|
107 |
-
## Legacy PHP Support
|
108 |
-
|
109 |
-
Version [2.40.0](https://github.com/braintree/braintree_php/releases/tag/2.40.0) is compatible with PHP 5.2 and 5.3. You can find it on our releases page.
|
110 |
-
|
111 |
-
## Documentation
|
112 |
-
|
113 |
-
* [Official documentation](https://developers.braintreepayments.com/php/sdk/server/overview)
|
114 |
-
|
115 |
-
## Developing (Docker)
|
116 |
-
|
117 |
-
The `Makefile` and `Dockerfile` will build an image containing the dependencies and drop you to a terminal where you can run tests.
|
118 |
-
|
119 |
-
```
|
120 |
-
make
|
121 |
-
```
|
122 |
-
|
123 |
-
## Testing
|
124 |
-
|
125 |
-
The unit specs can be run by anyone on any system, but the integration specs are meant to be run against a local development server of our gateway code. These integration specs are not meant for public consumption and will likely fail if run on your system. To run unit tests use rake: `rake test:unit`.
|
126 |
-
|
127 |
-
The benefit of the `rake` tasks is that testing covers default `hhvm` and `php` interpreters. However, if you want to run tests manually simply use the following command:
|
128 |
-
```
|
129 |
-
phpunit tests/unit/
|
130 |
-
```
|
131 |
-
|
132 |
-
## License
|
133 |
-
|
134 |
-
See the LICENSE file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/lib/Braintree/composer.json
DELETED
@@ -1,36 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"name": "braintree/braintree_php",
|
3 |
-
"type": "library",
|
4 |
-
"description": "Braintree PHP Client Library",
|
5 |
-
"license": "MIT",
|
6 |
-
"authors": [
|
7 |
-
{
|
8 |
-
"name": "Braintree",
|
9 |
-
"homepage": "https://www.braintreepayments.com"
|
10 |
-
}
|
11 |
-
],
|
12 |
-
"require": {
|
13 |
-
"php": ">=5.4.0",
|
14 |
-
"ext-curl": "*",
|
15 |
-
"ext-dom": "*",
|
16 |
-
"ext-hash": "*",
|
17 |
-
"ext-openssl": "*",
|
18 |
-
"ext-xmlwriter": "*"
|
19 |
-
},
|
20 |
-
"require-dev": {
|
21 |
-
"phpunit/phpunit": "3.7.*"
|
22 |
-
},
|
23 |
-
"autoload": {
|
24 |
-
"psr-0": {
|
25 |
-
"Braintree": "lib/"
|
26 |
-
},
|
27 |
-
"psr-4": {
|
28 |
-
"Braintree\\": "lib/Braintree"
|
29 |
-
}
|
30 |
-
},
|
31 |
-
"autoload-dev": {
|
32 |
-
"psr-4": {
|
33 |
-
"Test\\": "tests"
|
34 |
-
}
|
35 |
-
}
|
36 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/lib/Braintree/lib/Braintree/Util.php
CHANGED
@@ -99,7 +99,7 @@ class Util
|
|
99 |
|
100 |
switch($error["extensions"]["errorClass"]) {
|
101 |
case "VALIDATION":
|
102 |
-
continue;
|
103 |
case "AUTHENTICATION":
|
104 |
throw new Exception\Authentication();
|
105 |
break;
|
99 |
|
100 |
switch($error["extensions"]["errorClass"]) {
|
101 |
case "VALIDATION":
|
102 |
+
continue 2;
|
103 |
case "AUTHENTICATION":
|
104 |
throw new Exception\Authentication();
|
105 |
break;
|
includes/lib/Stripe/README.md
DELETED
@@ -1,266 +0,0 @@
|
|
1 |
-
# Stripe PHP bindings
|
2 |
-
|
3 |
-
[![Build Status](https://travis-ci.org/stripe/stripe-php.svg?branch=master)](https://travis-ci.org/stripe/stripe-php)
|
4 |
-
[![Latest Stable Version](https://poser.pugx.org/stripe/stripe-php/v/stable.svg)](https://packagist.org/packages/stripe/stripe-php)
|
5 |
-
[![Total Downloads](https://poser.pugx.org/stripe/stripe-php/downloads.svg)](https://packagist.org/packages/stripe/stripe-php)
|
6 |
-
[![License](https://poser.pugx.org/stripe/stripe-php/license.svg)](https://packagist.org/packages/stripe/stripe-php)
|
7 |
-
[![Code Coverage](https://coveralls.io/repos/stripe/stripe-php/badge.svg?branch=master)](https://coveralls.io/r/stripe/stripe-php?branch=master)
|
8 |
-
|
9 |
-
The Stripe PHP library provides convenient access to the Stripe API from
|
10 |
-
applications written in the PHP language. It includes a pre-defined set of
|
11 |
-
classes for API resources that initialize themselves dynamically from API
|
12 |
-
responses which makes it compatible with a wide range of versions of the Stripe
|
13 |
-
API.
|
14 |
-
|
15 |
-
## Requirements
|
16 |
-
|
17 |
-
PHP 5.6.0 and later.
|
18 |
-
|
19 |
-
## Composer
|
20 |
-
|
21 |
-
You can install the bindings via [Composer](http://getcomposer.org/). Run the following command:
|
22 |
-
|
23 |
-
```bash
|
24 |
-
composer require stripe/stripe-php
|
25 |
-
```
|
26 |
-
|
27 |
-
To use the bindings, use Composer's [autoload](https://getcomposer.org/doc/01-basic-usage.md#autoloading):
|
28 |
-
|
29 |
-
```php
|
30 |
-
require_once('vendor/autoload.php');
|
31 |
-
```
|
32 |
-
|
33 |
-
## Manual Installation
|
34 |
-
|
35 |
-
If you do not wish to use Composer, you can download the [latest release](https://github.com/stripe/stripe-php/releases). Then, to use the bindings, include the `init.php` file.
|
36 |
-
|
37 |
-
```php
|
38 |
-
require_once('/path/to/stripe-php/init.php');
|
39 |
-
```
|
40 |
-
|
41 |
-
## Dependencies
|
42 |
-
|
43 |
-
The bindings require the following extensions in order to work properly:
|
44 |
-
|
45 |
-
- [`curl`](https://secure.php.net/manual/en/book.curl.php), although you can use your own non-cURL client if you prefer
|
46 |
-
- [`json`](https://secure.php.net/manual/en/book.json.php)
|
47 |
-
- [`mbstring`](https://secure.php.net/manual/en/book.mbstring.php) (Multibyte String)
|
48 |
-
|
49 |
-
If you use Composer, these dependencies should be handled automatically. If you install manually, you'll want to make sure that these extensions are available.
|
50 |
-
|
51 |
-
## Getting Started
|
52 |
-
|
53 |
-
Simple usage looks like:
|
54 |
-
|
55 |
-
```php
|
56 |
-
$stripe = new \Stripe\StripeClient('sk_test_BQokikJOvBiI2HlWgH4olfQ2');
|
57 |
-
$customer = $stripe->customers->create([
|
58 |
-
'description' => 'example customer',
|
59 |
-
'email' => 'email@example.com',
|
60 |
-
'payment_method' => 'pm_card_visa',
|
61 |
-
]);
|
62 |
-
echo $customer;
|
63 |
-
```
|
64 |
-
|
65 |
-
### Client/service patterns vs legacy patterns
|
66 |
-
|
67 |
-
You can continue to use the legacy integration patterns used prior to version [7.33.0](https://github.com/stripe/stripe-php/blob/master/CHANGELOG.md#7330---2020-05-14). Review the [migration guide](https://github.com/stripe/stripe-php/wiki/Migration-to-StripeClient-and-services-in-7.33.0) for the backwards-compatible client/services pattern changes.
|
68 |
-
|
69 |
-
## Documentation
|
70 |
-
|
71 |
-
See the [PHP API docs](https://stripe.com/docs/api/php#intro).
|
72 |
-
|
73 |
-
## Legacy Version Support
|
74 |
-
|
75 |
-
### PHP 5.4 & 5.5
|
76 |
-
|
77 |
-
If you are using PHP 5.4 or 5.5, you can download v6.21.1 ([zip](https://github.com/stripe/stripe-php/archive/v6.21.1.zip), [tar.gz](https://github.com/stripe/stripe-php/archive/v5.9.2.tar.gz)) from our [releases page](https://github.com/stripe/stripe-php/releases). This version will continue to work with new versions of the Stripe API for all common uses.
|
78 |
-
|
79 |
-
### PHP 5.3
|
80 |
-
|
81 |
-
If you are using PHP 5.3, you can download v5.9.2 ([zip](https://github.com/stripe/stripe-php/archive/v5.9.2.zip), [tar.gz](https://github.com/stripe/stripe-php/archive/v5.9.2.tar.gz)) from our [releases page](https://github.com/stripe/stripe-php/releases). This version will continue to work with new versions of the Stripe API for all common uses.
|
82 |
-
|
83 |
-
## Custom Request Timeouts
|
84 |
-
|
85 |
-
_NOTE:_ We do not recommend decreasing the timeout for non-read-only calls (e.g. charge creation), since even if you locally timeout, the request on Stripe's side can still complete. If you are decreasing timeouts on these calls, make sure to use [idempotency tokens](https://stripe.com/docs/api/php#idempotent_requests) to avoid executing the same transaction twice as a result of timeout retry logic.
|
86 |
-
|
87 |
-
To modify request timeouts (connect or total, in seconds) you'll need to tell the API client to use a CurlClient other than its default. You'll set the timeouts in that CurlClient.
|
88 |
-
|
89 |
-
```php
|
90 |
-
// set up your tweaked Curl client
|
91 |
-
$curl = new \Stripe\HttpClient\CurlClient();
|
92 |
-
$curl->setTimeout(10); // default is \Stripe\HttpClient\CurlClient::DEFAULT_TIMEOUT
|
93 |
-
$curl->setConnectTimeout(5); // default is \Stripe\HttpClient\CurlClient::DEFAULT_CONNECT_TIMEOUT
|
94 |
-
|
95 |
-
echo $curl->getTimeout(); // 10
|
96 |
-
echo $curl->getConnectTimeout(); // 5
|
97 |
-
|
98 |
-
// tell Stripe to use the tweaked client
|
99 |
-
\Stripe\ApiRequestor::setHttpClient($curl);
|
100 |
-
|
101 |
-
// use the Stripe API client as you normally would
|
102 |
-
```
|
103 |
-
|
104 |
-
## Custom cURL Options (e.g. proxies)
|
105 |
-
|
106 |
-
Need to set a proxy for your requests? Pass in the requisite `CURLOPT_*` array to the CurlClient constructor, using the same syntax as `curl_stopt_array()`. This will set the default cURL options for each HTTP request made by the SDK, though many more common options (e.g. timeouts; see above on how to set those) will be overridden by the client even if set here.
|
107 |
-
|
108 |
-
```php
|
109 |
-
// set up your tweaked Curl client
|
110 |
-
$curl = new \Stripe\HttpClient\CurlClient([CURLOPT_PROXY => 'proxy.local:80']);
|
111 |
-
// tell Stripe to use the tweaked client
|
112 |
-
\Stripe\ApiRequestor::setHttpClient($curl);
|
113 |
-
```
|
114 |
-
|
115 |
-
Alternately, a callable can be passed to the CurlClient constructor that returns the above array based on request inputs. See `testDefaultOptions()` in `tests/CurlClientTest.php` for an example of this behavior. Note that the callable is called at the beginning of every API request, before the request is sent.
|
116 |
-
|
117 |
-
### Configuring a Logger
|
118 |
-
|
119 |
-
The library does minimal logging, but it can be configured
|
120 |
-
with a [`PSR-3` compatible logger][psr3] so that messages
|
121 |
-
end up there instead of `error_log`:
|
122 |
-
|
123 |
-
```php
|
124 |
-
\Stripe\Stripe::setLogger($logger);
|
125 |
-
```
|
126 |
-
|
127 |
-
### Accessing response data
|
128 |
-
|
129 |
-
You can access the data from the last API response on any object via `getLastResponse()`.
|
130 |
-
|
131 |
-
```php
|
132 |
-
$customer = $stripe->customers->create([
|
133 |
-
'description' => 'example customer',
|
134 |
-
]);
|
135 |
-
echo $customer->getLastResponse()->headers['Request-Id'];
|
136 |
-
```
|
137 |
-
|
138 |
-
### SSL / TLS compatibility issues
|
139 |
-
|
140 |
-
Stripe's API now requires that [all connections use TLS 1.2](https://stripe.com/blog/upgrading-tls). Some systems (most notably some older CentOS and RHEL versions) are capable of using TLS 1.2 but will use TLS 1.0 or 1.1 by default. In this case, you'd get an `invalid_request_error` with the following error message: "Stripe no longer supports API requests made with TLS 1.0. Please initiate HTTPS connections with TLS 1.2 or later. You can learn more about this at [https://stripe.com/blog/upgrading-tls](https://stripe.com/blog/upgrading-tls).".
|
141 |
-
|
142 |
-
The recommended course of action is to [upgrade your cURL and OpenSSL packages](https://support.stripe.com/questions/how-do-i-upgrade-my-stripe-integration-from-tls-1-0-to-tls-1-2#php) so that TLS 1.2 is used by default, but if that is not possible, you might be able to solve the issue by setting the `CURLOPT_SSLVERSION` option to either `CURL_SSLVERSION_TLSv1` or `CURL_SSLVERSION_TLSv1_2`:
|
143 |
-
|
144 |
-
```php
|
145 |
-
$curl = new \Stripe\HttpClient\CurlClient([CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1]);
|
146 |
-
\Stripe\ApiRequestor::setHttpClient($curl);
|
147 |
-
```
|
148 |
-
|
149 |
-
### Per-request Configuration
|
150 |
-
|
151 |
-
For apps that need to use multiple keys during the lifetime of a process, like
|
152 |
-
one that uses [Stripe Connect][connect], it's also possible to set a
|
153 |
-
per-request key and/or account:
|
154 |
-
|
155 |
-
```php
|
156 |
-
$customers = $stripe->customers->all([],[
|
157 |
-
'api_key' => 'sk_test_...',
|
158 |
-
'stripe_account' => 'acct_...'
|
159 |
-
]);
|
160 |
-
|
161 |
-
$stripe->customers->retrieve('cus_123456789', [], [
|
162 |
-
'api_key' => 'sk_test_...',
|
163 |
-
'stripe_account' => 'acct_...'
|
164 |
-
]);
|
165 |
-
```
|
166 |
-
|
167 |
-
### Configuring CA Bundles
|
168 |
-
|
169 |
-
By default, the library will use its own internal bundle of known CA
|
170 |
-
certificates, but it's possible to configure your own:
|
171 |
-
|
172 |
-
```php
|
173 |
-
\Stripe\Stripe::setCABundlePath("path/to/ca/bundle");
|
174 |
-
```
|
175 |
-
|
176 |
-
### Configuring Automatic Retries
|
177 |
-
|
178 |
-
The library can be configured to automatically retry requests that fail due to
|
179 |
-
an intermittent network problem:
|
180 |
-
|
181 |
-
```php
|
182 |
-
\Stripe\Stripe::setMaxNetworkRetries(2);
|
183 |
-
```
|
184 |
-
|
185 |
-
[Idempotency keys][idempotency-keys] are added to requests to guarantee that
|
186 |
-
retries are safe.
|
187 |
-
|
188 |
-
### Request latency telemetry
|
189 |
-
|
190 |
-
By default, the library sends request latency telemetry to Stripe. These
|
191 |
-
numbers help Stripe improve the overall latency of its API for all users.
|
192 |
-
|
193 |
-
You can disable this behavior if you prefer:
|
194 |
-
|
195 |
-
```php
|
196 |
-
\Stripe\Stripe::setEnableTelemetry(false);
|
197 |
-
```
|
198 |
-
|
199 |
-
## Development
|
200 |
-
|
201 |
-
Get [Composer][composer]. For example, on Mac OS:
|
202 |
-
|
203 |
-
```bash
|
204 |
-
brew install composer
|
205 |
-
```
|
206 |
-
|
207 |
-
Install dependencies:
|
208 |
-
|
209 |
-
```bash
|
210 |
-
composer install
|
211 |
-
```
|
212 |
-
|
213 |
-
The test suite depends on [stripe-mock], so make sure to fetch and run it from a
|
214 |
-
background terminal ([stripe-mock's README][stripe-mock] also contains
|
215 |
-
instructions for installing via Homebrew and other methods):
|
216 |
-
|
217 |
-
```bash
|
218 |
-
go get -u github.com/stripe/stripe-mock
|
219 |
-
stripe-mock
|
220 |
-
```
|
221 |
-
|
222 |
-
Install dependencies as mentioned above (which will resolve [PHPUnit](http://packagist.org/packages/phpunit/phpunit)), then you can run the test suite:
|
223 |
-
|
224 |
-
```bash
|
225 |
-
./vendor/bin/phpunit
|
226 |
-
```
|
227 |
-
|
228 |
-
Or to run an individual test file:
|
229 |
-
|
230 |
-
```bash
|
231 |
-
./vendor/bin/phpunit tests/UtilTest.php
|
232 |
-
```
|
233 |
-
|
234 |
-
Update bundled CA certificates from the [Mozilla cURL release][curl]:
|
235 |
-
|
236 |
-
```bash
|
237 |
-
./update_certs.php
|
238 |
-
```
|
239 |
-
|
240 |
-
The library uses [PHP CS Fixer][php-cs-fixer] for code formatting. Code must be formatted before PRs are submitted, otherwise CI will fail. Run the formatter with:
|
241 |
-
|
242 |
-
```bash
|
243 |
-
./vendor/bin/php-cs-fixer fix -v .
|
244 |
-
```
|
245 |
-
|
246 |
-
## Attention plugin developers
|
247 |
-
|
248 |
-
Are you writing a plugin that integrates Stripe and embeds our library? Then please use the `setAppInfo` function to identify your plugin. For example:
|
249 |
-
|
250 |
-
```php
|
251 |
-
\Stripe\Stripe::setAppInfo("MyAwesomePlugin", "1.2.34", "https://myawesomeplugin.info");
|
252 |
-
```
|
253 |
-
|
254 |
-
The method should be called once, before any request is sent to the API. The second and third parameters are optional.
|
255 |
-
|
256 |
-
### SSL / TLS configuration option
|
257 |
-
|
258 |
-
See the "SSL / TLS compatibility issues" paragraph above for full context. If you want to ensure that your plugin can be used on all systems, you should add a configuration option to let your users choose between different values for `CURLOPT_SSLVERSION`: none (default), `CURL_SSLVERSION_TLSv1` and `CURL_SSLVERSION_TLSv1_2`.
|
259 |
-
|
260 |
-
[composer]: https://getcomposer.org/
|
261 |
-
[connect]: https://stripe.com/connect
|
262 |
-
[curl]: http://curl.haxx.se/docs/caextract.html
|
263 |
-
[idempotency-keys]: https://stripe.com/docs/api/php#idempotent_requests
|
264 |
-
[php-cs-fixer]: https://github.com/FriendsOfPHP/PHP-CS-Fixer
|
265 |
-
[psr3]: http://www.php-fig.org/psr/psr-3/
|
266 |
-
[stripe-mock]: https://github.com/stripe/stripe-mock
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/lib/name-parser.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
Taken from: http://code.google.com/p/php-name-parser/
|
4 |
-
|
5 |
Changed function names to avoid conflicts.
|
6 |
*/
|
7 |
|
@@ -14,11 +14,20 @@
|
|
14 |
if(!function_exists("pnp_split_full_name"))
|
15 |
{
|
16 |
function pnp_split_full_name($full_name) {
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
$fname = $lname = $initials = NULL;
|
21 |
-
|
22 |
$full_name = trim($full_name);
|
23 |
// split into words
|
24 |
$unfiltered_name_parts = explode(" ",$full_name);
|
@@ -28,11 +37,21 @@ if(!function_exists("pnp_split_full_name"))
|
|
28 |
if (!empty($word) && $word[0] != "(")
|
29 |
$name_parts[] = $word;
|
30 |
}
|
|
|
|
|
|
|
|
|
|
|
31 |
$num_words = sizeof($name_parts);
|
32 |
|
33 |
// is the first word a title? (Mr. Mrs, etc)
|
34 |
$salutation = pnp_is_salutation($name_parts[0]);
|
35 |
-
|
|
|
|
|
|
|
|
|
|
|
36 |
|
37 |
// set the range for the middle part of the name (trim prefixes & suffixes)
|
38 |
$start = ($salutation) ? 1 : 0;
|
@@ -48,12 +67,12 @@ if(!function_exists("pnp_split_full_name"))
|
|
48 |
// is it a middle initial or part of their first name?
|
49 |
// if we start off with an initial, we'll call it the first name
|
50 |
if (pnp_is_initial($word)) {
|
51 |
-
// is the initial the first word?
|
52 |
if ($i == $start) {
|
53 |
// if so, do a look-ahead to see if they go by their middle name
|
54 |
// for ex: "R. Jason Smith" => "Jason Smith" & "R." is stored as an initial
|
55 |
// but "R. J. Smith" => "R. Smith" and "J." is stored as an initial
|
56 |
-
if (pnp_is_initial($name_parts[$i+1]))
|
57 |
$fname .= " ".strtoupper($word);
|
58 |
else
|
59 |
$initials .= " ".strtoupper($word);
|
@@ -63,7 +82,7 @@ if(!function_exists("pnp_split_full_name"))
|
|
63 |
}
|
64 |
} else {
|
65 |
$fname .= " ".pnp_fix_case($word);
|
66 |
-
}
|
67 |
}
|
68 |
|
69 |
// check that we have more than 1 word in our string
|
1 |
<?php
|
2 |
/*
|
3 |
Taken from: http://code.google.com/p/php-name-parser/
|
4 |
+
|
5 |
Changed function names to avoid conflicts.
|
6 |
*/
|
7 |
|
14 |
if(!function_exists("pnp_split_full_name"))
|
15 |
{
|
16 |
function pnp_split_full_name($full_name) {
|
17 |
+
$name = [
|
18 |
+
'salutation' => '',
|
19 |
+
'fname' => '',
|
20 |
+
'initials' => '',
|
21 |
+
'lname' => '',
|
22 |
+
'suffix' => '',
|
23 |
+
];
|
24 |
+
|
25 |
+
if ( empty( $full_name ) ) {
|
26 |
+
return $name;
|
27 |
+
}
|
28 |
+
|
29 |
$fname = $lname = $initials = NULL;
|
30 |
+
|
31 |
$full_name = trim($full_name);
|
32 |
// split into words
|
33 |
$unfiltered_name_parts = explode(" ",$full_name);
|
37 |
if (!empty($word) && $word[0] != "(")
|
38 |
$name_parts[] = $word;
|
39 |
}
|
40 |
+
|
41 |
+
if ( empty( $name_parts ) ) {
|
42 |
+
return $name;
|
43 |
+
}
|
44 |
+
|
45 |
$num_words = sizeof($name_parts);
|
46 |
|
47 |
// is the first word a title? (Mr. Mrs, etc)
|
48 |
$salutation = pnp_is_salutation($name_parts[0]);
|
49 |
+
|
50 |
+
$suffix = false;
|
51 |
+
|
52 |
+
if ( isset( $name_parts[sizeof($name_parts)-1] ) ) {
|
53 |
+
$suffix = pnp_is_suffix( $name_parts[ sizeof( $name_parts ) - 1 ] );
|
54 |
+
}
|
55 |
|
56 |
// set the range for the middle part of the name (trim prefixes & suffixes)
|
57 |
$start = ($salutation) ? 1 : 0;
|
67 |
// is it a middle initial or part of their first name?
|
68 |
// if we start off with an initial, we'll call it the first name
|
69 |
if (pnp_is_initial($word)) {
|
70 |
+
// is the initial the first word?
|
71 |
if ($i == $start) {
|
72 |
// if so, do a look-ahead to see if they go by their middle name
|
73 |
// for ex: "R. Jason Smith" => "Jason Smith" & "R." is stored as an initial
|
74 |
// but "R. J. Smith" => "R. Smith" and "J." is stored as an initial
|
75 |
+
if ( isset( $name_parts[ $i + 1 ] ) && pnp_is_initial( $name_parts[ $i + 1 ] ) )
|
76 |
$fname .= " ".strtoupper($word);
|
77 |
else
|
78 |
$initials .= " ".strtoupper($word);
|
82 |
}
|
83 |
} else {
|
84 |
$fname .= " ".pnp_fix_case($word);
|
85 |
+
}
|
86 |
}
|
87 |
|
88 |
// check that we have more than 1 word in our string
|
includes/lib/stripe-apple-pay/apple-developer-merchantid-domain-association
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
7B227073704964223A2239373943394538343346343131343044463144313834343232393232313734313034353044314339464446394437384337313531303944334643463542433731222C2276657273696F6E223A312C22637265617465644F6E223A313536363233343735303036312C227369676E6174757265223A22333038303036303932613836343838366637306430313037303261303830333038303032303130313331306633303064303630393630383634383031363530333034303230313035303033303830303630393261383634383836663730643031303730313030303061303830333038323033653333303832303338386130303330323031303230323038346333303431343935313964353433363330306130363038326138363438636533643034303330323330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433313339333033353331333833303331333333323335333735613137306433323334333033353331333633303331333333323335333735613330356633313235333032333036303335353034303330633163363536333633326437333664373032643632373236663662363537323264373336393637366535663535343333343264353035323466343433313134333031323036303335353034306230633062363934663533323035333739373337343635366437333331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034633231353737656465626436633762323231386636386464373039306131323138646337623062643666326332383364383436303935643934616634613534313162383334323065643831316633343037653833333331663163353463336637656233323230643662616435643465666634393238393839336537633066313361333832303231313330383230323064333030633036303335353164313330313031666630343032333030303330316630363033353531643233303431383330313638303134323366323439633434663933653465663237653663346636323836633366613262626664326534623330343530363038326230363031303530353037303130313034333933303337333033353036303832623036303130353035303733303031383632393638373437343730336132663266366636333733373032653631373037303663363532653633366636643266366636333733373033303334326436313730373036633635363136393633363133333330333233303832303131643036303335353164323030343832303131343330383230313130333038323031306330363039326138363438383666373633363430353031333038316665333038316333303630383262303630313035303530373032303233303831623630633831623335323635366336393631366536333635323036663665323037343638363937333230363336353732373436393636363936333631373436353230363237393230363136653739323037303631373237343739323036313733373337353664363537333230363136333633363537303734363136653633363532303666363632303734363836353230373436383635366532303631373037303663363936333631363236633635323037333734363136653634363137323634323037343635373236643733323036313665363432303633366636653634363937343639366636653733323036663636323037353733363532633230363336353732373436393636363936333631373436353230373036663663363936333739323036313665363432303633363537323734363936363639363336313734363936663665323037303732363136333734363936333635323037333734363137343635366436353665373437333265333033363036303832623036303130353035303730323031313632613638373437343730336132663266373737373737326536313730373036633635326536333666366432663633363537323734363936363639363336313734363536313735373436383666373236393734373932663330333430363033353531643166303432643330326233303239613032376130323538363233363837343734373033613266326636333732366332653631373037303663363532653633366636643266363137303730366336353631363936333631333332653633373236633330316430363033353531643065303431363034313439343537646236666435373438313836383938393736326637653537383530376537396235383234333030653036303335353164306630313031666630343034303330323037383033303066303630393261383634383836663736333634303631643034303230353030333030613036303832613836343863653364303430333032303334393030333034363032323130306265303935373166653731653165373335623535653561666163623463373266656234343566333031383532323263373235313030326236316562643666353530323231303064313862333530613564643664643665623137343630333562313165623263653837636661336536616636636264383338303839306463383263646461613633333038323032656533303832303237356130303330323031303230323038343936643266626633613938646139373330306130363038326138363438636533643034303330323330363733313162333031393036303335353034303330633132343137303730366336353230353236663666373432303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330316531373064333133343330333533303336333233333334333633333330356131373064333233393330333533303336333233333334333633333330356133303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346630313731313834313964373634383564353161356532353831303737366538383061326566646537626165346465303864666334623933653133333536643536363562333561653232643039373736306432323465376262613038666437363137636538386362373662623636373062656338653832393834666635343435613338316637333038316634333034363036303832623036303130353035303730313031303433613330333833303336303630383262303630313035303530373330303138363261363837343734373033613266326636663633373337303265363137303730366336353265363336663664326636663633373337303330333432643631373037303663363537323666366637343633363136373333333031643036303335353164306530343136303431343233663234396334346639336534656632376536633466363238366333666132626266643265346233303066303630333535316431333031303166663034303533303033303130316666333031663036303335353164323330343138333031363830313462626230646561313538333338383961613438613939646562656264656261666461636232346162333033373036303335353164316630343330333032653330326361303261613032383836323636383734373437303361326632663633373236633265363137303730366336353265363336663664326636313730373036633635373236663666373436333631363733333265363337323663333030653036303335353164306630313031666630343034303330323031303633303130303630613261383634383836663736333634303630323065303430323035303033303061303630383261383634386365336430343033303230333637303033303634303233303361636637323833353131363939623138366662333563333536636136326266663431376564643930663735346461323865626566313963383135653432623738396638393866373962353939663938643534313064386639646539633266653032333033323264643534343231623061333035373736633564663333383362393036376664313737633263323136643936346663363732363938323132366635346638376137643162393963623962303938393231363130363939306630393932316430303030333138323031386233303832303138373032303130313330383138363330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533303230383463333034313439353139643534333633303064303630393630383634383031363530333034303230313035303061303831393533303138303630393261383634383836663730643031303930333331306230363039326138363438383666373064303130373031333031633036303932613836343838366637306430313039303533313066313730643331333933303338333133393331333733313332333333303561333032613036303932613836343838366637306430313039333433313164333031623330306430363039363038363438303136353033303430323031303530306131306130363038326138363438636533643034303330323330326630363039326138363438383666373064303130393034333132323034323062303731303365313430613462386231376262613230316130336163643036396234653431366232613263383066383661383338313435633239373566633131333030613036303832613836343863653364303430333032303434363330343430323230343639306264636637626461663833636466343934396534633035313039656463663334373665303564373261313264376335666538633033303033343464663032323032363764353863393365626233353031333836363062353730373938613064643731313734316262353864626436613138363633353038353431656565393035303030303030303030303030227D
|
includes/lib/stripe-apple-pay/stripe-apple-pay.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* Add query var if Stripe is looking for domain association file.
|
5 |
+
*/
|
6 |
+
function pmpro_stripe_apple_pay_rewrite_rule() {
|
7 |
+
add_rewrite_rule( '^\.well-known\/apple-developer-merchantid-domain-association$', 'index.php?pmpro_stripe_apple_pay=true', 'top' );
|
8 |
+
}
|
9 |
+
add_action( 'init', 'pmpro_stripe_apple_pay_rewrite_rule' );
|
10 |
+
|
11 |
+
/*
|
12 |
+
* Create query var to detect if Stripe is looking for domain association file.
|
13 |
+
*/
|
14 |
+
function pmpro_stripe_apple_pay_add_query_vars( $qvars ) {
|
15 |
+
$qvars[] = 'pmpro_stripe_apple_pay';
|
16 |
+
return $qvars;
|
17 |
+
}
|
18 |
+
add_filter( 'query_vars', 'pmpro_stripe_apple_pay_add_query_vars' );
|
19 |
+
|
20 |
+
/**
|
21 |
+
* If query var is present, serve the domain association file.
|
22 |
+
*/
|
23 |
+
function pmpro_stripe_apple_pay_controller() {
|
24 |
+
global $wp_filesystem;
|
25 |
+
|
26 |
+
if ( empty( get_query_var( 'pmpro_stripe_apple_pay' ) ) ) {
|
27 |
+
return;
|
28 |
+
}
|
29 |
+
|
30 |
+
require_once ( ABSPATH . '/wp-admin/includes/file.php' );
|
31 |
+
WP_Filesystem();
|
32 |
+
echo $wp_filesystem->get_contents( PMPRO_DIR . '/includes/lib/stripe-apple-pay/apple-developer-merchantid-domain-association' );
|
33 |
+
exit;
|
34 |
+
}
|
35 |
+
add_action( 'template_redirect', 'pmpro_stripe_apple_pay_controller' );
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Remove trailing slash from WP redirect if serving domain association file.
|
39 |
+
*/
|
40 |
+
function pmpro_stripe_apple_pay_redirect_canonical_filter( $redirect, $request ) {
|
41 |
+
if ( ! empty( get_query_var( 'pmpro_stripe_apple_pay' ) ) ) {
|
42 |
+
return false;
|
43 |
+
}
|
44 |
+
return $redirect;
|
45 |
+
}
|
46 |
+
add_filter( 'redirect_canonical', 'pmpro_stripe_apple_pay_redirect_canonical_filter', 10, 2 );
|
includes/license.php
CHANGED
@@ -25,39 +25,56 @@
|
|
25 |
*/
|
26 |
define('PMPRO_LICENSE_SERVER', 'https://license.paidmembershipspro.com/');
|
27 |
|
28 |
-
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
|
|
31 |
function pmpro_license_isValid($key = NULL, $type = NULL, $force = false) {
|
32 |
-
//
|
33 |
-
$
|
34 |
-
if(empty($force) && $pmpro_license_check !== false && $pmpro_license_check['enddate'] > current_time('timestamp'))
|
35 |
-
{
|
36 |
-
if(empty($type))
|
37 |
-
return true;
|
38 |
-
elseif($type == $pmpro_license_check['license'])
|
39 |
-
return true;
|
40 |
-
else
|
41 |
-
return false;
|
42 |
-
}
|
43 |
-
|
44 |
-
//get key and site url
|
45 |
-
if(empty($key))
|
46 |
$key = get_option("pmpro_license_key", "");
|
47 |
-
|
48 |
-
//no key
|
49 |
-
if(!empty($key))
|
50 |
-
{
|
51 |
-
return pmpro_license_check_key($key);
|
52 |
}
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
delete_option('pmpro_license_check');
|
57 |
add_option('pmpro_license_check', array('license'=>false, 'enddate'=>0), NULL, 'no');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
|
|
|
|
|
59 |
return false;
|
60 |
}
|
|
|
|
|
|
|
61 |
}
|
62 |
|
63 |
/*
|
@@ -75,134 +92,71 @@ function pmpro_license_deactivation() {
|
|
75 |
}
|
76 |
register_deactivation_hook(__FILE__, 'pmpro_deactivation');
|
77 |
|
78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
function pmpro_license_check_key($key = NULL) {
|
80 |
-
|
81 |
-
if(empty($key))
|
82 |
-
$key = get_option('pmpro_license_key');
|
83 |
|
84 |
-
//key
|
85 |
-
if(
|
86 |
-
|
87 |
-
//check license server
|
88 |
-
$url = add_query_arg(array('license'=>$key, 'domain'=>site_url()), PMPRO_LICENSE_SERVER);
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Filter to change the timeout for this wp_remote_get() request.
|
92 |
-
*
|
93 |
-
* @since 1.8.5.1
|
94 |
-
*
|
95 |
-
* @param int $timeout The number of seconds before the request times out
|
96 |
-
*/
|
97 |
-
$timeout = apply_filters("pmpro_license_check_key_timeout", 5);
|
98 |
-
|
99 |
-
$r = wp_remote_get($url, array("timeout" => $timeout));
|
100 |
-
|
101 |
-
//test response
|
102 |
-
if(is_wp_error($r)) {
|
103 |
-
//error
|
104 |
-
pmpro_setMessage("Could not connect to the PMPro License Server to check key Try again later.", "error");
|
105 |
-
}
|
106 |
-
elseif(!empty($r) && $r['response']['code'] == 200)
|
107 |
-
{
|
108 |
-
$r = json_decode($r['body']);
|
109 |
-
|
110 |
-
if($r->active == 1)
|
111 |
-
{
|
112 |
-
//valid key save enddate
|
113 |
-
if(!empty($r->enddate))
|
114 |
-
$enddate = strtotime($r->enddate, current_time('timestamp'));
|
115 |
-
else
|
116 |
-
$enddate = strtotime("+1 Year", current_time("timestamp"));
|
117 |
-
|
118 |
-
delete_option('pmpro_license_check');
|
119 |
-
add_option('pmpro_license_check', array('license'=>$r->license, 'enddate'=>$enddate), NULL, 'no');
|
120 |
-
return true;
|
121 |
-
}
|
122 |
-
elseif(!empty($r->error))
|
123 |
-
{
|
124 |
-
//invalid key
|
125 |
-
global $pmpro_license_error;
|
126 |
-
$pmpro_license_error = $r->error;
|
127 |
-
|
128 |
-
delete_option('pmpro_license_check');
|
129 |
-
add_option('pmpro_license_check', array('license'=>false, 'enddate'=>0), NULL, 'no');
|
130 |
-
|
131 |
-
}
|
132 |
-
}
|
133 |
-
}
|
134 |
-
|
135 |
-
//no key or there was an error
|
136 |
-
return false;
|
137 |
-
}
|
138 |
-
add_action('pmpro_license_check_key', 'pmpro_license_check_key');
|
139 |
-
|
140 |
-
/*
|
141 |
-
Check for pause
|
142 |
-
*/
|
143 |
-
function pmpro_license_pause() {
|
144 |
-
if(!empty($_REQUEST['pmpro_nag_paused']) && current_user_can('manage_options')) {
|
145 |
-
$pmpro_nag_paused = current_time('timestamp')+(3600*24*7);
|
146 |
-
update_option('pmpro_nag_paused', $pmpro_nag_paused, 'no');
|
147 |
-
|
148 |
-
return;
|
149 |
-
}
|
150 |
-
}
|
151 |
-
add_action('admin_init', 'pmpro_license_pause');
|
152 |
-
|
153 |
-
/*
|
154 |
-
Add nags.
|
155 |
-
*/
|
156 |
-
//nag function embedded into headers of plugins
|
157 |
-
function pmpro_license_nag() {
|
158 |
-
static $pmpro_nagged;
|
159 |
-
|
160 |
-
//nagged already?
|
161 |
-
if(!empty($pmpro_nagged)) {
|
162 |
-
return;
|
163 |
-
}
|
164 |
-
|
165 |
-
//remember that we've nagged already
|
166 |
-
$pmpro_nagged = true;
|
167 |
-
|
168 |
-
//blocked by constant?
|
169 |
-
if(defined('PMPRO_LICENSE_NAG') && !PMPRO_LICENSE_NAG) {
|
170 |
-
return;
|
171 |
}
|
172 |
|
173 |
-
//
|
174 |
-
if(
|
175 |
-
return;
|
176 |
}
|
177 |
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
|
183 |
-
|
184 |
-
if(
|
185 |
-
return;
|
186 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
?>
|
202 |
-
<?php _e("If you're running Paid Memberships Pro on a production website, we recommend an annual support license.", 'paid-memberships-pro' );?>
|
203 |
-
<a href="<?php echo admin_url('admin.php?page=pmpro-license');?>"><?php _e('More Info', 'paid-memberships-pro' );?></a> | <a href="<?php echo add_query_arg('pmpro_nag_paused', '1', $_SERVER['REQUEST_URI']);?>"><?php _e('Dismiss', 'paid-memberships-pro' );?></a>
|
204 |
-
</p>
|
205 |
-
</div>
|
206 |
-
<?php
|
207 |
}
|
208 |
-
add_action('
|
25 |
*/
|
26 |
define('PMPRO_LICENSE_SERVER', 'https://license.paidmembershipspro.com/');
|
27 |
|
28 |
+
/**
|
29 |
+
* Check if a license key is valid.
|
30 |
+
* @param string $key The key to check.
|
31 |
+
* @param string $type If passed will also check that the key is this type.
|
32 |
+
* @param bool $force If true, will check key against the PMPro server.
|
33 |
+
* @return bool True if valid, false if not.
|
34 |
+
*/
|
35 |
function pmpro_license_isValid($key = NULL, $type = NULL, $force = false) {
|
36 |
+
// Get key from options if non passed in.
|
37 |
+
if( empty( $key ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
$key = get_option("pmpro_license_key", "");
|
|
|
|
|
|
|
|
|
|
|
39 |
}
|
40 |
+
|
41 |
+
// No key? Clean up options and return false.
|
42 |
+
if ( empty( $key ) ) {
|
43 |
delete_option('pmpro_license_check');
|
44 |
add_option('pmpro_license_check', array('license'=>false, 'enddate'=>0), NULL, 'no');
|
45 |
+
return false;
|
46 |
+
}
|
47 |
+
|
48 |
+
// If force was passed in, let's check with the server.
|
49 |
+
if ( $force ) {
|
50 |
+
$pmpro_license_check = pmpro_license_check_key( $key );
|
51 |
+
}
|
52 |
+
|
53 |
+
// Get license check value from options.
|
54 |
+
$pmpro_license_check = get_option( 'pmpro_license_check', false );
|
55 |
+
|
56 |
+
// No license info from server?
|
57 |
+
if ( empty( $pmpro_license_check ) ) {
|
58 |
+
return false;
|
59 |
+
}
|
60 |
+
|
61 |
+
// Server check errored out?
|
62 |
+
if ( is_wp_error( $pmpro_license_check ) ) {
|
63 |
+
return false;
|
64 |
+
}
|
65 |
+
|
66 |
+
// Check if 30 days past the end date. (We only run the cron every 30 days.)
|
67 |
+
if ( $pmpro_license_check['enddate'] < ( current_time( 'timestamp' ) + 86400*31 ) ) {
|
68 |
+
return false;
|
69 |
+
}
|
70 |
|
71 |
+
// Check if a specific type.
|
72 |
+
if ( ! empty( $type ) && $type != $pmpro_license_check['license'] ) {
|
73 |
return false;
|
74 |
}
|
75 |
+
|
76 |
+
// If we got here, we should be good.
|
77 |
+
return true;
|
78 |
}
|
79 |
|
80 |
/*
|
92 |
}
|
93 |
register_deactivation_hook(__FILE__, 'pmpro_deactivation');
|
94 |
|
95 |
+
/**
|
96 |
+
* Check a key against the PMPro license server.
|
97 |
+
* Runs via cron every month.
|
98 |
+
* @param string The key to check.
|
99 |
+
* @return array|WP_Error Returns an array with the key and enddate
|
100 |
+
* or WP_Error if invalid or there was an error.
|
101 |
+
*/
|
102 |
function pmpro_license_check_key($key = NULL) {
|
103 |
+
global $pmpro_license_error;
|
|
|
|
|
104 |
|
105 |
+
// Get key from options if non passed in.
|
106 |
+
if( empty( $key ) ) {
|
107 |
+
$key = get_option("pmpro_license_key", "");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
}
|
109 |
|
110 |
+
// No key? Return error.
|
111 |
+
if ( empty ( $key ) ) {
|
112 |
+
return new WP_Error ( 'no_key', __( 'Missing key.', 'paid-memberships-pro' ) );
|
113 |
}
|
114 |
|
115 |
+
/**
|
116 |
+
* Filter to change the timeout for this wp_remote_get() request.
|
117 |
+
*
|
118 |
+
* @since 1.8.5.1
|
119 |
+
*
|
120 |
+
* @param int $timeout The number of seconds before the request times out
|
121 |
+
*/
|
122 |
+
$timeout = apply_filters( 'pmpro_license_check_key_timeout', 5 );
|
123 |
+
|
124 |
+
$url = add_query_arg(array('license'=>$key, 'domain'=>site_url()), PMPRO_LICENSE_SERVER);
|
125 |
+
$r = wp_remote_get( $url, array( "timeout" => $timeout ) );
|
126 |
+
|
127 |
+
// Trouble connecting?
|
128 |
+
if( is_wp_error( $r ) ) {
|
129 |
+
// Connection error.
|
130 |
+
return new WP_Error( 'connection_error', $r->get_error_message() );
|
131 |
+
}
|
132 |
|
133 |
+
// Bad response code?
|
134 |
+
if ( $r['response']['code'] !== 200 ) {
|
135 |
+
return new WP_Error( 'bad_response_code', __( sprintf( 'Bad response code %s.', 'paid-memberships-pro' ), $r['response']['code'] ) );
|
136 |
}
|
137 |
+
|
138 |
+
// Process the response.
|
139 |
+
$r = json_decode($r['body']);
|
140 |
+
if( $r->active == 1 ) {
|
141 |
+
// Get end date. If none, let's set it 1 year out.
|
142 |
+
if( ! empty( $r->enddate ) ) {
|
143 |
+
$enddate = strtotime( $r->enddate, current_time( 'timestamp' ) );
|
144 |
+
} else {
|
145 |
+
$enddate = strtotime( '+1 Year', current_time( 'timestamp' ) );
|
146 |
+
}
|
147 |
|
148 |
+
$license_check = array( 'license' => $r->license, 'enddate' => $enddate );
|
149 |
+
update_option( 'pmpro_license_check', $license_check, 'no' );
|
150 |
+
|
151 |
+
return $license_check;
|
152 |
+
} elseif ( ! empty( $r->error ) ) {
|
153 |
+
// Invalid key. Let's clear out the option.
|
154 |
+
update_option( 'pmpro_license_check', array('license'=>false, 'enddate'=>0), 'no' );
|
155 |
+
|
156 |
+
return new WP_Error( 'invalid_key', $r->error );
|
157 |
+
} else {
|
158 |
+
// Unknown error. We should maybe clear out the option, but we're not.
|
159 |
+
return new WP_Error( 'unknown_error', __( 'Unknown error.', 'paid-memberships-pro' ) );
|
160 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
}
|
162 |
+
add_action('pmpro_license_check_key', 'pmpro_license_check_key');
|
includes/localization.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
function pmpro_load_textdomain()
|
3 |
{
|
4 |
//get the locale
|
5 |
-
$locale = apply_filters("plugin_locale",
|
6 |
$mofile = "paid-memberships-pro-" . $locale . ".mo";
|
7 |
|
8 |
//paths to local (plugin) and global (WP) language files
|
@@ -25,11 +25,14 @@ function pmpro_load_textdomain()
|
|
25 |
add_action("init", "pmpro_load_textdomain", 1);
|
26 |
|
27 |
function pmpro_translate_billing_period($period, $number = 1)
|
28 |
-
{
|
29 |
//note as of v1.8, we stopped using _n and split things up to aid in localization
|
30 |
if($number == 1)
|
31 |
{
|
32 |
-
|
|
|
|
|
|
|
33 |
return __("Day", 'paid-memberships-pro' );
|
34 |
elseif($period == "Week")
|
35 |
return __("Week", 'paid-memberships-pro' );
|
@@ -39,8 +42,10 @@ function pmpro_translate_billing_period($period, $number = 1)
|
|
39 |
return __("Year", 'paid-memberships-pro' );
|
40 |
}
|
41 |
else
|
42 |
-
{
|
43 |
-
if($period == "
|
|
|
|
|
44 |
return __("Days", 'paid-memberships-pro' );
|
45 |
elseif($period == "Week")
|
46 |
return __("Weeks", 'paid-memberships-pro' );
|
2 |
function pmpro_load_textdomain()
|
3 |
{
|
4 |
//get the locale
|
5 |
+
$locale = apply_filters("plugin_locale", get_user_locale(), "paid-memberships-pro");
|
6 |
$mofile = "paid-memberships-pro-" . $locale . ".mo";
|
7 |
|
8 |
//paths to local (plugin) and global (WP) language files
|
25 |
add_action("init", "pmpro_load_textdomain", 1);
|
26 |
|
27 |
function pmpro_translate_billing_period($period, $number = 1)
|
28 |
+
{
|
29 |
//note as of v1.8, we stopped using _n and split things up to aid in localization
|
30 |
if($number == 1)
|
31 |
{
|
32 |
+
|
33 |
+
if( $period == "Hour" ){
|
34 |
+
return __("Hour", "paid-memberships-pro" );
|
35 |
+
} else if($period == "Day")
|
36 |
return __("Day", 'paid-memberships-pro' );
|
37 |
elseif($period == "Week")
|
38 |
return __("Week", 'paid-memberships-pro' );
|
42 |
return __("Year", 'paid-memberships-pro' );
|
43 |
}
|
44 |
else
|
45 |
+
{
|
46 |
+
if( $period == "Hour" ){
|
47 |
+
return __("Hours", "paid-memberships-pro" );
|
48 |
+
} else if($period == "Day")
|
49 |
return __("Days", 'paid-memberships-pro' );
|
50 |
elseif($period == "Week")
|
51 |
return __("Weeks", 'paid-memberships-pro' );
|
includes/login.php
CHANGED
@@ -31,7 +31,7 @@ function pmpro_login_redirect( $redirect_to, $request = NULL, $user = NULL ) {
|
|
31 |
// This filter is left in place for PMPro versions dating back to 2014.
|
32 |
return apply_filters( 'pmpro_login_redirect_url', $redirect_to, $request, $user );
|
33 |
}
|
34 |
-
add_filter( 'login_redirect','pmpro_login_redirect', 10, 3 );
|
35 |
|
36 |
/**
|
37 |
* Where is the sign up page? Levels page or default multisite page.
|
@@ -84,12 +84,19 @@ add_action('login_init', 'pmpro_login_head');
|
|
84 |
* @since 1.7.14
|
85 |
*/
|
86 |
function pmpro_redirect_to_logged_in() {
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
exit;
|
90 |
}
|
91 |
}
|
92 |
-
add_action("template_redirect", "pmpro_redirect_to_logged_in",
|
93 |
add_action("login_init", "pmpro_redirect_to_logged_in", 5);
|
94 |
|
95 |
/**
|
@@ -99,9 +106,19 @@ add_action("login_init", "pmpro_redirect_to_logged_in", 5);
|
|
99 |
* @since 2.3
|
100 |
*/
|
101 |
function pmpro_login_url_filter( $login_url='', $redirect='' ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
$login_page_id = pmpro_getOption( 'login_page_id' );
|
103 |
if ( ! empty ( $login_page_id ) ) {
|
104 |
-
$
|
|
|
|
|
|
|
|
|
105 |
|
106 |
if ( ! empty( $redirect ) ) {
|
107 |
$login_url = add_query_arg( 'redirect_to', urlencode( $redirect ), $login_url ) ;
|
@@ -119,7 +136,7 @@ function pmpro_login_url_filter( $login_url='', $redirect='' ) {
|
|
119 |
*
|
120 |
*/
|
121 |
function pmpro_wp_loaded_login_setup() {
|
122 |
-
add_filter( 'login_url', 'pmpro_login_url_filter', 50, 2 );
|
123 |
}
|
124 |
add_action( 'wp_loaded', 'pmpro_wp_loaded_login_setup' );
|
125 |
|
@@ -130,16 +147,16 @@ add_action( 'wp_loaded', 'pmpro_wp_loaded_login_setup' );
|
|
130 |
function pmpro_use_default_login_for_confirm_admin_email( $location ) {
|
131 |
if ( strpos( $location, 'action=confirm_admin_email' ) !== false ) {
|
132 |
$login_url = wp_login_url();
|
133 |
-
|
134 |
remove_filter( 'login_url', 'pmpro_login_url_filter', 50, 2 );
|
135 |
$default_login_url = wp_login_url();
|
136 |
add_filter( 'login_url', 'pmpro_login_url_filter', 50, 2 );
|
137 |
-
|
138 |
if ( $login_url != $default_login_url ) {
|
139 |
$location = str_replace( $login_url, $default_login_url, $location );
|
140 |
}
|
141 |
}
|
142 |
-
|
143 |
return $location;
|
144 |
}
|
145 |
add_filter( 'wp_redirect', 'pmpro_use_default_login_for_confirm_admin_email' );
|
@@ -155,22 +172,22 @@ add_filter( 'wp_redirect', 'pmpro_use_default_login_for_confirm_admin_email' );
|
|
155 |
*/
|
156 |
function pmpro_login_url( $redirect = '', $force_reauth = false ) {
|
157 |
global $pmpro_pages;
|
158 |
-
|
159 |
if ( empty( $pmpro_pages['login'] ) ) {
|
160 |
// skip everything, including filter below
|
161 |
return wp_login_url( $redirect, $force_reauth );
|
162 |
}
|
163 |
-
|
164 |
$login_url = get_permalink( $pmpro_pages['login'] );
|
165 |
-
|
166 |
if ( ! empty( $redirect ) ) {
|
167 |
$login_url = add_query_arg( 'redirect_to', urlencode( $redirect ), $login_url );
|
168 |
}
|
169 |
-
|
170 |
if ( $force_reauth ) {
|
171 |
$login_url = add_query_arg( 'reauth', '1', $login_url );
|
172 |
}
|
173 |
-
|
174 |
/**
|
175 |
* Filters the login URL.
|
176 |
*
|
@@ -192,19 +209,19 @@ function pmpro_login_url( $redirect = '', $force_reauth = false ) {
|
|
192 |
*/
|
193 |
function pmpro_lostpassword_url( $redirect = '' ) {
|
194 |
global $pmpro_pages;
|
195 |
-
|
196 |
if ( empty( $pmpro_pages['login'] ) ) {
|
197 |
// skip everything, including filter below
|
198 |
return wp_lostpassword_url( $redirect );
|
199 |
}
|
200 |
-
|
201 |
$args = array( 'action' => 'lostpassword' );
|
202 |
if ( ! empty( $redirect ) ) {
|
203 |
-
$args['redirect_to'] = urlencode( $redirect );
|
204 |
}
|
205 |
-
|
206 |
$lostpassword_url = add_query_arg( $args, get_permalink( $pmpro_pages['login'] ) );
|
207 |
-
|
208 |
/**
|
209 |
* Filters the Lost Password URL.
|
210 |
*
|
@@ -270,7 +287,7 @@ function pmpro_login_document_title_parts( $titleparts ) {
|
|
270 |
if ( empty( $pmpro_pages ) || empty ( $pmpro_pages['login'] ) || ! is_page( $pmpro_pages['login'] ) ) {
|
271 |
return $titleparts;
|
272 |
}
|
273 |
-
|
274 |
if ( is_user_logged_in() ) {
|
275 |
$titleparts['title'] = __( 'Welcome', 'paid-memberships-pro' );
|
276 |
} elseif ( ! empty( $_REQUEST['action'] ) && $_REQUEST['action'] === 'reset_pass' ) {
|
@@ -293,7 +310,7 @@ function pmpro_login_forms_handler( $show_menu = true, $show_logout_link = true,
|
|
293 |
if ( $location === 'widget' && pmpro_is_login_page() ) {
|
294 |
return '';
|
295 |
}
|
296 |
-
|
297 |
// Set the message return string.
|
298 |
$message = '';
|
299 |
$msgt = 'pmpro_alert';
|
@@ -322,6 +339,12 @@ function pmpro_login_forms_handler( $show_menu = true, $show_logout_link = true,
|
|
322 |
case 'recovered':
|
323 |
$message = __( 'Check your email for the confirmation link.', 'paid-memberships-pro' );
|
324 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
325 |
}
|
326 |
}
|
327 |
|
@@ -371,7 +394,7 @@ function pmpro_login_forms_handler( $show_menu = true, $show_logout_link = true,
|
|
371 |
}
|
372 |
|
373 |
if ( isset( $_GET['password'] ) ) {
|
374 |
-
switch(
|
375 |
case 'changed':
|
376 |
$message = __( 'Your password has successfully been updated.', 'paid-memberships-pro' );
|
377 |
$msgt = 'pmpro_success';
|
@@ -421,7 +444,7 @@ function pmpro_login_forms_handler( $show_menu = true, $show_logout_link = true,
|
|
421 |
|
422 |
// Note we don't show messages on the widget form.
|
423 |
if ( $message && $location !== 'widget' ) {
|
424 |
-
echo '<div class="' . pmpro_get_element_class( 'pmpro_message ' . $msgt, esc_attr( $msgt ) ) . '">'.
|
425 |
}
|
426 |
|
427 |
// Get the form title HTML tag.
|
@@ -440,44 +463,44 @@ function pmpro_login_forms_handler( $show_menu = true, $show_logout_link = true,
|
|
440 |
}
|
441 |
|
442 |
// Figure out which login view to show.
|
443 |
-
if ( ! is_user_logged_in() ) {
|
444 |
if ( ! in_array( $action, array( 'reset_pass', 'rp' ) ) ) {
|
445 |
// Login form.
|
446 |
if ( empty( $_GET['login'] ) || empty( $_GET['key'] ) ) {
|
447 |
$username = isset( $_REQUEST['username'] ) ? sanitize_text_field( $_REQUEST['username'] ) : NULL;
|
448 |
$redirect_to = isset( $_REQUEST['redirect_to'] ) ? esc_url( $_REQUEST['redirect_to'] ) : NULL;
|
449 |
-
|
450 |
-
// Redirect users back to their page that they logged-in from via the widget.
|
451 |
-
if( empty( $redirect_to ) && $location === 'widget' && apply_filters( 'pmpro_login_widget_redirect_back', true ) ) {
|
452 |
$redirect_to = esc_url( site_url( $_SERVER['REQUEST_URI'] ) );
|
453 |
}
|
454 |
?>
|
455 |
<div class="<?php echo pmpro_get_element_class( 'pmpro_login_wrap' ); ?>">
|
456 |
-
<?php
|
457 |
if ( ! pmpro_is_login_page() ) {
|
458 |
-
echo $before_title .
|
459 |
}
|
460 |
?>
|
461 |
<?php
|
462 |
pmpro_login_form( array( 'value_username' => esc_html( $username ), 'redirect' => esc_url( $redirect_to ) ) );
|
463 |
pmpro_login_forms_handler_nav( 'login' );
|
464 |
?>
|
465 |
-
</div> <!-- end pmpro_login_wrap -->
|
466 |
<?php if ( pmpro_is_login_page() ) { ?>
|
467 |
<script>
|
468 |
document.getElementById('user_login').focus();
|
469 |
</script>
|
470 |
<?php } ?>
|
471 |
-
|
472 |
<?php
|
473 |
}
|
474 |
} elseif ( $location !== 'widget' && ( $action === 'reset_pass' || ( $action === 'rp' && in_array( $_REQUEST['login'], array( 'invalidkey', 'expiredkey' ) ) ) ) ) {
|
475 |
-
// Reset password form.
|
476 |
?>
|
477 |
<div class="<?php echo pmpro_get_element_class( 'pmpro_lost_password_wrap' ); ?>">
|
478 |
-
<?php
|
479 |
if ( ! pmpro_is_login_page() ) {
|
480 |
-
echo $before_title .
|
481 |
}
|
482 |
?>
|
483 |
<p class="<?php echo pmpro_get_element_class( 'pmpro_lost_password-instructions' ); ?>">
|
@@ -492,12 +515,12 @@ function pmpro_login_forms_handler( $show_menu = true, $show_logout_link = true,
|
|
492 |
</div> <!-- end pmpro_lost_password_wrap -->
|
493 |
<?php
|
494 |
} elseif ( $location !== 'widget' && $action === 'rp' ) {
|
495 |
-
// Password reset processing key.
|
496 |
?>
|
497 |
<div class="<?php echo pmpro_get_element_class( 'pmpro_reset_password_wrap' ); ?>">
|
498 |
-
<?php
|
499 |
if ( ! pmpro_is_login_page() ) {
|
500 |
-
echo $before_title .
|
501 |
}
|
502 |
?>
|
503 |
<?php pmpro_reset_password_form(); ?>
|
@@ -515,12 +538,12 @@ function pmpro_login_forms_handler( $show_menu = true, $show_logout_link = true,
|
|
515 |
<?php
|
516 |
}
|
517 |
}
|
518 |
-
|
519 |
$content = ob_get_clean();
|
520 |
if ( $echo ) {
|
521 |
echo $content;
|
522 |
}
|
523 |
-
|
524 |
return $content;
|
525 |
}
|
526 |
|
@@ -560,11 +583,11 @@ function pmpro_lost_password_form() { ?>
|
|
560 |
function pmpro_lost_password_redirect() {
|
561 |
if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) {
|
562 |
$login_page = pmpro_getOption( 'login_page_id' );
|
563 |
-
|
564 |
if ( empty( $login_page ) ) {
|
565 |
return;
|
566 |
}
|
567 |
-
|
568 |
$redirect_url = $login_page ? get_permalink( $login_page ): '';
|
569 |
|
570 |
$errors = retrieve_password();
|
@@ -584,17 +607,17 @@ add_action( 'login_form_lostpassword', 'pmpro_lost_password_redirect' );
|
|
584 |
* Redirect Password reset to our own page.
|
585 |
* @since 2.3
|
586 |
*/
|
587 |
-
function pmpro_reset_password_redirect() {
|
588 |
if ( 'GET' == $_SERVER['REQUEST_METHOD'] ) {
|
589 |
$login_page = pmpro_getOption( 'login_page_id' );
|
590 |
-
|
591 |
if ( empty( $login_page ) ) {
|
592 |
return;
|
593 |
}
|
594 |
-
|
595 |
$redirect_url = $login_page ? get_permalink( $login_page ): '';
|
596 |
$user = check_password_reset_key( $_REQUEST['rp_key'], $_REQUEST['rp_login'] );
|
597 |
-
|
598 |
if ( ! $user || is_wp_error( $user ) ) {
|
599 |
if ( $user && $user->get_error_code() === 'expired_key' ) {
|
600 |
wp_redirect( add_query_arg( 'login', urlencode( 'expiredkey' ), $redirect_url ) );
|
@@ -621,11 +644,42 @@ add_action( 'login_form_resetpass', 'pmpro_reset_password_redirect' );
|
|
621 |
function pmpro_reset_password_form() {
|
622 |
if ( isset( $_REQUEST['login'] ) && isset( $_REQUEST['key'] ) ) {
|
623 |
|
624 |
-
//
|
625 |
-
$
|
626 |
-
|
627 |
-
|
628 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
629 |
<form name="resetpassform" id="resetpassform" class="<?php echo pmpro_get_element_class( 'pmpro_form', 'resetpassform' ); ?>" action="<?php echo esc_url( site_url( 'wp-login.php?action=resetpass' ) ); ?>" method="post" autocomplete="off">
|
630 |
<input type="hidden" id="user_login" name="rp_login" value="<?php echo esc_attr( sanitize_text_field( $_REQUEST['login'] ) ); ?>" autocomplete="off" />
|
631 |
<input type="hidden" name="rp_key" value="<?php echo esc_attr( sanitize_text_field( $_REQUEST['key'] ) ); ?>" />
|
@@ -701,14 +755,14 @@ function pmpro_login_forms_handler_nav( $pmpro_form ) { ?>
|
|
701 |
function pmpro_do_password_reset() {
|
702 |
if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) {
|
703 |
$login_page = pmpro_getOption( 'login_page_id' );
|
704 |
-
|
705 |
if ( empty( $login_page ) ) {
|
706 |
return;
|
707 |
}
|
708 |
-
|
709 |
$rp_key = sanitize_text_field( $_REQUEST['rp_key'] );
|
710 |
-
$rp_login = sanitize_text_field( $_REQUEST['rp_login'] );
|
711 |
-
|
712 |
$redirect_url = $login_page ? get_permalink( $login_page ): '';
|
713 |
$user = check_password_reset_key( $rp_key, $rp_login );
|
714 |
|
@@ -767,35 +821,22 @@ add_action( 'login_form_resetpass', 'pmpro_do_password_reset' );
|
|
767 |
*
|
768 |
* @since 2.3
|
769 |
*/
|
770 |
-
function pmpro_password_reset_email_filter( $message, $key, $user_login
|
771 |
-
|
772 |
-
$login_page_id = pmpro_getOption( 'login_page_id' );
|
773 |
-
if ( ! empty ( $login_page_id ) ) {
|
774 |
-
$login_url = get_permalink( $login_page_id );
|
775 |
-
$message = str_replace( site_url( 'wp-login.php' ), $login_url, $message );
|
776 |
-
}
|
777 |
-
|
778 |
-
return $message;
|
779 |
-
}
|
780 |
-
add_filter( 'retrieve_password_message', 'pmpro_password_reset_email_filter', 10, 4 );
|
781 |
-
|
782 |
-
/**
|
783 |
-
* Replace the default login URL in the new user notification email
|
784 |
-
* with the membership account page login URL instead.
|
785 |
-
*
|
786 |
-
* @since 2.3.4
|
787 |
-
*/
|
788 |
-
function pmpro_new_user_notification_email_filter( $message, $user, $blogname ) {
|
789 |
|
790 |
$login_page_id = pmpro_getOption( 'login_page_id' );
|
791 |
if ( ! empty ( $login_page_id ) ) {
|
792 |
-
|
|
|
|
|
|
|
|
|
793 |
$message = str_replace( network_site_url( 'wp-login.php' ), $login_url, $message );
|
794 |
}
|
795 |
|
796 |
return $message;
|
797 |
}
|
798 |
-
add_filter( '
|
|
|
799 |
|
800 |
/**
|
801 |
* Authenticate the frontend user login.
|
@@ -846,7 +887,7 @@ add_filter( 'authenticate', 'pmpro_authenticate_username_password', 30, 3);
|
|
846 |
*/
|
847 |
function pmpro_login_failed( $username ) {
|
848 |
|
849 |
-
$login_page = pmpro_getOption( 'login_page_id' );
|
850 |
if ( empty( $login_page ) ) {
|
851 |
return;
|
852 |
}
|
@@ -954,7 +995,7 @@ function pmpro_confirmaction_handler() {
|
|
954 |
if ( empty( $_REQUEST['action'] ) || $_REQUEST['action'] !== 'confirmaction' ) {
|
955 |
return false;
|
956 |
}
|
957 |
-
|
958 |
if ( ! isset( $_GET['request_id'] ) ) {
|
959 |
wp_die( __( 'Missing request ID.' ) );
|
960 |
}
|
@@ -973,4 +1014,6 @@ function pmpro_confirmaction_handler() {
|
|
973 |
|
974 |
/** This action is documented in wp-login.php */
|
975 |
do_action( 'user_request_action_confirmed', $request_id );
|
976 |
-
|
|
|
|
31 |
// This filter is left in place for PMPro versions dating back to 2014.
|
32 |
return apply_filters( 'pmpro_login_redirect_url', $redirect_to, $request, $user );
|
33 |
}
|
34 |
+
add_filter( 'login_redirect','pmpro_login_redirect', 10, 3 );
|
35 |
|
36 |
/**
|
37 |
* Where is the sign up page? Levels page or default multisite page.
|
84 |
* @since 1.7.14
|
85 |
*/
|
86 |
function pmpro_redirect_to_logged_in() {
|
87 |
+
// Fixes Site Health loopback test.
|
88 |
+
|
89 |
+
if( ( pmpro_is_login_page() || is_page("login") )
|
90 |
+
&& ! empty( $_REQUEST['redirect_to'] )
|
91 |
+
&& is_user_logged_in()
|
92 |
+
&& ( empty( $_REQUEST['action'] ) || $_REQUEST['action'] == 'login' )
|
93 |
+
&& empty( $_REQUEST['reauth']) ) {
|
94 |
+
|
95 |
+
wp_safe_redirect( esc_url_raw( $_REQUEST['redirect_to'] ) );
|
96 |
exit;
|
97 |
}
|
98 |
}
|
99 |
+
add_action("template_redirect", "pmpro_redirect_to_logged_in", 15);
|
100 |
add_action("login_init", "pmpro_redirect_to_logged_in", 5);
|
101 |
|
102 |
/**
|
106 |
* @since 2.3
|
107 |
*/
|
108 |
function pmpro_login_url_filter( $login_url='', $redirect='' ) {
|
109 |
+
// Don't filter when specifically on wp-login.php.
|
110 |
+
if ( $_SERVER['SCRIPT_NAME'] === '/wp-login.php' ) {
|
111 |
+
return $login_url;
|
112 |
+
}
|
113 |
+
|
114 |
+
// Check for a PMPro Login page.
|
115 |
$login_page_id = pmpro_getOption( 'login_page_id' );
|
116 |
if ( ! empty ( $login_page_id ) ) {
|
117 |
+
$login_page_permalink = get_permalink( $login_page_id );
|
118 |
+
// If the page or permalink is unavailable, don't override the url here.
|
119 |
+
if ( $login_page_permalink ) {
|
120 |
+
$login_url = $login_page_permalink;
|
121 |
+
}
|
122 |
|
123 |
if ( ! empty( $redirect ) ) {
|
124 |
$login_url = add_query_arg( 'redirect_to', urlencode( $redirect ), $login_url ) ;
|
136 |
*
|
137 |
*/
|
138 |
function pmpro_wp_loaded_login_setup() {
|
139 |
+
add_filter( 'login_url', 'pmpro_login_url_filter', 50, 2 );
|
140 |
}
|
141 |
add_action( 'wp_loaded', 'pmpro_wp_loaded_login_setup' );
|
142 |
|
147 |
function pmpro_use_default_login_for_confirm_admin_email( $location ) {
|
148 |
if ( strpos( $location, 'action=confirm_admin_email' ) !== false ) {
|
149 |
$login_url = wp_login_url();
|
150 |
+
|
151 |
remove_filter( 'login_url', 'pmpro_login_url_filter', 50, 2 );
|
152 |
$default_login_url = wp_login_url();
|
153 |
add_filter( 'login_url', 'pmpro_login_url_filter', 50, 2 );
|
154 |
+
|
155 |
if ( $login_url != $default_login_url ) {
|
156 |
$location = str_replace( $login_url, $default_login_url, $location );
|
157 |
}
|
158 |
}
|
159 |
+
|
160 |
return $location;
|
161 |
}
|
162 |
add_filter( 'wp_redirect', 'pmpro_use_default_login_for_confirm_admin_email' );
|
172 |
*/
|
173 |
function pmpro_login_url( $redirect = '', $force_reauth = false ) {
|
174 |
global $pmpro_pages;
|
175 |
+
|
176 |
if ( empty( $pmpro_pages['login'] ) ) {
|
177 |
// skip everything, including filter below
|
178 |
return wp_login_url( $redirect, $force_reauth );
|
179 |
}
|
180 |
+
|
181 |
$login_url = get_permalink( $pmpro_pages['login'] );
|
182 |
+
|
183 |
if ( ! empty( $redirect ) ) {
|
184 |
$login_url = add_query_arg( 'redirect_to', urlencode( $redirect ), $login_url );
|
185 |
}
|
186 |
+
|
187 |
if ( $force_reauth ) {
|
188 |
$login_url = add_query_arg( 'reauth', '1', $login_url );
|
189 |
}
|
190 |
+
|
191 |
/**
|
192 |
* Filters the login URL.
|
193 |
*
|
209 |
*/
|
210 |
function pmpro_lostpassword_url( $redirect = '' ) {
|
211 |
global $pmpro_pages;
|
212 |
+
|
213 |
if ( empty( $pmpro_pages['login'] ) ) {
|
214 |
// skip everything, including filter below
|
215 |
return wp_lostpassword_url( $redirect );
|
216 |
}
|
217 |
+
|
218 |
$args = array( 'action' => 'lostpassword' );
|
219 |
if ( ! empty( $redirect ) ) {
|
220 |
+
$args['redirect_to'] = urlencode( $redirect );
|
221 |
}
|
222 |
+
|
223 |
$lostpassword_url = add_query_arg( $args, get_permalink( $pmpro_pages['login'] ) );
|
224 |
+
|
225 |
/**
|
226 |
* Filters the Lost Password URL.
|
227 |
*
|
287 |
if ( empty( $pmpro_pages ) || empty ( $pmpro_pages['login'] ) || ! is_page( $pmpro_pages['login'] ) ) {
|
288 |
return $titleparts;
|
289 |
}
|
290 |
+
|
291 |
if ( is_user_logged_in() ) {
|
292 |
$titleparts['title'] = __( 'Welcome', 'paid-memberships-pro' );
|
293 |
} elseif ( ! empty( $_REQUEST['action'] ) && $_REQUEST['action'] === 'reset_pass' ) {
|
310 |
if ( $location === 'widget' && pmpro_is_login_page() ) {
|
311 |
return '';
|
312 |
}
|
313 |
+
|
314 |
// Set the message return string.
|
315 |
$message = '';
|
316 |
$msgt = 'pmpro_alert';
|
339 |
case 'recovered':
|
340 |
$message = __( 'Check your email for the confirmation link.', 'paid-memberships-pro' );
|
341 |
break;
|
342 |
+
case 'confirmaction':
|
343 |
+
// Check if we are processing a confirmaction for a Data Request.
|
344 |
+
$request_id = pmpro_confirmaction_handler();
|
345 |
+
$message = _wp_privacy_account_request_confirmed_message( $request_id );
|
346 |
+
$msgt = 'pmpro_success';
|
347 |
+
break;
|
348 |
}
|
349 |
}
|
350 |
|
394 |
}
|
395 |
|
396 |
if ( isset( $_GET['password'] ) ) {
|
397 |
+
switch( $_GET['password'] ) {
|
398 |
case 'changed':
|
399 |
$message = __( 'Your password has successfully been updated.', 'paid-memberships-pro' );
|
400 |
$msgt = 'pmpro_success';
|
444 |
|
445 |
// Note we don't show messages on the widget form.
|
446 |
if ( $message && $location !== 'widget' ) {
|
447 |
+
echo '<div class="' . pmpro_get_element_class( 'pmpro_message ' . $msgt, esc_attr( $msgt ) ) . '">'. wp_kses_post( $message ) .'</div>';
|
448 |
}
|
449 |
|
450 |
// Get the form title HTML tag.
|
463 |
}
|
464 |
|
465 |
// Figure out which login view to show.
|
466 |
+
if ( ! is_user_logged_in() ) {
|
467 |
if ( ! in_array( $action, array( 'reset_pass', 'rp' ) ) ) {
|
468 |
// Login form.
|
469 |
if ( empty( $_GET['login'] ) || empty( $_GET['key'] ) ) {
|
470 |
$username = isset( $_REQUEST['username'] ) ? sanitize_text_field( $_REQUEST['username'] ) : NULL;
|
471 |
$redirect_to = isset( $_REQUEST['redirect_to'] ) ? esc_url( $_REQUEST['redirect_to'] ) : NULL;
|
472 |
+
|
473 |
+
// Redirect users back to their page that they logged-in from via the widget.
|
474 |
+
if( empty( $redirect_to ) && $location === 'widget' && apply_filters( 'pmpro_login_widget_redirect_back', true ) ) {
|
475 |
$redirect_to = esc_url( site_url( $_SERVER['REQUEST_URI'] ) );
|
476 |
}
|
477 |
?>
|
478 |
<div class="<?php echo pmpro_get_element_class( 'pmpro_login_wrap' ); ?>">
|
479 |
+
<?php
|
480 |
if ( ! pmpro_is_login_page() ) {
|
481 |
+
echo $before_title . esc_html__( 'Log In', 'paid-memberships-pro' ) . $after_title;
|
482 |
}
|
483 |
?>
|
484 |
<?php
|
485 |
pmpro_login_form( array( 'value_username' => esc_html( $username ), 'redirect' => esc_url( $redirect_to ) ) );
|
486 |
pmpro_login_forms_handler_nav( 'login' );
|
487 |
?>
|
488 |
+
</div> <!-- end pmpro_login_wrap -->
|
489 |
<?php if ( pmpro_is_login_page() ) { ?>
|
490 |
<script>
|
491 |
document.getElementById('user_login').focus();
|
492 |
</script>
|
493 |
<?php } ?>
|
494 |
+
|
495 |
<?php
|
496 |
}
|
497 |
} elseif ( $location !== 'widget' && ( $action === 'reset_pass' || ( $action === 'rp' && in_array( $_REQUEST['login'], array( 'invalidkey', 'expiredkey' ) ) ) ) ) {
|
498 |
+
// Reset password form.
|
499 |
?>
|
500 |
<div class="<?php echo pmpro_get_element_class( 'pmpro_lost_password_wrap' ); ?>">
|
501 |
+
<?php
|
502 |
if ( ! pmpro_is_login_page() ) {
|
503 |
+
echo $before_title . esc_html__( 'Password Reset', 'paid-memberships-pro' ) . $after_title;
|
504 |
}
|
505 |
?>
|
506 |
<p class="<?php echo pmpro_get_element_class( 'pmpro_lost_password-instructions' ); ?>">
|
515 |
</div> <!-- end pmpro_lost_password_wrap -->
|
516 |
<?php
|
517 |
} elseif ( $location !== 'widget' && $action === 'rp' ) {
|
518 |
+
// Password reset processing key.
|
519 |
?>
|
520 |
<div class="<?php echo pmpro_get_element_class( 'pmpro_reset_password_wrap' ); ?>">
|
521 |
+
<?php
|
522 |
if ( ! pmpro_is_login_page() ) {
|
523 |
+
echo $before_title . esc_html__( 'Reset Password', 'paid-memberships-pro' ) . $after_title;
|
524 |
}
|
525 |
?>
|
526 |
<?php pmpro_reset_password_form(); ?>
|
538 |
<?php
|
539 |
}
|
540 |
}
|
541 |
+
|
542 |
$content = ob_get_clean();
|
543 |
if ( $echo ) {
|
544 |
echo $content;
|
545 |
}
|
546 |
+
|
547 |
return $content;
|
548 |
}
|
549 |
|
583 |
function pmpro_lost_password_redirect() {
|
584 |
if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) {
|
585 |
$login_page = pmpro_getOption( 'login_page_id' );
|
586 |
+
|
587 |
if ( empty( $login_page ) ) {
|
588 |
return;
|
589 |
}
|
590 |
+
|
591 |
$redirect_url = $login_page ? get_permalink( $login_page ): '';
|
592 |
|
593 |
$errors = retrieve_password();
|
607 |
* Redirect Password reset to our own page.
|
608 |
* @since 2.3
|
609 |
*/
|
610 |
+
function pmpro_reset_password_redirect() {
|
611 |
if ( 'GET' == $_SERVER['REQUEST_METHOD'] ) {
|
612 |
$login_page = pmpro_getOption( 'login_page_id' );
|
613 |
+
|
614 |
if ( empty( $login_page ) ) {
|
615 |
return;
|
616 |
}
|
617 |
+
|
618 |
$redirect_url = $login_page ? get_permalink( $login_page ): '';
|
619 |
$user = check_password_reset_key( $_REQUEST['rp_key'], $_REQUEST['rp_login'] );
|
620 |
+
|
621 |
if ( ! $user || is_wp_error( $user ) ) {
|
622 |
if ( $user && $user->get_error_code() === 'expired_key' ) {
|
623 |
wp_redirect( add_query_arg( 'login', urlencode( 'expiredkey' ), $redirect_url ) );
|
644 |
function pmpro_reset_password_form() {
|
645 |
if ( isset( $_REQUEST['login'] ) && isset( $_REQUEST['key'] ) ) {
|
646 |
|
647 |
+
// Check if reset key is valid.
|
648 |
+
$user = check_password_reset_key( $_REQUEST['key'], $_REQUEST['login'] );
|
649 |
+
$errors = new WP_Error();
|
650 |
+
if ( ! $user || is_wp_error( $user ) ) {
|
651 |
+
if ( $user && $user->get_error_code() === 'invalid_key' ) {
|
652 |
+
$errors->add( 'invalidkey', __( 'Your password reset link appears to be invalid. Please request a new link below.', 'paid-membeships-pro' ) );
|
653 |
+
} elseif ( $user && $user->get_error_code() === 'expired_key' ) {
|
654 |
+
$errors->add( 'expiredkey', __( 'Your password reset link has expired. Please request a new link below.', 'paid-membeships-pro' ) );
|
655 |
+
}
|
656 |
+
}
|
657 |
+
|
658 |
+
// Grabbing errors from $_GET like wp-login.php does.
|
659 |
+
if ( isset( $_GET['error'] ) ) {
|
660 |
+
if ( 'invalidkey' === $_GET['error'] ) {
|
661 |
+
$errors->add( 'invalidkey', __( 'Your password reset link appears to be invalid. Please request a new link below.', 'paid-membeships-pro' ) );
|
662 |
+
} elseif ( 'expiredkey' === $_GET['error'] ) {
|
663 |
+
$errors->add( 'expiredkey', __( 'Your password reset link has expired. Please request a new link below.', 'paid-membeships-pro' ) );
|
664 |
+
}
|
665 |
+
}
|
666 |
+
|
667 |
+
if ( ! empty( $errors ) && $errors->has_errors() ) {
|
668 |
+
// Combine errors into one message.
|
669 |
+
$message = '';
|
670 |
+
foreach ( $errors->get_error_codes() as $code ) {
|
671 |
+
foreach ( $errors->get_error_messages( $code ) as $error_message ) {
|
672 |
+
$message .= ' ' . $error_message . ' ';
|
673 |
+
}
|
674 |
+
}
|
675 |
+
|
676 |
+
$msgt = 'pmpro_error';
|
677 |
+
echo '<div class="' . pmpro_get_element_class( 'pmpro_message ' . $msgt, esc_attr( $msgt ) ) . '">'. esc_html( $message ) .'</div>';
|
678 |
+
echo pmpro_lost_password_form();
|
679 |
+
return;
|
680 |
+
}
|
681 |
+
|
682 |
+
?>
|
683 |
<form name="resetpassform" id="resetpassform" class="<?php echo pmpro_get_element_class( 'pmpro_form', 'resetpassform' ); ?>" action="<?php echo esc_url( site_url( 'wp-login.php?action=resetpass' ) ); ?>" method="post" autocomplete="off">
|
684 |
<input type="hidden" id="user_login" name="rp_login" value="<?php echo esc_attr( sanitize_text_field( $_REQUEST['login'] ) ); ?>" autocomplete="off" />
|
685 |
<input type="hidden" name="rp_key" value="<?php echo esc_attr( sanitize_text_field( $_REQUEST['key'] ) ); ?>" />
|
755 |
function pmpro_do_password_reset() {
|
756 |
if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) {
|
757 |
$login_page = pmpro_getOption( 'login_page_id' );
|
758 |
+
|
759 |
if ( empty( $login_page ) ) {
|
760 |
return;
|
761 |
}
|
762 |
+
|
763 |
$rp_key = sanitize_text_field( $_REQUEST['rp_key'] );
|
764 |
+
$rp_login = sanitize_text_field( $_REQUEST['rp_login'] );
|
765 |
+
|
766 |
$redirect_url = $login_page ? get_permalink( $login_page ): '';
|
767 |
$user = check_password_reset_key( $rp_key, $rp_login );
|
768 |
|
821 |
*
|
822 |
* @since 2.3
|
823 |
*/
|
824 |
+
function pmpro_password_reset_email_filter( $message, $key, $user_login ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
825 |
|
826 |
$login_page_id = pmpro_getOption( 'login_page_id' );
|
827 |
if ( ! empty ( $login_page_id ) ) {
|
828 |
+
$login_url = get_permalink( $login_page_id );
|
829 |
+
if ( strpos( $login_url, '?' ) ) {
|
830 |
+
// Login page permalink contains a '?', so we need to replace the '?' already in the login URL with '&'.
|
831 |
+
$message = str_replace( network_site_url( 'wp-login.php' ) . '?', $login_url . '&', $message );
|
832 |
+
}
|
833 |
$message = str_replace( network_site_url( 'wp-login.php' ), $login_url, $message );
|
834 |
}
|
835 |
|
836 |
return $message;
|
837 |
}
|
838 |
+
add_filter( 'retrieve_password_message', 'pmpro_password_reset_email_filter', 20, 3 );
|
839 |
+
add_filter( 'wp_new_user_notification_email', 'pmpro_password_reset_email_filter', 10, 3 );
|
840 |
|
841 |
/**
|
842 |
* Authenticate the frontend user login.
|
887 |
*/
|
888 |
function pmpro_login_failed( $username ) {
|
889 |
|
890 |
+
$login_page = pmpro_getOption( 'login_page_id' );
|
891 |
if ( empty( $login_page ) ) {
|
892 |
return;
|
893 |
}
|
995 |
if ( empty( $_REQUEST['action'] ) || $_REQUEST['action'] !== 'confirmaction' ) {
|
996 |
return false;
|
997 |
}
|
998 |
+
|
999 |
if ( ! isset( $_GET['request_id'] ) ) {
|
1000 |
wp_die( __( 'Missing request ID.' ) );
|
1001 |
}
|
1014 |
|
1015 |
/** This action is documented in wp-login.php */
|
1016 |
do_action( 'user_request_action_confirmed', $request_id );
|
1017 |
+
|
1018 |
+
return $request_id;
|
1019 |
+
}
|
includes/metaboxes.php
CHANGED
@@ -5,9 +5,28 @@
|
|
5 |
function pmpro_page_meta() {
|
6 |
global $post, $wpdb;
|
7 |
$membership_levels = pmpro_getAllLevels( true, true );
|
|
|
8 |
$page_levels = $wpdb->get_col( "SELECT membership_id FROM {$wpdb->pmpro_memberships_pages} WHERE page_id = '" . intval( $post->ID ) . "'" );
|
9 |
-
|
10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
<input type="hidden" name="pmpro_noncename" id="pmpro_noncename" value="<?php echo esc_attr( wp_create_nonce( plugin_basename(__FILE__) ) )?>" />
|
12 |
<?php
|
13 |
$in_member_cat = false;
|
@@ -37,7 +56,8 @@ function pmpro_page_meta() {
|
|
37 |
<p class="pmpro_meta_notice">* <?php _e("This post is already protected for this level because it is within a category that requires membership.", 'paid-memberships-pro' );?></p>
|
38 |
<?php
|
39 |
}
|
40 |
-
|
|
|
41 |
do_action( 'pmpro_after_require_membership_metabox', $post );
|
42 |
?>
|
43 |
<?php
|
5 |
function pmpro_page_meta() {
|
6 |
global $post, $wpdb;
|
7 |
$membership_levels = pmpro_getAllLevels( true, true );
|
8 |
+
$membership_levels = pmpro_sort_levels_by_order( $membership_levels );
|
9 |
$page_levels = $wpdb->get_col( "SELECT membership_id FROM {$wpdb->pmpro_memberships_pages} WHERE page_id = '" . intval( $post->ID ) . "'" );
|
10 |
+
|
11 |
+
// Build the selectors for the #memberships list based on level count.
|
12 |
+
$pmpro_memberships_checklist_classes = array( 'list:category', 'categorychecklist', 'form-no-clear');
|
13 |
+
if ( count( $membership_levels ) > 9 ) {
|
14 |
+
$pmpro_memberships_checklist_classes[] = "pmpro_scrollable";
|
15 |
+
}
|
16 |
+
$pmpro_memberships_checklist_classes = implode( ' ', array_unique( $pmpro_memberships_checklist_classes ) );
|
17 |
+
|
18 |
+
if ( count( $membership_levels ) > 1 ) { ?>
|
19 |
+
<p><?php esc_html_e( 'Select:', 'paid-memberships-pro' ); ?> <a id="pmpro-memberships-checklist-select-all" href="javascript:void(0);"><?php esc_html_e( 'All', 'paid-memberships-pro' ); ?></a> | <a id="pmpro-memberships-checklist-select-none" href="javascript:void(0);"><?php esc_html_e( 'None', 'paid-memberships-pro' ); ?></a></p>
|
20 |
+
<script type="text/javascript">
|
21 |
+
jQuery('#pmpro-memberships-checklist-select-all').click(function(){
|
22 |
+
jQuery('#pmpro-memberships-checklist input').prop('checked', true);
|
23 |
+
});
|
24 |
+
jQuery('#pmpro-memberships-checklist-select-none').click(function(){
|
25 |
+
jQuery('#pmpro-memberships-checklist input').prop('checked', false);
|
26 |
+
});
|
27 |
+
</script>
|
28 |
+
<?php } ?>
|
29 |
+
<ul id="pmpro-memberships-checklist" class="<?php echo esc_attr( $pmpro_memberships_checklist_classes ); ?>">
|
30 |
<input type="hidden" name="pmpro_noncename" id="pmpro_noncename" value="<?php echo esc_attr( wp_create_nonce( plugin_basename(__FILE__) ) )?>" />
|
31 |
<?php
|
32 |
$in_member_cat = false;
|
56 |
<p class="pmpro_meta_notice">* <?php _e("This post is already protected for this level because it is within a category that requires membership.", 'paid-memberships-pro' );?></p>
|
57 |
<?php
|
58 |
}
|
59 |
+
?>
|
60 |
+
<?php
|
61 |
do_action( 'pmpro_after_require_membership_metabox', $post );
|
62 |
?>
|
63 |
<?php
|
includes/notifications.php
CHANGED
@@ -44,6 +44,7 @@ function pmpro_notifications() {
|
|
44 |
'class' => array(),
|
45 |
),
|
46 |
'br' => array(),
|
|
|
47 |
);
|
48 |
echo wp_kses( $notification->content, $allowed_html );
|
49 |
?>
|
@@ -434,14 +435,17 @@ function pmpro_notification_test_pmpro_setting( $data ) {
|
|
434 |
|
435 |
/**
|
436 |
* PMPro site URL test.
|
437 |
-
* @param string $string String to look for in the site URL
|
438 |
* @returns bool true if the string shows up in the site URL
|
439 |
*/
|
440 |
-
function pmpro_notification_test_site_url_match( $string ) {
|
441 |
if ( ! empty( $string ) ) {
|
442 |
-
|
443 |
-
|
444 |
-
|
|
|
|
|
|
|
445 |
}
|
446 |
return false;
|
447 |
}
|
44 |
'class' => array(),
|
45 |
),
|
46 |
'br' => array(),
|
47 |
+
'strike' => array(),
|
48 |
);
|
49 |
echo wp_kses( $notification->content, $allowed_html );
|
50 |
?>
|
435 |
|
436 |
/**
|
437 |
* PMPro site URL test.
|
438 |
+
* @param string $string String or array of strings to look for in the site URL
|
439 |
* @returns bool true if the string shows up in the site URL
|
440 |
*/
|
441 |
+
function pmpro_notification_test_site_url_match( $string ) {
|
442 |
if ( ! empty( $string ) ) {
|
443 |
+
$strings_to_check = (array) $string;
|
444 |
+
foreach( $strings_to_check as $check ) {
|
445 |
+
if ( strpos( get_bloginfo( 'url' ), $check ) !== false ) {
|
446 |
+
return true;
|
447 |
+
}
|
448 |
+
}
|
449 |
}
|
450 |
return false;
|
451 |
}
|
includes/profile.php
CHANGED
@@ -40,31 +40,7 @@ function pmpro_membership_level_profile_fields($user)
|
|
40 |
<?php
|
41 |
}
|
42 |
?>
|
43 |
-
</select>
|
44 |
-
<span id="current_level_cost">
|
45 |
-
<?php
|
46 |
-
$membership_values = pmpro_getMembershipLevelForUser($user->ID);
|
47 |
-
|
48 |
-
//we tweak the initial payment here so the text here effectively shows the recurring amount
|
49 |
-
if(!empty($membership_values))
|
50 |
-
{
|
51 |
-
$membership_values->original_initial_payment = $membership_values->initial_payment;
|
52 |
-
$membership_values->initial_payment = $membership_values->billing_amount;
|
53 |
-
}
|
54 |
-
|
55 |
-
if(empty($membership_values) || pmpro_isLevelFree($membership_values))
|
56 |
-
{
|
57 |
-
if(!empty($membership_values->original_initial_payment) && $membership_values->original_initial_payment > 0)
|
58 |
-
echo __('Paid', 'paid-memberships-pro' ) . pmpro_formatPrice($membership_values->original_initial_payment) . ".";
|
59 |
-
else
|
60 |
-
_e('Not paying.', 'paid-memberships-pro' );
|
61 |
-
}
|
62 |
-
else
|
63 |
-
{
|
64 |
-
echo pmpro_getLevelCost($membership_values, true, true);
|
65 |
-
}
|
66 |
-
?>
|
67 |
-
</span>
|
68 |
<p id="cancel_description" class="description hidden"><?php _e("This will not change the subscription at the gateway unless the 'Cancel' checkbox is selected below.", 'paid-memberships-pro' ); ?></p>
|
69 |
</td>
|
70 |
</tr>
|
@@ -81,6 +57,9 @@ function pmpro_membership_level_profile_fields($user)
|
|
81 |
$selected_expires_day = date( 'j', $end_date ? $user->membership_level->enddate : current_time('timestamp') );
|
82 |
$selected_expires_month = date( 'm', $end_date ? $user->membership_level->enddate : current_time('timestamp') );
|
83 |
$selected_expires_year = date( 'Y', $end_date ? $user->membership_level->enddate : current_time('timestamp') );
|
|
|
|
|
|
|
84 |
?>
|
85 |
<tr>
|
86 |
<th><label for="expiration"><?php _e("Expires", 'paid-memberships-pro' ); ?></label></th>
|
@@ -103,6 +82,21 @@ function pmpro_membership_level_profile_fields($user)
|
|
103 |
</select>
|
104 |
<input name="expires_day" type="text" size="2" value="<?php echo $selected_expires_day?>" />
|
105 |
<input name="expires_year" type="text" size="4" value="<?php echo $selected_expires_year?>" />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
</span>
|
107 |
<script>
|
108 |
jQuery('#expires').change(function() {
|
@@ -140,17 +134,19 @@ function pmpro_membership_level_profile_fields($user)
|
|
140 |
<th><label for="tos_consent_history"><?php _e("TOS Consent History", 'paid-memberships-pro' ); ?></label></th>
|
141 |
<td id="tos_consent_history">
|
142 |
<?php
|
143 |
-
if( !empty( $consent_log ) ) {
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
|
|
148 |
}
|
149 |
-
|
|
|
150 |
foreach( $consent_log as $entry ) {
|
151 |
echo '<li>' . pmpro_consent_to_text( $entry ) . '</li>';
|
152 |
}
|
153 |
-
echo '</ul>';
|
154 |
} else {
|
155 |
echo __( 'N/A', 'paid-memberships-pro' );
|
156 |
}
|
@@ -313,6 +309,14 @@ function pmpro_membership_level_profile_fields_update()
|
|
313 |
{
|
314 |
//update the expiration date
|
315 |
$expiration_date = intval($_REQUEST['expires_year']) . "-" . str_pad(intval($_REQUEST['expires_month']), 2, "0", STR_PAD_LEFT) . "-" . str_pad(intval($_REQUEST['expires_day']), 2, "0", STR_PAD_LEFT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
316 |
$sqlQuery = "UPDATE $wpdb->pmpro_memberships_users SET enddate = '" . $expiration_date . "' WHERE status = 'active' AND membership_id = '" . intval($_REQUEST['membership_level']) . "' AND user_id = '" . $user_ID . "' LIMIT 1";
|
317 |
if($wpdb->query($sqlQuery))
|
318 |
$expiration_changed = true;
|
@@ -357,6 +361,250 @@ add_action( 'edit_user_profile', 'pmpro_membership_level_profile_fields' );
|
|
357 |
add_action( 'personal_options_update', 'pmpro_membership_level_profile_fields_update' );
|
358 |
add_action( 'edit_user_profile_update', 'pmpro_membership_level_profile_fields_update' );
|
359 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
/**
|
361 |
* Sanitizes the passed value.
|
362 |
*
|
@@ -405,13 +653,12 @@ function pmpro_member_profile_edit_form() {
|
|
405 |
return;
|
406 |
}
|
407 |
|
408 |
-
do_action( 'pmpro_personal_options_update', $current_user->ID );
|
409 |
-
|
410 |
// Saving profile updates.
|
411 |
if ( isset( $_POST['action'] ) && $_POST['action'] == 'update-profile' && $current_user->ID == $_POST['user_id'] && wp_verify_nonce( $_POST['update_user_nonce'], 'update-user_' . $current_user->ID ) ) {
|
412 |
$update = true;
|
413 |
$user = new stdClass;
|
414 |
$user->ID = $_POST[ 'user_id' ];
|
|
|
415 |
} else {
|
416 |
$update = false;
|
417 |
}
|
40 |
<?php
|
41 |
}
|
42 |
?>
|
43 |
+
</select>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
<p id="cancel_description" class="description hidden"><?php _e("This will not change the subscription at the gateway unless the 'Cancel' checkbox is selected below.", 'paid-memberships-pro' ); ?></p>
|
45 |
</td>
|
46 |
</tr>
|
57 |
$selected_expires_day = date( 'j', $end_date ? $user->membership_level->enddate : current_time('timestamp') );
|
58 |
$selected_expires_month = date( 'm', $end_date ? $user->membership_level->enddate : current_time('timestamp') );
|
59 |
$selected_expires_year = date( 'Y', $end_date ? $user->membership_level->enddate : current_time('timestamp') );
|
60 |
+
$selected_expires_hour = date( 'H', $end_date ? $user->membership_level->enddate : current_time('timestamp') );
|
61 |
+
|
62 |
+
$selected_expires_minute = date( 'i', $end_date ? $user->membership_level->enddate : current_time('timestamp') );
|
63 |
?>
|
64 |
<tr>
|
65 |
<th><label for="expiration"><?php _e("Expires", 'paid-memberships-pro' ); ?></label></th>
|
82 |
</select>
|
83 |
<input name="expires_day" type="text" size="2" value="<?php echo $selected_expires_day?>" />
|
84 |
<input name="expires_year" type="text" size="4" value="<?php echo $selected_expires_year?>" />
|
85 |
+
<?php _e('at', 'paid-memberships-pro'); ?>
|
86 |
+
<select name='expires_hour'>
|
87 |
+
<?php
|
88 |
+
for( $i = 0; $i <= 24; $i++ ){
|
89 |
+
echo "<option value='".$i."' ".selected( $selected_expires_hour, sprintf("%02d", $i ), true ).">".sprintf("%02d", $i )."</option>";
|
90 |
+
}
|
91 |
+
?>
|
92 |
+
</select>
|
93 |
+
<select name='expires_minute'>
|
94 |
+
<?php
|
95 |
+
for( $i = 0; $i <= 59; $i++ ){
|
96 |
+
echo "<option value='".$i."' ".selected( $selected_expires_minute, sprintf("%02d", $i ), true ).">".sprintf("%02d", $i )."</option>";
|
97 |
+
}
|
98 |
+
?>
|
99 |
+
</select>
|
100 |
</span>
|
101 |
<script>
|
102 |
jQuery('#expires').change(function() {
|
134 |
<th><label for="tos_consent_history"><?php _e("TOS Consent History", 'paid-memberships-pro' ); ?></label></th>
|
135 |
<td id="tos_consent_history">
|
136 |
<?php
|
137 |
+
if ( ! empty( $consent_log ) ) {
|
138 |
+
// Build the selectors for the invoices history list based on history count.
|
139 |
+
$consent_log_classes = array();
|
140 |
+
$consent_log_classes[] = "pmpro_consent_log";
|
141 |
+
if ( count( $consent_log ) > 5 ) {
|
142 |
+
$consent_log_classes[] = "pmpro_scrollable";
|
143 |
}
|
144 |
+
$consent_log_class = implode( ' ', array_unique( $consent_log_classes ) );
|
145 |
+
echo '<ul class="' . esc_attr( $consent_log_class ) . '">';
|
146 |
foreach( $consent_log as $entry ) {
|
147 |
echo '<li>' . pmpro_consent_to_text( $entry ) . '</li>';
|
148 |
}
|
149 |
+
echo '</ul> <!-- end pmpro_consent_log -->';
|
150 |
} else {
|
151 |
echo __( 'N/A', 'paid-memberships-pro' );
|
152 |
}
|
309 |
{
|
310 |
//update the expiration date
|
311 |
$expiration_date = intval($_REQUEST['expires_year']) . "-" . str_pad(intval($_REQUEST['expires_month']), 2, "0", STR_PAD_LEFT) . "-" . str_pad(intval($_REQUEST['expires_day']), 2, "0", STR_PAD_LEFT);
|
312 |
+
if( !empty( $_REQUEST['expires_hour'] ) ){
|
313 |
+
if( !empty( $_REQUEST['expires_minute'] ) ){
|
314 |
+
$expiration_date = $expiration_date ." ".$_REQUEST['expires_hour'].":".$_REQUEST['expires_minute'].":00";
|
315 |
+
} else{
|
316 |
+
$expiration_date = $expiration_date ." ".$_REQUEST['expires_hour'].":00:00";
|
317 |
+
}
|
318 |
+
}
|
319 |
+
|
320 |
$sqlQuery = "UPDATE $wpdb->pmpro_memberships_users SET enddate = '" . $expiration_date . "' WHERE status = 'active' AND membership_id = '" . intval($_REQUEST['membership_level']) . "' AND user_id = '" . $user_ID . "' LIMIT 1";
|
321 |
if($wpdb->query($sqlQuery))
|
322 |
$expiration_changed = true;
|
361 |
add_action( 'personal_options_update', 'pmpro_membership_level_profile_fields_update' );
|
362 |
add_action( 'edit_user_profile_update', 'pmpro_membership_level_profile_fields_update' );
|
363 |
|
364 |
+
|
365 |
+
/**
|
366 |
+
* Add the history view to the user profile
|
367 |
+
*
|
368 |
+
*/
|
369 |
+
function pmpro_membership_history_profile_fields( $user ) {
|
370 |
+
global $current_user;
|
371 |
+
$membership_level_capability = apply_filters( 'pmpro_edit_member_capability', 'manage_options' );
|
372 |
+
|
373 |
+
if ( ! current_user_can( $membership_level_capability ) ) {
|
374 |
+
return false;
|
375 |
+
}
|
376 |
+
|
377 |
+
global $wpdb;
|
378 |
+
|
379 |
+
//Show all invoices for user
|
380 |
+
$invoices = $wpdb->get_results("SELECT mo.*, UNIX_TIMESTAMP(mo.timestamp) as timestamp, du.code_id as code_id FROM $wpdb->pmpro_membership_orders mo LEFT JOIN $wpdb->pmpro_discount_codes_uses du ON mo.id = du.order_id WHERE mo.user_id = '$user->ID' ORDER BY mo.timestamp DESC");
|
381 |
+
|
382 |
+
$levelshistory = $wpdb->get_results("SELECT * FROM $wpdb->pmpro_memberships_users WHERE user_id = '$user->ID' ORDER BY id DESC");
|
383 |
+
|
384 |
+
$totalvalue = $wpdb->get_var("SELECT SUM(total) FROM $wpdb->pmpro_membership_orders WHERE user_id = '$user->ID' AND status NOT IN('token','review','pending','error','refunded')");
|
385 |
+
|
386 |
+
if ( $invoices || $levelshistory ) { ?>
|
387 |
+
<hr />
|
388 |
+
<h3><?php esc_html_e( 'Member History', 'paid-memberships-pro' ); ?></h3>
|
389 |
+
<p><strong><?php esc_html_e( 'Total Paid', 'paid-memberships-pro' ); ?></strong> <?php echo pmpro_formatPrice( $totalvalue ); ?></p>
|
390 |
+
<ul id="member-history-filters" class="subsubsub">
|
391 |
+
<li id="member-history-filters-orders"><a href="javascript:void(0);" class="current orders tab"><?php esc_html_e( 'Order History', 'paid-memberships-pro' ); ?></a> <span>(<?php echo count( $invoices ); ?>)</span></li>
|
392 |
+
<li id="member-history-filters-memberships">| <a href="javascript:void(0);" class="tab"><?php esc_html_e( 'Membership Levels History', 'paid-memberships-pro' ); ?></a> <span>(<?php echo count( $levelshistory ); ?>)</span></li>
|
393 |
+
</ul>
|
394 |
+
<br class="clear" />
|
395 |
+
<?php
|
396 |
+
// Build the selectors for the invoices history list based on history count.
|
397 |
+
$invoices_classes = array();
|
398 |
+
$invoices_classes[] = "widgets-holder-wrap";
|
399 |
+
if ( ! empty( $invoices ) && count( $invoices ) > 2 ) {
|
400 |
+
$invoices_classes[] = "pmpro_scrollable";
|
401 |
+
}
|
402 |
+
$invoice_class = implode( ' ', array_unique( $invoices_classes ) );
|
403 |
+
?>
|
404 |
+
<div id="member-history-orders" class="<?php echo esc_attr( $invoice_class ); ?>">
|
405 |
+
<?php if ( $invoices ) { ?>
|
406 |
+
<table class="wp-list-table widefat striped fixed" width="100%" cellpadding="0" cellspacing="0" border="0">
|
407 |
+
<thead>
|
408 |
+
<tr>
|
409 |
+
<th><?php esc_html_e( 'Date', 'paid-memberships-pro' ); ?></th>
|
410 |
+
<th><?php esc_html_e( 'Invoice ID', 'paid-memberships-pro' ); ?></th>
|
411 |
+
<th><?php esc_html_e( 'Level', 'paid-memberships-pro' ); ?></th>
|
412 |
+
<th><?php esc_html_e( 'Level ID', 'paid-memberships-pro' ); ?>
|
413 |
+
<th><?php esc_html_e( 'Total Billed', 'paid-memberships-pro' ); ?></th>
|
414 |
+
<th><?php esc_html_e( 'Discount Code', 'paid-memberships-pro' ); ?></th>
|
415 |
+
<th><?php esc_html_e( 'Status', 'paid-memberships-pro' ); ?></th>
|
416 |
+
<?php do_action('pmpromh_orders_extra_cols_header');?>
|
417 |
+
</tr>
|
418 |
+
</thead>
|
419 |
+
<tbody>
|
420 |
+
<?php
|
421 |
+
foreach ( $invoices as $invoice ) {
|
422 |
+
$level = pmpro_getLevel( $invoice->membership_id );
|
423 |
+
?>
|
424 |
+
<tr>
|
425 |
+
<td><?php echo date_i18n( get_option( 'date_format'), $invoice->timestamp ); ?></td>
|
426 |
+
<td class="order_code column-order_code has-row-actions">
|
427 |
+
<a href="<?php echo add_query_arg( array( 'page' => 'pmpro-orders', 'order' => $invoice->id ), admin_url('admin.php' ) ); ?>"><?php echo $invoice->code; ?></a><br />
|
428 |
+
<div class="row-actions">
|
429 |
+
<span class="edit">
|
430 |
+
<a title="<?php esc_html_e( 'Edit', 'paid-memberships-pro' ); ?>" href="<?php echo add_query_arg( array( 'page' => 'pmpro-orders', 'order' => $invoice->id ), admin_url('admin.php' ) ); ?>"><?php esc_html_e( 'Edit', 'paid-memberships-pro' ); ?></a>
|
431 |
+
</span> |
|
432 |
+
<span class="print">
|
433 |
+
<a target="_blank" title="<?php _e( 'Print', 'paid-memberships-pro' ); ?>" href="<?php echo add_query_arg( array( 'action' => 'pmpro_orders_print_view', 'order' => $invoice->id ), admin_url('admin-ajax.php' ) ); ?>"><?php esc_html_e( 'Print', 'paid-memberships-pro' ); ?></a>
|
434 |
+
</span>
|
435 |
+
<?php if ( function_exists( 'pmpro_add_email_order_modal' ) ) { ?>
|
436 |
+
|
|
437 |
+
<span class="email">
|
438 |
+
<a title="<?php esc_html_e( 'Email', 'paid-memberships-pro' ); ?>" href="#TB_inline?width=600&height=200&inlineId=email_invoice" class="thickbox email_link" data-order="<?php echo esc_attr( $invoice->id ); ?>"><?php _e( 'Email', 'paid-memberships-pro' ); ?></a>
|
439 |
+
</span>
|
440 |
+
<?php } ?>
|
441 |
+
</div> <!-- end .row-actions -->
|
442 |
+
</td>
|
443 |
+
<td><?php if ( ! empty( $level ) ) { echo $level->name; } else { _e( 'N/A', 'paid-memberships-pro'); } ?></td>
|
444 |
+
<td><?php if ( ! empty( $level ) ) { echo $level->id; } else { _e( 'N/A', 'paid-memberships-pro'); } ?></td>
|
445 |
+
<td><?php echo pmpro_formatPrice( $invoice->total ); ?></td>
|
446 |
+
<td><?php
|
447 |
+
if ( empty( $invoice->code_id ) ) {
|
448 |
+
echo '-';
|
449 |
+
} else {
|
450 |
+
$discountQuery = "SELECT c.code FROM $wpdb->pmpro_discount_codes c WHERE c.id = ".$invoice->code_id." LIMIT 1";
|
451 |
+
$discount_code = $wpdb->get_row( $discountQuery );
|
452 |
+
echo '<a href="admin.php?page=pmpro-discountcodes&edit='.$invoice->code_id.'">'. esc_attr( $discount_code->code ) . '</a>';
|
453 |
+
}
|
454 |
+
?></td>
|
455 |
+
<td>
|
456 |
+
<?php
|
457 |
+
if ( empty( $invoice->status ) ) {
|
458 |
+
echo '-';
|
459 |
+
} else {
|
460 |
+
echo esc_html( $invoice->status );
|
461 |
+
}
|
462 |
+
?>
|
463 |
+
</td>
|
464 |
+
<?php do_action( 'pmpromh_orders_extra_cols_body', $invoice ); ?>
|
465 |
+
</tr>
|
466 |
+
<?php
|
467 |
+
}
|
468 |
+
?>
|
469 |
+
</tbody>
|
470 |
+
</table>
|
471 |
+
<?php } else { ?>
|
472 |
+
<table class="wp-list-table widefat striped fixed" width="100%" cellpadding="0" cellspacing="0" border="0">
|
473 |
+
<tbody>
|
474 |
+
<tr>
|
475 |
+
<td><?php esc_html_e( 'No membership orders found.', 'paid-memberships-pro' ); ?></td>
|
476 |
+
</tr>
|
477 |
+
</tbody>
|
478 |
+
</table>
|
479 |
+
<?php } ?>
|
480 |
+
</div> <!-- end #member-history-invoices -->
|
481 |
+
<?php
|
482 |
+
// Build the selectors for the membership levels history list based on history count.
|
483 |
+
$levelshistory_classes = array();
|
484 |
+
$levelshistory_classes[] = "widgets-holder-wrap";
|
485 |
+
if ( ! empty( $levelshistory ) && count( $levelshistory ) > 4 ) {
|
486 |
+
$levelshistory_classes[] = "pmpro_scrollable";
|
487 |
+
}
|
488 |
+
$levelshistory_class = implode( ' ', array_unique( $levelshistory_classes ) );
|
489 |
+
?>
|
490 |
+
<div id="member-history-memberships" class="<?php echo esc_attr( $levelshistory_class ); ?>" style="display: none;">
|
491 |
+
<?php if ( $levelshistory ) { ?>
|
492 |
+
<table class="wp-list-table widefat striped fixed" width="100%" cellpadding="0" cellspacing="0" border="0">
|
493 |
+
<thead>
|
494 |
+
<tr>
|
495 |
+
<th><?php esc_html_e( 'Level ID', 'paid-memberships-pro' ); ?>
|
496 |
+
<th><?php esc_html_e( 'Level', 'paid-memberships-pro' ); ?></th>
|
497 |
+
<th><?php esc_html_e( 'Start Date', 'paid-memberships-pro' ); ?></th>
|
498 |
+
<th><?php esc_html_e( 'Date Modified', 'paid-memberships-pro' ); ?></th>
|
499 |
+
<th><?php esc_html_e( 'End Date', 'paid-memberships-pro' ); ?></th>
|
500 |
+
<th><?php esc_html_e( 'Level Cost', 'paid-memberships-pro' ); ?></th>
|
501 |
+
<th><?php esc_html_e( 'Status', 'paid-memberships-pro' ); ?></th>
|
502 |
+
<?php do_action( 'pmpromh_member_history_extra_cols_header' ); ?>
|
503 |
+
</tr>
|
504 |
+
</thead>
|
505 |
+
<tbody>
|
506 |
+
<?php
|
507 |
+
foreach ( $levelshistory as $levelhistory ) {
|
508 |
+
$level = pmpro_getLevel( $levelhistory->membership_id );
|
509 |
+
|
510 |
+
if ( $levelhistory->enddate === null || $levelhistory->enddate == '0000-00-00 00:00:00' ) {
|
511 |
+
$levelhistory->enddate = __( 'Never', 'paid-memberships-pro' );
|
512 |
+
} else {
|
513 |
+
$levelhistory->enddate = date_i18n( get_option( 'date_format'), strtotime( $levelhistory->enddate ) );
|
514 |
+
} ?>
|
515 |
+
<tr>
|
516 |
+
<td><?php if ( ! empty( $level ) ) { echo $level->id; } else { esc_html_e( 'N/A', 'paid-memberships-pro' ); } ?></td>
|
517 |
+
<td><?php if ( ! empty( $level ) ) { echo $level->name; } else { esc_html_e( 'N/A', 'paid-memberships-pro' ); } ?></td>
|
518 |
+
<td><?php echo ( $levelhistory->startdate === '0000-00-00 00:00:00' ? __('N/A', 'paid-memberships-pro') : date_i18n( get_option( 'date_format' ), strtotime( $levelhistory->startdate ) ) ); ?></td>
|
519 |
+
<td><?php echo date_i18n( get_option( 'date_format'), strtotime( $levelhistory->modified ) ); ?></td>
|
520 |
+
<td><?php echo esc_html( $levelhistory->enddate ); ?></td>
|
521 |
+
<td><?php echo pmpro_getLevelCost( $levelhistory, true, true ); ?></td>
|
522 |
+
<td>
|
523 |
+
<?php
|
524 |
+
if ( empty( $levelhistory->status ) ) {
|
525 |
+
echo '-';
|
526 |
+
} else {
|
527 |
+
echo esc_html( $levelhistory->status );
|
528 |
+
}
|
529 |
+
?>
|
530 |
+
</td>
|
531 |
+
<?php do_action( 'pmpromh_member_history_extra_cols_body', $user, $level ); ?>
|
532 |
+
</tr>
|
533 |
+
<?php
|
534 |
+
}
|
535 |
+
?>
|
536 |
+
</tbody>
|
537 |
+
</table>
|
538 |
+
<?php } else { ?>
|
539 |
+
<table class="wp-list-table widefat striped fixed" width="100%" cellpadding="0" cellspacing="0" border="0">
|
540 |
+
<tbody>
|
541 |
+
<tr>
|
542 |
+
<td><?php esc_html_e( 'No membership history found.', 'paid-memberships-pro'); ?></td>
|
543 |
+
</tr>
|
544 |
+
</tbody>
|
545 |
+
</table>
|
546 |
+
<?php } ?>
|
547 |
+
</div> <!-- end #member-history-memberships -->
|
548 |
+
<script>
|
549 |
+
//tabs
|
550 |
+
jQuery(document).ready(function() {
|
551 |
+
jQuery('#member-history-filters a.tab').click(function() {
|
552 |
+
//which tab?
|
553 |
+
var tab = jQuery(this).parent().attr('id').replace('member-history-filters-', '');
|
554 |
+
|
555 |
+
//un select tabs
|
556 |
+
jQuery('#member-history-filters a.tab').removeClass('current');
|
557 |
+
|
558 |
+
//select this tab
|
559 |
+
jQuery('#member-history-filters-'+tab+' a').addClass('current');
|
560 |
+
|
561 |
+
//show orders?
|
562 |
+
if(tab == 'orders')
|
563 |
+
{
|
564 |
+
jQuery('#member-history-memberships').hide();
|
565 |
+
jQuery('#member-history-orders').show();
|
566 |
+
}
|
567 |
+
else
|
568 |
+
{
|
569 |
+
jQuery('div#member-history-orders').hide();
|
570 |
+
jQuery('#member-history-memberships').show();
|
571 |
+
|
572 |
+
<?php if ( count( $levelshistory ) > 5 ) { ?>
|
573 |
+
jQuery('#member-history-memberships').css({'height': '150px', 'overflow': 'auto' });
|
574 |
+
<?php } ?>
|
575 |
+
}
|
576 |
+
});
|
577 |
+
});
|
578 |
+
</script>
|
579 |
+
<?php
|
580 |
+
}
|
581 |
+
}
|
582 |
+
add_action('edit_user_profile', 'pmpro_membership_history_profile_fields');
|
583 |
+
add_action('show_user_profile', 'pmpro_membership_history_profile_fields');
|
584 |
+
|
585 |
+
|
586 |
+
/**
|
587 |
+
* Allow orders to be emailed from the member history section on user profile.
|
588 |
+
*
|
589 |
+
*/
|
590 |
+
function pmpro_membership_history_email_modal() {
|
591 |
+
$screen = get_current_screen();
|
592 |
+
if ( $screen->base == 'user-edit' || $screen->base == 'profile' ) {
|
593 |
+
// Require the core Paid Memberships Pro Admin Functions.
|
594 |
+
if ( defined( 'PMPRO_DIR' ) ) {
|
595 |
+
require_once( PMPRO_DIR . '/adminpages/functions.php' );
|
596 |
+
}
|
597 |
+
|
598 |
+
// Load the email order modal.
|
599 |
+
if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
600 |
+
pmpro_add_email_order_modal();
|
601 |
+
}
|
602 |
+
}
|
603 |
+
}
|
604 |
+
add_action( 'in_admin_header', 'pmpro_membership_history_email_modal' );
|
605 |
+
|
606 |
+
|
607 |
+
|
608 |
/**
|
609 |
* Sanitizes the passed value.
|
610 |
*
|
653 |
return;
|
654 |
}
|
655 |
|
|
|
|
|
656 |
// Saving profile updates.
|
657 |
if ( isset( $_POST['action'] ) && $_POST['action'] == 'update-profile' && $current_user->ID == $_POST['user_id'] && wp_verify_nonce( $_POST['update_user_nonce'], 'update-user_' . $current_user->ID ) ) {
|
658 |
$update = true;
|
659 |
$user = new stdClass;
|
660 |
$user->ID = $_POST[ 'user_id' ];
|
661 |
+
do_action( 'pmpro_personal_options_update', $user->ID );
|
662 |
} else {
|
663 |
$update = false;
|
664 |
}
|
includes/recaptcha.php
CHANGED
@@ -5,14 +5,15 @@
|
|
5 |
*/
|
6 |
function pmpro_init_recaptcha() {
|
7 |
//don't load if setting is off
|
8 |
-
global $recaptcha, $recaptcha_validated;
|
9 |
$recaptcha = pmpro_getOption( 'recaptcha' );
|
10 |
if ( empty( $recaptcha ) ) {
|
11 |
return;
|
12 |
}
|
13 |
|
14 |
-
//don't load unless we're on the checkout page
|
15 |
-
|
|
|
16 |
return;
|
17 |
}
|
18 |
|
@@ -28,91 +29,143 @@ function pmpro_init_recaptcha() {
|
|
28 |
|
29 |
require_once(PMPRO_DIR . '/includes/lib/recaptchalib.php' );
|
30 |
|
31 |
-
|
|
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
}
|
82 |
-
}
|
83 |
});
|
84 |
-
}
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
|
94 |
-
//
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
jQuery(this).click(function(event) {
|
99 |
event.preventDefault();
|
100 |
-
|
101 |
-
|
102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
});
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
<script type="text/javascript"
|
112 |
-
src="https://www.google.com/recaptcha/api.js?hl=<?php echo $lang;?>">
|
113 |
-
</script>
|
114 |
-
<?php }
|
115 |
-
}
|
116 |
|
117 |
//for templates using the old recaptcha_get_html
|
118 |
if( ! function_exists( 'recaptcha_get_html' ) ) {
|
@@ -125,7 +178,7 @@ function pmpro_init_recaptcha() {
|
|
125 |
$recaptcha_privatekey = pmpro_getOption( 'recaptcha_privatekey' );
|
126 |
}
|
127 |
}
|
128 |
-
add_action( 'wp', 'pmpro_init_recaptcha',
|
129 |
|
130 |
/**
|
131 |
* AJAX Method to Validate a ReCAPTCHA Response Token
|
@@ -137,7 +190,6 @@ function pmpro_wp_ajax_validate_recaptcha() {
|
|
137 |
|
138 |
$reCaptcha = new pmpro_ReCaptcha( $recaptcha_privatekey );
|
139 |
$resp = $reCaptcha->verifyResponse( $_SERVER['REMOTE_ADDR'], $_REQUEST['g-recaptcha-response'] );
|
140 |
-
|
141 |
if ( $resp->success ) {
|
142 |
pmpro_set_session_var( 'pmpro_recaptcha_validated', true );
|
143 |
echo "1";
|
@@ -153,4 +205,5 @@ add_action( 'wp_ajax_pmpro_validate_recaptcha', 'pmpro_wp_ajax_validate_recaptch
|
|
153 |
function pmpro_after_checkout_reset_recaptcha() {
|
154 |
pmpro_unset_session_var( 'pmpro_recaptcha_validated' );
|
155 |
}
|
156 |
-
add_action( 'pmpro_after_checkout', 'pmpro_after_checkout_reset_recaptcha' );
|
|
5 |
*/
|
6 |
function pmpro_init_recaptcha() {
|
7 |
//don't load if setting is off
|
8 |
+
global $recaptcha, $recaptcha_validated, $pmpro_pages;
|
9 |
$recaptcha = pmpro_getOption( 'recaptcha' );
|
10 |
if ( empty( $recaptcha ) ) {
|
11 |
return;
|
12 |
}
|
13 |
|
14 |
+
//don't load unless we're on the checkout or billing page
|
15 |
+
$is_billing = ! empty( $pmpro_pages['billing'] ) && is_page( $pmpro_pages['billing'] );
|
16 |
+
if ( ! pmpro_is_checkout() && ! $is_billing ) {
|
17 |
return;
|
18 |
}
|
19 |
|
29 |
|
30 |
require_once(PMPRO_DIR . '/includes/lib/recaptchalib.php' );
|
31 |
|
32 |
+
if ( ! function_exists( 'pmpro_recaptcha_get_html' ) ) {
|
33 |
+
function pmpro_recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) {
|
34 |
|
35 |
+
// Figure out language.
|
36 |
+
$locale = get_locale();
|
37 |
+
if(!empty($locale)) {
|
38 |
+
$parts = explode("_", $locale);
|
39 |
+
$lang = $parts[0];
|
40 |
+
} else {
|
41 |
+
$lang = "en";
|
42 |
+
}
|
43 |
+
$lang = apply_filters( 'pmpro_recaptcha_lang', $lang );
|
44 |
+
|
45 |
+
// Check which version of ReCAPTCHA we are using.
|
46 |
+
$recaptcha_version = pmpro_getOption( 'recaptcha_version' );
|
47 |
+
|
48 |
+
if( $recaptcha_version == '3_invisible' ) { ?>
|
49 |
+
<div class="g-recaptcha" data-sitekey="<?php echo $pubkey;?>" data-size="invisible" data-callback="onSubmit"></div>
|
50 |
+
<script type="text/javascript">
|
51 |
+
var pmpro_recaptcha_validated = false;
|
52 |
+
var pmpro_recaptcha_onSubmit = function(token) {
|
53 |
+
if ( pmpro_recaptcha_validated ) {
|
54 |
+
jQuery('#pmpro_form').submit();
|
55 |
+
return;
|
56 |
+
} else {
|
57 |
+
jQuery.ajax({
|
58 |
+
url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
|
59 |
+
type: 'GET',
|
60 |
+
timeout: 30000,
|
61 |
+
dataType: 'html',
|
62 |
+
data: {
|
63 |
+
'action': 'pmpro_validate_recaptcha',
|
64 |
+
'g-recaptcha-response': token,
|
65 |
+
},
|
66 |
+
error: function(xml){
|
67 |
+
alert('Error validating ReCAPTCHA.');
|
68 |
+
},
|
69 |
+
success: function(response){
|
70 |
+
if ( response == '1' ) {
|
71 |
+
pmpro_recaptcha_validated = true;
|
72 |
+
|
73 |
+
//get a new token to be submitted with the form
|
74 |
+
grecaptcha.execute();
|
75 |
+
} else {
|
76 |
+
pmpro_recaptcha_validated = false;
|
77 |
+
|
78 |
+
//warn user validation failed
|
79 |
+
alert( 'ReCAPTCHA validation failed. Try again.' );
|
80 |
+
|
81 |
+
//get a new token to be submitted with the form
|
82 |
+
grecaptcha.execute();
|
83 |
+
}
|
84 |
+
}
|
85 |
+
});
|
86 |
+
}
|
87 |
+
};
|
88 |
+
|
89 |
+
var pmpro_recaptcha_onloadCallback = function() {
|
90 |
+
// Render on main submit button.
|
91 |
+
grecaptcha.render('pmpro_btn-submit', {
|
92 |
+
'sitekey' : '<?php echo $pubkey;?>',
|
93 |
+
'callback' : pmpro_recaptcha_onSubmit
|
94 |
+
});
|
95 |
+
|
96 |
+
// Update other submit buttons.
|
97 |
+
var submit_buttons = jQuery('.pmpro_btn-submit-checkout');
|
98 |
+
submit_buttons.each(function() {
|
99 |
+
if(jQuery(this).attr('id') != 'pmpro_btn-submit') {
|
100 |
+
jQuery(this).click(function(event) {
|
101 |
+
event.preventDefault();
|
102 |
+
grecaptcha.execute();
|
103 |
+
});
|
104 |
}
|
|
|
105 |
});
|
106 |
+
};
|
107 |
+
</script>
|
108 |
+
<script type="text/javascript"
|
109 |
+
src="https://www.google.com/recaptcha/api.js?onload=pmpro_recaptcha_onloadCallback&hl=<?php echo $lang;?>&render=explicit" async defer>
|
110 |
+
</script>
|
111 |
+
<?php } else { ?>
|
112 |
+
<div class="g-recaptcha" data-callback="pmpro_recaptcha_validatedCallback" data-expired-callback="pmpro_recaptcha_expiredCallback" data-sitekey="<?php echo $pubkey;?>"></div>
|
113 |
+
<script type="text/javascript">
|
114 |
+
var pmpro_recaptcha_validated = false;
|
115 |
+
var pmpro_recaptcha_error_msg = "<?php esc_attr_e( 'Please check the ReCAPTCHA box to confirm you are not a bot.', 'paid-memberships-pro' ); ?>";
|
116 |
+
|
117 |
+
// Validation callback.
|
118 |
+
function pmpro_recaptcha_validatedCallback() {
|
119 |
+
// ReCAPTCHA worked.
|
120 |
+
pmpro_recaptcha_validated = true;
|
121 |
+
|
122 |
+
// Re-enable the submit button.
|
123 |
+
jQuery('.pmpro_btn-submit-checkout,.pmpro_btn-submit').removeAttr('disabled');
|
124 |
|
125 |
+
// Hide processing message.
|
126 |
+
jQuery('#pmpro_processing_message').css('visibility', 'hidden');
|
127 |
+
|
128 |
+
// Hide error message.
|
129 |
+
if ( jQuery('#pmpro_message').text() == pmpro_recaptcha_error_msg ) {
|
130 |
+
jQuery( '#pmpro_message' ).hide();
|
131 |
+
jQuery( '#pmpro_message_bottom' ).hide();
|
132 |
+
}
|
133 |
+
};
|
134 |
+
|
135 |
+
// Expiration callback.
|
136 |
+
function pmpro_recaptcha_expiredCallback() {
|
137 |
+
pmpro_recaptcha_validated = false;
|
138 |
+
}
|
139 |
|
140 |
+
// Check validation on submit.
|
141 |
+
jQuery(document).ready(function(){
|
142 |
+
jQuery('#pmpro_form').submit(function(event){
|
143 |
+
if( pmpro_recaptcha_validated == false ) {
|
|
|
144 |
event.preventDefault();
|
145 |
+
|
146 |
+
// Re-enable the submit button.
|
147 |
+
jQuery('.pmpro_btn-submit-checkout,.pmpro_btn-submit').removeAttr('disabled');
|
148 |
+
|
149 |
+
// Hide processing message.
|
150 |
+
jQuery('#pmpro_processing_message').css('visibility', 'hidden');
|
151 |
+
|
152 |
+
// error message
|
153 |
+
jQuery( '#pmpro_message' ).text( pmpro_recaptcha_error_msg ).addClass( 'pmpro_error' ).removeClass( 'pmpro_alert' ).removeClass( 'pmpro_success' ).hide().fadeIn();
|
154 |
+
jQuery( '#pmpro_message_bottom' ).hide().fadeIn();
|
155 |
+
|
156 |
+
return false;
|
157 |
+
} else {
|
158 |
+
return true;
|
159 |
+
}
|
160 |
+
});
|
161 |
});
|
162 |
+
</script>
|
163 |
+
<script type="text/javascript"
|
164 |
+
src="https://www.google.com/recaptcha/api.js?hl=<?php echo $lang;?>">
|
165 |
+
</script>
|
166 |
+
<?php }
|
167 |
+
}
|
168 |
+
}
|
|
|
|
|
|
|
|
|
|
|
169 |
|
170 |
//for templates using the old recaptcha_get_html
|
171 |
if( ! function_exists( 'recaptcha_get_html' ) ) {
|
178 |
$recaptcha_privatekey = pmpro_getOption( 'recaptcha_privatekey' );
|
179 |
}
|
180 |
}
|
181 |
+
add_action( 'wp', 'pmpro_init_recaptcha', 1 );
|
182 |
|
183 |
/**
|
184 |
* AJAX Method to Validate a ReCAPTCHA Response Token
|
190 |
|
191 |
$reCaptcha = new pmpro_ReCaptcha( $recaptcha_privatekey );
|
192 |
$resp = $reCaptcha->verifyResponse( $_SERVER['REMOTE_ADDR'], $_REQUEST['g-recaptcha-response'] );
|
|
|
193 |
if ( $resp->success ) {
|
194 |
pmpro_set_session_var( 'pmpro_recaptcha_validated', true );
|
195 |
echo "1";
|
205 |
function pmpro_after_checkout_reset_recaptcha() {
|
206 |
pmpro_unset_session_var( 'pmpro_recaptcha_validated' );
|
207 |
}
|
208 |
+
add_action( 'pmpro_after_checkout', 'pmpro_after_checkout_reset_recaptcha' );
|
209 |
+
add_action( 'pmpro_after_update_billing', 'pmpro_after_checkout_reset_recaptcha' );
|
includes/rest-api.php
CHANGED
@@ -173,6 +173,50 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
173 |
'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
|
174 |
),
|
175 |
));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
}
|
177 |
|
178 |
/**
|
@@ -183,16 +227,16 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
183 |
function pmpro_rest_api_get_membership_level_for_user($request) {
|
184 |
$params = $request->get_params();
|
185 |
|
186 |
-
$user_id = isset( $params['user_id'] ) ? $params['user_id'] : null;
|
187 |
|
188 |
// Param id was used instead (old style endpoint).
|
189 |
if ( empty( $user_id ) && !empty( $params['id'] ) ) {
|
190 |
-
$user_id = $params['id'];
|
191 |
}
|
192 |
|
193 |
// Query by email.
|
194 |
if ( empty( $user_id ) && !empty( $params['email'] ) ) {
|
195 |
-
$user = get_user_by_email( $params['email'] );
|
196 |
$user_id = $user->ID;
|
197 |
}
|
198 |
|
@@ -213,16 +257,16 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
213 |
function pmpro_rest_api_get_membership_levels_for_user($request) {
|
214 |
$params = $request->get_params();
|
215 |
|
216 |
-
$user_id = isset( $params['user_id'] ) ? $params['user_id'] : null;
|
217 |
|
218 |
// Param id was used instead.
|
219 |
if ( empty( $user_id ) && !empty( $params['id'] ) ) {
|
220 |
-
$user_id = $params['id'];
|
221 |
}
|
222 |
|
223 |
// Param email was used instead.
|
224 |
if ( empty( $user_id ) && !empty( $params['email'] ) ) {
|
225 |
-
$user = get_user_by_email( $params['email'] );
|
226 |
$user_id = $user->ID;
|
227 |
}
|
228 |
|
@@ -243,13 +287,13 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
243 |
*/
|
244 |
function pmpro_rest_api_get_has_membership_access($request) {
|
245 |
$params = $request->get_params();
|
246 |
-
$post_id = isset( $params['post_id'] ) ? $params['post_id'] : null;
|
247 |
-
$user_id = isset( $params['user_id'] ) ? $params['user_id'] : null;
|
248 |
|
249 |
if ( empty( $user_id ) ) {
|
250 |
// see if they sent an email
|
251 |
if ( ! empty( $params['email'] ) ) {
|
252 |
-
$user = get_user_by_email( $params['email'] );
|
253 |
$user_id = $user->ID;
|
254 |
} else {
|
255 |
return new WP_REST_Response( 'No user information passed through.', 404 );
|
@@ -274,29 +318,43 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
274 |
*/
|
275 |
function pmpro_rest_api_change_membership_level( $request ) {
|
276 |
$params = $request->get_params();
|
277 |
-
$user_id = isset( $params['user_id'] ) ? $params['user_id'] : null;
|
278 |
-
$level_id = isset( $params['level_id'] ) ? $params['level_id'] : null;
|
|
|
|
|
279 |
|
280 |
if ( empty( $user_id ) ) {
|
281 |
// see if they sent an email
|
282 |
-
if ( ! empty( $
|
283 |
-
$user = get_user_by_email( $
|
284 |
$user_id = $user->ID;
|
285 |
} else {
|
|
|
|
|
|
|
|
|
286 |
return new WP_REST_Response( 'No user information passed through.', 404 );
|
287 |
}
|
288 |
}
|
289 |
|
290 |
if ( ! function_exists( 'pmpro_changeMembershipLevel' ) ) {
|
|
|
|
|
|
|
|
|
291 |
return new WP_REST_Response( 'Paid Memberships Pro function not found.', 404 );
|
292 |
}
|
293 |
-
|
294 |
if ( ! empty( $user_id ) ) {
|
295 |
$response = pmpro_changeMembershipLevel( $level_id, $user_id );
|
296 |
} else {
|
297 |
$response = false;
|
298 |
}
|
299 |
|
|
|
|
|
|
|
|
|
300 |
return new WP_REST_Response( $response, 200 );
|
301 |
}
|
302 |
|
@@ -307,24 +365,38 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
307 |
*/
|
308 |
function pmpro_rest_api_cancel_membership_level( $request ) {
|
309 |
$params = $request->get_params();
|
310 |
-
$user_id = isset( $params['user_id'] ) ? $params['user_id'] : null;
|
311 |
-
$level_id = isset( $params['level_id'] ) ? $params['level_id'] : null;
|
|
|
|
|
312 |
|
313 |
if ( empty( $user_id ) ) {
|
314 |
// see if they sent an email
|
315 |
-
if ( ! empty( $
|
316 |
-
$user = get_user_by_email( $
|
317 |
$user_id = $user->ID;
|
318 |
} else {
|
|
|
|
|
|
|
|
|
319 |
return new WP_REST_Response( 'No user information passed through.', 404 );
|
320 |
}
|
321 |
}
|
322 |
|
323 |
if ( empty( $level_id ) ) {
|
|
|
|
|
|
|
|
|
324 |
return new WP_REST_Response( 'No membership level ID data.', 400 );
|
325 |
}
|
326 |
|
327 |
if ( ! function_exists( 'pmpro_cancelMembershipLevel' ) ) {
|
|
|
|
|
|
|
|
|
328 |
return new WP_REST_Response( 'Paid Memberships Pro function not found.', 404 );
|
329 |
}
|
330 |
|
@@ -333,7 +405,11 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
333 |
} else {
|
334 |
$response = false;
|
335 |
}
|
336 |
-
|
|
|
|
|
|
|
|
|
337 |
return new WP_REST_Response( $response, 200 );
|
338 |
}
|
339 |
|
@@ -350,6 +426,7 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
350 |
|
351 |
$params = $request->get_params();
|
352 |
$id = isset( $params['id'] ) ? intval( $params['id'] ) : null;
|
|
|
353 |
|
354 |
if ( empty( $id ) ) {
|
355 |
return new WP_REST_Response( 'ID not passed through', 400 );
|
@@ -364,6 +441,10 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
364 |
$level->confirmation = '';
|
365 |
}
|
366 |
|
|
|
|
|
|
|
|
|
367 |
return new WP_REST_Response( $level, 200 );
|
368 |
}
|
369 |
|
@@ -382,6 +463,7 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
382 |
$method = $request->get_method();
|
383 |
|
384 |
$id = isset( $params['id'] ) ? intval( $params['id'] ) : '';
|
|
|
385 |
|
386 |
// Pass through an ID only for PUT/PATCH methods. POST treats it as a brand new level.
|
387 |
if ( ! empty( $id ) && ( $method === 'PUT' || $method === 'PATCH' ) ) {
|
@@ -422,6 +504,10 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
422 |
$level->categories = $categories;
|
423 |
$level->save();
|
424 |
|
|
|
|
|
|
|
|
|
425 |
return new WP_REST_Response( $level, 200 );
|
426 |
|
427 |
}
|
@@ -460,7 +546,7 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
460 |
}
|
461 |
|
462 |
$params = $request->get_params();
|
463 |
-
$code = isset( $params['code'] ) ? $params['code'] : null;
|
464 |
|
465 |
if ( empty( $code ) ) {
|
466 |
return new WP_REST_Response( 'No discount code sent.', 400 );
|
@@ -487,7 +573,7 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
487 |
$uses = isset( $params['uses'] ) ? intval( $params['uses'] ) : '';
|
488 |
$starts = isset( $params['starts'] ) ? sanitize_text_field( $params['starts'] ) : '';
|
489 |
$expires = isset( $params['expires'] ) ? sanitize_text_field( $params['expires'] ) : '';
|
490 |
-
$levels = isset( $params['levels'] ) ? $params['levels'] : null;
|
491 |
|
492 |
if ( ! empty( $levels ) ) {
|
493 |
$levels = json_decode( $levels, true );
|
@@ -529,7 +615,7 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
529 |
|
530 |
$discount_code->code = $code;
|
531 |
$discount_code->starts = $starts;
|
532 |
-
$discount_code->
|
533 |
$discount_code->uses = $uses;
|
534 |
$discount_code->levels = !empty( $levels_array ) ? $levels_array : $levels;
|
535 |
$discount_code->save();
|
@@ -546,12 +632,17 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
546 |
function pmpro_rest_api_get_checkout_level( $request ) {
|
547 |
$params = $request->get_params();
|
548 |
|
549 |
-
|
|
|
|
|
|
|
|
|
|
|
550 |
if ( empty( $level_id ) ) {
|
551 |
return new WP_REST_Response( 'No level found.', 400 );
|
552 |
}
|
553 |
|
554 |
-
$discount_code = isset( $params['discount_code'] ) ? $params['discount_code'] : null;
|
555 |
$checkout_level = pmpro_getLevelAtCheckout( $level_id, $discount_code );
|
556 |
|
557 |
// Hide confirmation message if not an admin or member.
|
@@ -575,27 +666,183 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
575 |
if ( ! empty( $pmpro_checkout_level_ids ) ) {
|
576 |
// MMPU Compatibility...
|
577 |
$level_ids = $pmpro_checkout_level_ids;
|
578 |
-
} elseif ( isset( $
|
579 |
-
$level_ids = explode( '+', $
|
|
|
|
|
580 |
}
|
581 |
|
582 |
if ( empty( $level_ids ) ) {
|
583 |
return new WP_REST_Response( 'No levels found.', 400 );
|
584 |
}
|
585 |
-
$discount_code = isset( $params['discount_code'] ) ? $params['discount_code'] : null;
|
586 |
|
587 |
$r = array();
|
588 |
$r['initial_payment'] = 0.00;
|
589 |
foreach ( $level_ids as $level_id ) {
|
590 |
$r[ $level_id ] = pmpro_getLevelAtCheckout( $level_id, $discount_code );
|
591 |
if ( ! empty( $r[ $level_id ]->initial_payment ) ) {
|
592 |
-
$r['initial_payment'] +=
|
593 |
}
|
594 |
}
|
595 |
$r['initial_payment_formatted'] = pmpro_formatPrice( $r['initial_payment'] );
|
596 |
return new WP_REST_Response( $r );
|
597 |
}
|
598 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
599 |
/**
|
600 |
* Default permissions check for endpoints/routes.
|
601 |
* Defaults to 'subscriber' for all GET requests and
|
@@ -621,18 +868,21 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
621 |
'/pmpro/v1/membership_level' => true,
|
622 |
'/pmpro/v1/discount_code' => 'pmpro_discountcodes',
|
623 |
'/pmpro/v1/checkout_level' => true,
|
624 |
-
'/pmpro/v1/checkout_levels' => true,
|
|
|
|
|
|
|
625 |
);
|
626 |
$route_caps = apply_filters( 'pmpro_rest_api_route_capabilities', $route_caps, $request );
|
627 |
-
|
628 |
if ( isset( $route_caps[$route] ) ) {
|
629 |
if ( $route_caps[$route] === true ) {
|
630 |
// public
|
631 |
$permission = true;
|
632 |
-
} else {
|
633 |
-
$permission = current_user_can( $route_caps[$route] );
|
634 |
}
|
635 |
-
}
|
636 |
|
637 |
// Is the request method allowed? We disable DELETE by default.
|
638 |
if ( ! in_array( $method, pmpro_get_rest_api_methods( $route ) ) ) {
|
@@ -640,7 +890,6 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
640 |
}
|
641 |
|
642 |
$permission = apply_filters( 'pmpro_rest_api_permissions', $permission, $request );
|
643 |
-
|
644 |
return $permission;
|
645 |
}
|
646 |
|
@@ -651,8 +900,6 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
651 |
function pmpro_rest_api_convert_to_array( $string ) {
|
652 |
return explode( ',', $string );
|
653 |
}
|
654 |
-
|
655 |
-
|
656 |
} // End of class
|
657 |
|
658 |
/**
|
@@ -667,6 +914,7 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
667 |
add_action( 'rest_api_init', 'pmpro_rest_api_register_custom_routes', 5 );
|
668 |
}
|
669 |
|
|
|
670 |
/**
|
671 |
* Get the allowed methods for PMPro REST API endpoints.
|
672 |
* To enable DELETE, hook into this filter.
|
@@ -676,4 +924,4 @@ function pmpro_get_rest_api_methods( $route = NULL ) {
|
|
676 |
$methods = array( 'GET', 'POST', 'PUT', 'PATCH' );
|
677 |
$methods = apply_filters( 'pmpro_rest_api_methods', $methods, $route );
|
678 |
return $methods;
|
679 |
-
}
|
173 |
'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
|
174 |
),
|
175 |
));
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Authentication route for Zapier integration.
|
179 |
+
*
|
180 |
+
* Used to do authentication when connecting Zapier to PMPro.
|
181 |
+
*
|
182 |
+
* @since 2.6.0
|
183 |
+
*/
|
184 |
+
register_rest_route( $pmpro_namespace, '/me',
|
185 |
+
array(
|
186 |
+
array(
|
187 |
+
'methods' => WP_REST_Server::READABLE,
|
188 |
+
'callback' => array( $this, 'validate_me' ),
|
189 |
+
'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
|
190 |
+
),
|
191 |
+
)
|
192 |
+
);
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Get the last couple of membership levels/members.
|
196 |
+
*
|
197 |
+
* @since 2.6.0
|
198 |
+
*/
|
199 |
+
register_rest_route( $pmpro_namespace, '/recent_memberships',
|
200 |
+
array(
|
201 |
+
array(
|
202 |
+
'methods' => WP_REST_Server::READABLE,
|
203 |
+
'callback' => array( $this, 'pmpro_rest_api_recent_memberships' ),
|
204 |
+
'args' => array(
|
205 |
+
'status' => array(),
|
206 |
+
),
|
207 |
+
'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
|
208 |
+
)
|
209 |
+
));
|
210 |
+
|
211 |
+
register_rest_route( $pmpro_namespace, '/recent_orders',
|
212 |
+
array(
|
213 |
+
array(
|
214 |
+
'methods' => WP_REST_Server::READABLE,
|
215 |
+
'callback' => array( $this, 'pmpro_rest_api_recent_orders' ),
|
216 |
+
'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
|
217 |
+
)
|
218 |
+
)
|
219 |
+
);
|
220 |
}
|
221 |
|
222 |
/**
|
227 |
function pmpro_rest_api_get_membership_level_for_user($request) {
|
228 |
$params = $request->get_params();
|
229 |
|
230 |
+
$user_id = isset( $params['user_id'] ) ? intval( $params['user_id'] ) : null;
|
231 |
|
232 |
// Param id was used instead (old style endpoint).
|
233 |
if ( empty( $user_id ) && !empty( $params['id'] ) ) {
|
234 |
+
$user_id = intval( $params['id'] );
|
235 |
}
|
236 |
|
237 |
// Query by email.
|
238 |
if ( empty( $user_id ) && !empty( $params['email'] ) ) {
|
239 |
+
$user = get_user_by_email( sanitize_email( $params['email'] ) );
|
240 |
$user_id = $user->ID;
|
241 |
}
|
242 |
|
257 |
function pmpro_rest_api_get_membership_levels_for_user($request) {
|
258 |
$params = $request->get_params();
|
259 |
|
260 |
+
$user_id = isset( $params['user_id'] ) ? intval( $params['user_id'] ) : null;
|
261 |
|
262 |
// Param id was used instead.
|
263 |
if ( empty( $user_id ) && !empty( $params['id'] ) ) {
|
264 |
+
$user_id = intval( $params['id'] );
|
265 |
}
|
266 |
|
267 |
// Param email was used instead.
|
268 |
if ( empty( $user_id ) && !empty( $params['email'] ) ) {
|
269 |
+
$user = get_user_by_email( sanitize_email( $params['email'] ) );
|
270 |
$user_id = $user->ID;
|
271 |
}
|
272 |
|
287 |
*/
|
288 |
function pmpro_rest_api_get_has_membership_access($request) {
|
289 |
$params = $request->get_params();
|
290 |
+
$post_id = isset( $params['post_id'] ) ? intval( $params['post_id'] ) : null;
|
291 |
+
$user_id = isset( $params['user_id'] ) ? intval( $params['user_id'] ) : null;
|
292 |
|
293 |
if ( empty( $user_id ) ) {
|
294 |
// see if they sent an email
|
295 |
if ( ! empty( $params['email'] ) ) {
|
296 |
+
$user = get_user_by_email( sanitize_email( $params['email'] ) );
|
297 |
$user_id = $user->ID;
|
298 |
} else {
|
299 |
return new WP_REST_Response( 'No user information passed through.', 404 );
|
318 |
*/
|
319 |
function pmpro_rest_api_change_membership_level( $request ) {
|
320 |
$params = $request->get_params();
|
321 |
+
$user_id = isset( $params['user_id'] ) ? intval( $params['user_id'] ) : null;
|
322 |
+
$level_id = isset( $params['level_id'] ) ? intval( $params['level_id'] ) : null;
|
323 |
+
$email = isset( $params['email'] ) ? sanitize_email( $params['email'] ) : null;
|
324 |
+
$response_type = isset( $params['response_type'] ) ? sanitize_text_field( $params['response_type'] ) : null;
|
325 |
|
326 |
if ( empty( $user_id ) ) {
|
327 |
// see if they sent an email
|
328 |
+
if ( ! empty( $email ) ) {
|
329 |
+
$user = get_user_by_email( $email );
|
330 |
$user_id = $user->ID;
|
331 |
} else {
|
332 |
+
if ( 'json' === $response_type ) {
|
333 |
+
wp_send_json_error( array( 'email' => $email, 'error' => 'No user information passed through.' ) );
|
334 |
+
}
|
335 |
+
|
336 |
return new WP_REST_Response( 'No user information passed through.', 404 );
|
337 |
}
|
338 |
}
|
339 |
|
340 |
if ( ! function_exists( 'pmpro_changeMembershipLevel' ) ) {
|
341 |
+
if ( 'json' === $response_type ) {
|
342 |
+
wp_send_json_error( array( 'email' => $email, 'error' => 'Paid Memberships Pro function not found.' ) );
|
343 |
+
}
|
344 |
+
|
345 |
return new WP_REST_Response( 'Paid Memberships Pro function not found.', 404 );
|
346 |
}
|
347 |
+
|
348 |
if ( ! empty( $user_id ) ) {
|
349 |
$response = pmpro_changeMembershipLevel( $level_id, $user_id );
|
350 |
} else {
|
351 |
$response = false;
|
352 |
}
|
353 |
|
354 |
+
if ( 'json' === $response_type ) {
|
355 |
+
wp_send_json_success( array( 'user_id' => $user_id, 'level_changed' => $level_id, 'response' => $response, 'status' => 200 ) );
|
356 |
+
}
|
357 |
+
|
358 |
return new WP_REST_Response( $response, 200 );
|
359 |
}
|
360 |
|
365 |
*/
|
366 |
function pmpro_rest_api_cancel_membership_level( $request ) {
|
367 |
$params = $request->get_params();
|
368 |
+
$user_id = isset( $params['user_id'] ) ? intval( $params['user_id'] ) : null;
|
369 |
+
$level_id = isset( $params['level_id'] ) ? intval( $params['level_id'] ) : null;
|
370 |
+
$email = isset( $params['email'] ) ? sanitize_email( $params['email'] ) : null;
|
371 |
+
$response_type = isset( $params['response_type'] ) ? sanitize_text_field( $params['response_type'] ) : null;
|
372 |
|
373 |
if ( empty( $user_id ) ) {
|
374 |
// see if they sent an email
|
375 |
+
if ( ! empty( $email ) ) {
|
376 |
+
$user = get_user_by_email( $email );
|
377 |
$user_id = $user->ID;
|
378 |
} else {
|
379 |
+
if ( 'json' === $response_type ) {
|
380 |
+
wp_send_json_error( array( 'email' => $email ) );
|
381 |
+
}
|
382 |
+
|
383 |
return new WP_REST_Response( 'No user information passed through.', 404 );
|
384 |
}
|
385 |
}
|
386 |
|
387 |
if ( empty( $level_id ) ) {
|
388 |
+
if ( 'json' === $response_type ) {
|
389 |
+
wp_send_json_error( array( 'email' => $email ) );
|
390 |
+
}
|
391 |
+
|
392 |
return new WP_REST_Response( 'No membership level ID data.', 400 );
|
393 |
}
|
394 |
|
395 |
if ( ! function_exists( 'pmpro_cancelMembershipLevel' ) ) {
|
396 |
+
if ( 'json' === $response_type ) {
|
397 |
+
wp_send_json_error( array( 'email' => $email ) );
|
398 |
+
}
|
399 |
+
|
400 |
return new WP_REST_Response( 'Paid Memberships Pro function not found.', 404 );
|
401 |
}
|
402 |
|
405 |
} else {
|
406 |
$response = false;
|
407 |
}
|
408 |
+
|
409 |
+
if ( 'json' === $response_type ) {
|
410 |
+
wp_send_json_success( array( 'email' => $email ) );
|
411 |
+
}
|
412 |
+
|
413 |
return new WP_REST_Response( $response, 200 );
|
414 |
}
|
415 |
|
426 |
|
427 |
$params = $request->get_params();
|
428 |
$id = isset( $params['id'] ) ? intval( $params['id'] ) : null;
|
429 |
+
$response_type = isset( $params['response_type'] ) ? sanitize_text_field( $params['response_type'] ) : false;
|
430 |
|
431 |
if ( empty( $id ) ) {
|
432 |
return new WP_REST_Response( 'ID not passed through', 400 );
|
441 |
$level->confirmation = '';
|
442 |
}
|
443 |
|
444 |
+
if ( 'json' === $response_type ) {
|
445 |
+
wp_send_json_success( array( 'level' => $level ) );
|
446 |
+
}
|
447 |
+
|
448 |
return new WP_REST_Response( $level, 200 );
|
449 |
}
|
450 |
|
463 |
$method = $request->get_method();
|
464 |
|
465 |
$id = isset( $params['id'] ) ? intval( $params['id'] ) : '';
|
466 |
+
$response_type = isset( $params['response_type'] ) ? sanitize_text_field( $params['response_type'] ) : null;
|
467 |
|
468 |
// Pass through an ID only for PUT/PATCH methods. POST treats it as a brand new level.
|
469 |
if ( ! empty( $id ) && ( $method === 'PUT' || $method === 'PATCH' ) ) {
|
504 |
$level->categories = $categories;
|
505 |
$level->save();
|
506 |
|
507 |
+
if ( 'json' === $response_type ) {
|
508 |
+
wp_send_json_success( array( "level" => $level ) );
|
509 |
+
}
|
510 |
+
|
511 |
return new WP_REST_Response( $level, 200 );
|
512 |
|
513 |
}
|
546 |
}
|
547 |
|
548 |
$params = $request->get_params();
|
549 |
+
$code = isset( $params['code'] ) ? sanitize_text_field( $params['code'] ) : null;
|
550 |
|
551 |
if ( empty( $code ) ) {
|
552 |
return new WP_REST_Response( 'No discount code sent.', 400 );
|
573 |
$uses = isset( $params['uses'] ) ? intval( $params['uses'] ) : '';
|
574 |
$starts = isset( $params['starts'] ) ? sanitize_text_field( $params['starts'] ) : '';
|
575 |
$expires = isset( $params['expires'] ) ? sanitize_text_field( $params['expires'] ) : '';
|
576 |
+
$levels = isset( $params['levels'] ) ? sanitize_text_field( $params['levels'] ) : null;
|
577 |
|
578 |
if ( ! empty( $levels ) ) {
|
579 |
$levels = json_decode( $levels, true );
|
615 |
|
616 |
$discount_code->code = $code;
|
617 |
$discount_code->starts = $starts;
|
618 |
+
$discount_code->expires = $expires;
|
619 |
$discount_code->uses = $uses;
|
620 |
$discount_code->levels = !empty( $levels_array ) ? $levels_array : $levels;
|
621 |
$discount_code->save();
|
632 |
function pmpro_rest_api_get_checkout_level( $request ) {
|
633 |
$params = $request->get_params();
|
634 |
|
635 |
+
if ( isset( $params['level_id'] ) ) {
|
636 |
+
$level_id = intval( $params['level_id'] );
|
637 |
+
} elseif ( isset( $params['level'] ) ) {
|
638 |
+
$level_id = intval( $params['level'] );
|
639 |
+
}
|
640 |
+
|
641 |
if ( empty( $level_id ) ) {
|
642 |
return new WP_REST_Response( 'No level found.', 400 );
|
643 |
}
|
644 |
|
645 |
+
$discount_code = isset( $params['discount_code'] ) ? sanitize_text_field( $params['discount_code'] ) : null;
|
646 |
$checkout_level = pmpro_getLevelAtCheckout( $level_id, $discount_code );
|
647 |
|
648 |
// Hide confirmation message if not an admin or member.
|
666 |
if ( ! empty( $pmpro_checkout_level_ids ) ) {
|
667 |
// MMPU Compatibility...
|
668 |
$level_ids = $pmpro_checkout_level_ids;
|
669 |
+
} elseif ( isset( $params['level_id'] ) ) {
|
670 |
+
$level_ids = explode( '+', intval( $params['level_id'] ) );
|
671 |
+
} elseif ( isset( $params['level'] ) ) {
|
672 |
+
$level_ids = explode( '+', intval( $params['level'] ) );
|
673 |
}
|
674 |
|
675 |
if ( empty( $level_ids ) ) {
|
676 |
return new WP_REST_Response( 'No levels found.', 400 );
|
677 |
}
|
678 |
+
$discount_code = isset( $params['discount_code'] ) ? sanitize_text_field( $params['discount_code'] ) : null;
|
679 |
|
680 |
$r = array();
|
681 |
$r['initial_payment'] = 0.00;
|
682 |
foreach ( $level_ids as $level_id ) {
|
683 |
$r[ $level_id ] = pmpro_getLevelAtCheckout( $level_id, $discount_code );
|
684 |
if ( ! empty( $r[ $level_id ]->initial_payment ) ) {
|
685 |
+
$r['initial_payment'] += floatval( $r[ $level_id ]->initial_payment );
|
686 |
}
|
687 |
}
|
688 |
$r['initial_payment_formatted'] = pmpro_formatPrice( $r['initial_payment'] );
|
689 |
return new WP_REST_Response( $r );
|
690 |
}
|
691 |
|
692 |
+
|
693 |
+
/// ZAPIER TRIGGERS
|
694 |
+
/**
|
695 |
+
* Handle authentication testing for the Zapier API.
|
696 |
+
*
|
697 |
+
* @since 2.6.0
|
698 |
+
*
|
699 |
+
* @param WP_REST_Request $request The REST request.
|
700 |
+
*/
|
701 |
+
public function validate_me( $request ) {
|
702 |
+
|
703 |
+
$params = $request->get_params();
|
704 |
+
|
705 |
+
if ( is_user_logged_in() ) {
|
706 |
+
$me = wp_get_current_user()->display_name;
|
707 |
+
} else {
|
708 |
+
$me = false;
|
709 |
+
}
|
710 |
+
|
711 |
+
wp_send_json_success( array( 'username' => $me ) );
|
712 |
+
}
|
713 |
+
|
714 |
+
/**
|
715 |
+
* Handle requests for the list of recent memberships.
|
716 |
+
*
|
717 |
+
* @since 2.6.0
|
718 |
+
*
|
719 |
+
* @param WP_REST_Request $request The REST request.
|
720 |
+
*
|
721 |
+
* @return WP_REST_Response The REST response.
|
722 |
+
*/
|
723 |
+
public function pmpro_rest_api_recent_memberships( $request ) {
|
724 |
+
$params = $request->get_params();
|
725 |
+
if ( isset($params['limit']) ) {
|
726 |
+
$limit = intval( $params['limit'] );
|
727 |
+
} else {
|
728 |
+
$limit = 1;
|
729 |
+
}
|
730 |
+
/**
|
731 |
+
* Allow filtering the total number of recent members to show in the /recent_memberships PMPro endpoint.
|
732 |
+
*
|
733 |
+
* @param int $limit The total number of recent members to show.
|
734 |
+
*/
|
735 |
+
$limit = apply_filters( 'pmpro_trigger_recent_members_limit', $limit );
|
736 |
+
|
737 |
+
$response_type = isset( $params['response_type'] ) ? sanitize_text_field( $params['response_type'] ) : null;
|
738 |
+
|
739 |
+
if ( empty( $params['level_status'] ) ) {
|
740 |
+
$level_status = [ 'active' ];
|
741 |
+
} else {
|
742 |
+
$level_status = sanitize_text_field( trim( $params['level_status'] ) );
|
743 |
+
|
744 |
+
// Force it into an array so we can implode it in the query itself.
|
745 |
+
$level_status = explode( ',', $level_status );
|
746 |
+
}
|
747 |
+
|
748 |
+
// Set up values to prepare.
|
749 |
+
$prepare = $level_status;
|
750 |
+
$prepare[] = $limit;
|
751 |
+
|
752 |
+
// Set up the placeholders we want to use.
|
753 |
+
$level_status_placeholders = implode( ', ', array_fill( 0, count( $level_status ), '%s' ) );
|
754 |
+
|
755 |
+
// Grab the useful information.
|
756 |
+
global $wpdb;
|
757 |
+
|
758 |
+
$sql = "
|
759 |
+
SELECT
|
760 |
+
`mu`.`user_id` as `id`,
|
761 |
+
`u`.`user_email`,
|
762 |
+
`u`.`user_nicename`,
|
763 |
+
`mu`.`membership_id`,
|
764 |
+
`ml`.`name` as membership_name,
|
765 |
+
`mu`.`status`,
|
766 |
+
`mu`.`modified`
|
767 |
+
FROM `{$wpdb->pmpro_memberships_users}` AS `mu`
|
768 |
+
LEFT JOIN `{$wpdb->users}` AS `u`
|
769 |
+
ON `mu`.`user_id` = `u`.`id`
|
770 |
+
LEFT JOIN `{$wpdb->pmpro_membership_levels}` AS `ml`
|
771 |
+
ON `ml`.`id` = `mu`.`membership_id`
|
772 |
+
WHERE
|
773 |
+
`mu`.`status` IN ( {$level_status_placeholders} )
|
774 |
+
ORDER BY
|
775 |
+
`mu`.`modified` DESC
|
776 |
+
LIMIT %d
|
777 |
+
";
|
778 |
+
|
779 |
+
$results = $wpdb->get_results( $wpdb->prepare( $sql, $prepare ) );
|
780 |
+
|
781 |
+
// Let's format the date to ISO8601
|
782 |
+
$results[0]->modified = pmpro_format_date_iso8601( $results[0]->modified );
|
783 |
+
|
784 |
+
return new WP_REST_Response( $results, 200 );
|
785 |
+
|
786 |
+
}
|
787 |
+
|
788 |
+
/**
|
789 |
+
* Handle requests for the list of recent orders.
|
790 |
+
*
|
791 |
+
* @since 2.6.0
|
792 |
+
*
|
793 |
+
* @param WP_REST_Request $request The REST request.
|
794 |
+
*
|
795 |
+
* @return WP_REST_Response The REST response.
|
796 |
+
*/
|
797 |
+
public function pmpro_rest_api_recent_orders( $request ) {
|
798 |
+
$params = $request->get_params();
|
799 |
+
|
800 |
+
if ( isset($params['limit']) ) {
|
801 |
+
$orders_limit = intval( $params['limit'] );
|
802 |
+
} else {
|
803 |
+
$orders_limit = 1;
|
804 |
+
}
|
805 |
+
|
806 |
+
$limit = apply_filters( 'pmpro_trigger_recent_orders_limit', $orders_limit );
|
807 |
+
|
808 |
+
global $wpdb;
|
809 |
+
|
810 |
+
$sql = "
|
811 |
+
SELECT
|
812 |
+
`o`.`id`,
|
813 |
+
`o`.`code`,
|
814 |
+
`u`.`ID` AS `user_id`,
|
815 |
+
`u`.`user_email`,
|
816 |
+
`u`.`user_nicename`,
|
817 |
+
`o`.`billing_name`,
|
818 |
+
`o`.`billing_street`,
|
819 |
+
`o`.`billing_city`,
|
820 |
+
`o`.`billing_state`,
|
821 |
+
`o`.`billing_zip`,
|
822 |
+
`o`.`billing_country`,
|
823 |
+
`o`.`billing_phone`,
|
824 |
+
`o`.`subtotal`,
|
825 |
+
`o`.`tax`,
|
826 |
+
`o`.`total`,
|
827 |
+
`o`.`status`,
|
828 |
+
`o`.`gateway`,
|
829 |
+
`o`.`gateway_environment`,
|
830 |
+
`o`.`timestamp`
|
831 |
+
FROM `{$wpdb->pmpro_membership_orders}` AS `o`
|
832 |
+
LEFT JOIN `{$wpdb->users}` AS `u`
|
833 |
+
ON `o`.`user_id` = `u`.`ID`
|
834 |
+
ORDER BY
|
835 |
+
`o`.`timestamp` DESC
|
836 |
+
LIMIT %d
|
837 |
+
";
|
838 |
+
|
839 |
+
$results = $wpdb->get_results( $wpdb->prepare( $sql, $limit ) );
|
840 |
+
|
841 |
+
$results[0]->timestamp = pmpro_format_date_iso8601( $results[0]->timestamp );
|
842 |
+
|
843 |
+
return new WP_REST_Response( $results, 200 );
|
844 |
+
}
|
845 |
+
|
846 |
/**
|
847 |
* Default permissions check for endpoints/routes.
|
848 |
* Defaults to 'subscriber' for all GET requests and
|
868 |
'/pmpro/v1/membership_level' => true,
|
869 |
'/pmpro/v1/discount_code' => 'pmpro_discountcodes',
|
870 |
'/pmpro/v1/checkout_level' => true,
|
871 |
+
'/pmpro/v1/checkout_levels' => true,
|
872 |
+
'/pmpro/v1/me' => true,
|
873 |
+
'/pmpro/v1/recent_memberships' => 'pmpro_edit_memberships',
|
874 |
+
'/pmpro/v1/recent_orders' => 'pmpro_orders'
|
875 |
);
|
876 |
$route_caps = apply_filters( 'pmpro_rest_api_route_capabilities', $route_caps, $request );
|
877 |
+
|
878 |
if ( isset( $route_caps[$route] ) ) {
|
879 |
if ( $route_caps[$route] === true ) {
|
880 |
// public
|
881 |
$permission = true;
|
882 |
+
} else {
|
883 |
+
$permission = current_user_can( $route_caps[$route] );
|
884 |
}
|
885 |
+
}
|
886 |
|
887 |
// Is the request method allowed? We disable DELETE by default.
|
888 |
if ( ! in_array( $method, pmpro_get_rest_api_methods( $route ) ) ) {
|
890 |
}
|
891 |
|
892 |
$permission = apply_filters( 'pmpro_rest_api_permissions', $permission, $request );
|
|
|
893 |
return $permission;
|
894 |
}
|
895 |
|
900 |
function pmpro_rest_api_convert_to_array( $string ) {
|
901 |
return explode( ',', $string );
|
902 |
}
|
|
|
|
|
903 |
} // End of class
|
904 |
|
905 |
/**
|
914 |
add_action( 'rest_api_init', 'pmpro_rest_api_register_custom_routes', 5 );
|
915 |
}
|
916 |
|
917 |
+
|
918 |
/**
|
919 |
* Get the allowed methods for PMPro REST API endpoints.
|
920 |
* To enable DELETE, hook into this filter.
|
924 |
$methods = array( 'GET', 'POST', 'PUT', 'PATCH' );
|
925 |
$methods = apply_filters( 'pmpro_rest_api_methods', $methods, $route );
|
926 |
return $methods;
|
927 |
+
}
|
includes/scripts.php
CHANGED
@@ -5,27 +5,26 @@
|
|
5 |
function pmpro_enqueue_scripts() {
|
6 |
global $pmpro_pages;
|
7 |
|
8 |
-
//
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
$frontend_css_rtl = get_stylesheet_directory_uri() . "/paid-memberships-pro/css/frontend-rtl.css";
|
14 |
-
}
|
15 |
-
} elseif(file_exists(get_template_directory() . "/paid-memberships-pro/frontend.css")) {
|
16 |
-
$frontend_css = get_template_directory_uri() . "/paid-memberships-pro/frontend.css";
|
17 |
-
if( is_rtl() && file_exists(get_template_directory() . "/paid-memberships-pro/css/frontend-rtl.css") ) {
|
18 |
$frontend_css_rtl = get_template_directory_uri() . "/paid-memberships-pro/css/frontend-rtl.css";
|
19 |
-
}
|
20 |
-
} else {
|
21 |
-
$frontend_css = plugins_url('css/frontend.css',dirname(__FILE__) );
|
22 |
-
if( is_rtl() ) {
|
23 |
$frontend_css_rtl = plugins_url('css/frontend-rtl.css',dirname(__FILE__) );
|
24 |
-
}
|
25 |
-
|
26 |
-
wp_enqueue_style('pmpro_frontend', $frontend_css, array(), PMPRO_VERSION, "screen");
|
27 |
-
if( $frontend_css_rtl ) {
|
28 |
-
wp_enqueue_style('pmpro_frontend_rtl', $frontend_css_rtl, array(), PMPRO_VERSION, "screen");
|
29 |
}
|
30 |
|
31 |
// Print styles.
|
@@ -94,43 +93,53 @@ add_action( 'wp_enqueue_scripts', 'pmpro_enqueue_scripts' );
|
|
94 |
* Enqueue admin JavaScript and CSS
|
95 |
*/
|
96 |
function pmpro_admin_enqueue_scripts() {
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
$all_levels = pmpro_getAllLevels( true, true );
|
103 |
-
$all_level_values_and_labels = array();
|
104 |
-
foreach( $all_levels as $level ) {
|
105 |
-
$all_level_values_and_labels[] = array( 'value' => $level->id, 'label' => $level->name );
|
106 |
-
}
|
107 |
-
wp_localize_script( 'pmpro_admin', 'pmpro', array(
|
108 |
-
'all_levels' => $all_levels,
|
109 |
-
'all_level_values_and_labels' => $all_level_values_and_labels
|
110 |
-
));
|
111 |
-
wp_enqueue_script( 'pmpro_admin' );
|
112 |
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
}
|
136 |
-
add_action( 'admin_enqueue_scripts', 'pmpro_admin_enqueue_scripts' );
|
5 |
function pmpro_enqueue_scripts() {
|
6 |
global $pmpro_pages;
|
7 |
|
8 |
+
// Figure out which frontend.css file to load.
|
9 |
+
if( file_exists( get_stylesheet_directory() . "/paid-memberships-pro/css/frontend.css" ) ) {
|
10 |
+
$frontend_css = get_stylesheet_directory_uri() . "/paid-memberships-pro/css/frontend.css";
|
11 |
+
} elseif( file_exists( get_template_directory() . "/paid-memberships-pro/frontend.css" ) ) {
|
12 |
+
$frontend_css = get_template_directory_uri() . "/paid-memberships-pro/frontend.css";
|
13 |
+
} else {
|
14 |
+
$frontend_css = plugins_url( 'css/frontend.css',dirname(__FILE__) );
|
15 |
+
}
|
16 |
+
wp_enqueue_style( 'pmpro_frontend', $frontend_css, array(), PMPRO_VERSION, "screen" );
|
17 |
+
|
18 |
+
// Figure out which frontend-rlt.css file to load if applicable.
|
19 |
+
if( is_rtl() ) {
|
20 |
+
if( file_exists( get_stylesheet_directory() . "/paid-memberships-pro/css/frontend-rtl.css" ) ) {
|
21 |
$frontend_css_rtl = get_stylesheet_directory_uri() . "/paid-memberships-pro/css/frontend-rtl.css";
|
22 |
+
} elseif ( file_exists( get_template_directory() . "/paid-memberships-pro/css/frontend-rtl.css" ) ) {
|
|
|
|
|
|
|
23 |
$frontend_css_rtl = get_template_directory_uri() . "/paid-memberships-pro/css/frontend-rtl.css";
|
24 |
+
} else {
|
|
|
|
|
|
|
25 |
$frontend_css_rtl = plugins_url('css/frontend-rtl.css',dirname(__FILE__) );
|
26 |
+
}
|
27 |
+
wp_enqueue_style( 'pmpro_frontend_rtl', $frontend_css_rtl, array(), PMPRO_VERSION, "screen" );
|
|
|
|
|
|
|
28 |
}
|
29 |
|
30 |
// Print styles.
|
93 |
* Enqueue admin JavaScript and CSS
|
94 |
*/
|
95 |
function pmpro_admin_enqueue_scripts() {
|
96 |
+
// Admin JS
|
97 |
+
wp_register_script( 'pmpro_admin', plugins_url( 'js/pmpro-admin.js', __DIR__ ), [
|
98 |
+
'jquery',
|
99 |
+
'jquery-ui-sortable',
|
100 |
+
], PMPRO_VERSION );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
|
102 |
+
$all_levels = pmpro_getAllLevels( true, true );
|
103 |
+
$all_level_values_and_labels = [];
|
104 |
+
|
105 |
+
foreach ( $all_levels as $level ) {
|
106 |
+
$all_level_values_and_labels[] = [
|
107 |
+
'value' => $level->id,
|
108 |
+
'label' => $level->name,
|
109 |
+
];
|
110 |
+
}
|
111 |
+
|
112 |
+
wp_localize_script( 'pmpro_admin', 'pmpro', [
|
113 |
+
'all_levels' => $all_levels,
|
114 |
+
'all_level_values_and_labels' => $all_level_values_and_labels,
|
115 |
+
] );
|
116 |
+
|
117 |
+
// Figure out which admin.css to load.
|
118 |
+
if ( file_exists( get_stylesheet_directory() . '/paid-memberships-pro/css/admin.css' ) ) {
|
119 |
+
$admin_css = get_stylesheet_directory_uri() . '/paid-memberships-pro/css/admin.css';
|
120 |
+
} elseif ( file_exists( get_template_directory() . '/paid-memberships-pro/admin.css' ) ) {
|
121 |
+
$admin_css = get_template_directory_uri() . '/paid-memberships-pro/admin.css';
|
122 |
+
} else {
|
123 |
+
$admin_css = plugins_url( 'css/admin.css', __DIR__ );
|
124 |
+
}
|
125 |
+
|
126 |
+
// Figure out which admin-rtl.css to load if applicable.
|
127 |
+
if ( file_exists( get_stylesheet_directory() . '/paid-memberships-pro/css/admin-rtl.css' ) ) {
|
128 |
+
$admin_css_rtl = get_stylesheet_directory_uri() . '/paid-memberships-pro/css/admin-rtl.css';
|
129 |
+
} elseif( file_exists( get_template_directory() . '/paid-memberships-pro/css/admin-rtl.css' ) ) {
|
130 |
+
$admin_css_rtl = get_template_directory_uri() . '/paid-memberships-pro/css/admin-rtl.css';
|
131 |
+
} else {
|
132 |
+
$admin_css_rtl = plugins_url( 'css/admin-rtl.css', __DIR__ );
|
133 |
+
}
|
134 |
+
|
135 |
+
wp_register_style( 'pmpro_admin', $admin_css, [], PMPRO_VERSION, 'screen' );
|
136 |
+
wp_register_style( 'pmpro_admin_rtl', $admin_css_rtl, [], PMPRO_VERSION, 'screen' );
|
137 |
+
|
138 |
+
wp_enqueue_script( 'pmpro_admin' );
|
139 |
+
wp_enqueue_style( 'pmpro_admin' );
|
140 |
+
|
141 |
+
if ( is_rtl() ) {
|
142 |
+
wp_enqueue_style( 'pmpro_admin_rtl' );
|
143 |
+
}
|
144 |
}
|
145 |
+
add_action( 'admin_enqueue_scripts', 'pmpro_admin_enqueue_scripts' );
|
includes/services.php
CHANGED
@@ -86,7 +86,12 @@ add_action('wp_ajax_pmpro_orders_print_view', 'pmpro_orders_print_view');
|
|
86 |
* @since 1.8.6
|
87 |
*/
|
88 |
function pmpro_get_order_json() {
|
89 |
-
|
|
|
|
|
|
|
|
|
|
|
90 |
$order = new MemberOrder($order_id);
|
91 |
echo json_encode($order);
|
92 |
exit;
|
@@ -94,7 +99,11 @@ function pmpro_get_order_json() {
|
|
94 |
add_action('wp_ajax_pmpro_get_order_json', 'pmpro_get_order_json');
|
95 |
|
96 |
function pmpro_update_level_order() {
|
97 |
-
|
|
|
|
|
|
|
|
|
98 |
$level_order = null;
|
99 |
|
100 |
if ( isset( $_REQUEST['level_order'] ) && is_array( $_REQUEST['level_order'] ) ) {
|
86 |
* @since 1.8.6
|
87 |
*/
|
88 |
function pmpro_get_order_json() {
|
89 |
+
// only admins can get this
|
90 |
+
if ( ! function_exists( 'current_user_can' ) || ( ! current_user_can( 'manage_options' ) && ! current_user_can( 'pmpro_orders' ) ) ) {
|
91 |
+
die( __( 'You do not have permissions to perform this action.', 'paid-memberships-pro' ) );
|
92 |
+
}
|
93 |
+
|
94 |
+
$order_id = intval( $_REQUEST['order_id'] );
|
95 |
$order = new MemberOrder($order_id);
|
96 |
echo json_encode($order);
|
97 |
exit;
|
99 |
add_action('wp_ajax_pmpro_get_order_json', 'pmpro_get_order_json');
|
100 |
|
101 |
function pmpro_update_level_order() {
|
102 |
+
// only admins can get this
|
103 |
+
if ( ! function_exists( 'current_user_can' ) || ( ! current_user_can( 'manage_options' ) && ! current_user_can( 'pmpro_membershiplevels' ) ) ) {
|
104 |
+
die( __( 'You do not have permissions to perform this action.', 'paid-memberships-pro' ) );
|
105 |
+
}
|
106 |
+
|
107 |
$level_order = null;
|
108 |
|
109 |
if ( isset( $_REQUEST['level_order'] ) && is_array( $_REQUEST['level_order'] ) ) {
|
includes/setup.sql
CHANGED
@@ -45,7 +45,7 @@ CREATE TABLE `wp_pmpro_discount_codes_levels` (
|
|
45 |
`trial_amount` decimal(18,8) NOT NULL DEFAULT '0.00',
|
46 |
`trial_limit` int(11) NOT NULL DEFAULT '0',
|
47 |
`expiration_number` int(10) unsigned NOT NULL,
|
48 |
-
`expiration_period` enum('Day','Week','Month','Year') NOT NULL,
|
49 |
PRIMARY KEY (`code_id`,`level_id`),
|
50 |
KEY `initial_payment` (`initial_payment`)
|
51 |
);
|
@@ -87,7 +87,7 @@ CREATE TABLE `wp_pmpro_membership_levels` (
|
|
87 |
`trial_limit` int(11) NOT NULL DEFAULT '0',
|
88 |
`allow_signups` tinyint(4) NOT NULL DEFAULT '1',
|
89 |
`expiration_number` int(10) unsigned NOT NULL,
|
90 |
-
`expiration_period` enum('Day','Week','Month','Year') NOT NULL,
|
91 |
PRIMARY KEY (`id`),
|
92 |
KEY `allow_signups` (`allow_signups`),
|
93 |
KEY `initial_payment` (`initial_payment`),
|
@@ -112,6 +112,22 @@ CREATE TABLE `wp_pmpro_membership_levelmeta` (
|
|
112 |
|
113 |
-- --------------------------------------------------------
|
114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
--
|
116 |
-- Table structure for table `wp_pmpro_membership_orders`
|
117 |
--
|
@@ -177,7 +193,7 @@ CREATE TABLE `wp_pmpro_memberships_categories` (
|
|
177 |
`membership_id` int(11) unsigned NOT NULL,
|
178 |
`category_id` int(11) unsigned NOT NULL,
|
179 |
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
180 |
-
|
181 |
UNIQUE KEY `category_membership` (`category_id`,`membership_id`)
|
182 |
);
|
183 |
|
@@ -191,7 +207,7 @@ CREATE TABLE `wp_pmpro_memberships_pages` (
|
|
191 |
`membership_id` int(11) unsigned NOT NULL,
|
192 |
`page_id` int(11) unsigned NOT NULL,
|
193 |
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
194 |
-
|
195 |
UNIQUE KEY `membership_page` (`membership_id`,`page_id`)
|
196 |
);
|
197 |
|
45 |
`trial_amount` decimal(18,8) NOT NULL DEFAULT '0.00',
|
46 |
`trial_limit` int(11) NOT NULL DEFAULT '0',
|
47 |
`expiration_number` int(10) unsigned NOT NULL,
|
48 |
+
`expiration_period` enum('Hour','Day','Week','Month','Year') NOT NULL,
|
49 |
PRIMARY KEY (`code_id`,`level_id`),
|
50 |
KEY `initial_payment` (`initial_payment`)
|
51 |
);
|
87 |
`trial_limit` int(11) NOT NULL DEFAULT '0',
|
88 |
`allow_signups` tinyint(4) NOT NULL DEFAULT '1',
|
89 |
`expiration_number` int(10) unsigned NOT NULL,
|
90 |
+
`expiration_period` enum('Hour','Day','Week','Month','Year') NOT NULL,
|
91 |
PRIMARY KEY (`id`),
|
92 |
KEY `allow_signups` (`allow_signups`),
|
93 |
KEY `initial_payment` (`initial_payment`),
|
112 |
|
113 |
-- --------------------------------------------------------
|
114 |
|
115 |
+
--
|
116 |
+
-- Table structure for table `wp_pmpro_membership_ordermeta`
|
117 |
+
--
|
118 |
+
|
119 |
+
CREATE TABLE `wp_pmpro_membership_ordermeta` (
|
120 |
+
`meta_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
121 |
+
`pmpro_membership_order_id` int(10) unsigned NOT NULL,
|
122 |
+
`meta_key` varchar(255) NOT NULL,
|
123 |
+
`meta_value` longtext,
|
124 |
+
PRIMARY KEY (`meta_id`),
|
125 |
+
KEY `pmpro_membership_order_id` (`pmpro_membership_order_id`),
|
126 |
+
KEY `meta_key` (`meta_key`)
|
127 |
+
);
|
128 |
+
|
129 |
+
-- --------------------------------------------------------
|
130 |
+
|
131 |
--
|
132 |
-- Table structure for table `wp_pmpro_membership_orders`
|
133 |
--
|
193 |
`membership_id` int(11) unsigned NOT NULL,
|
194 |
`category_id` int(11) unsigned NOT NULL,
|
195 |
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
196 |
+
PRIMARY KEY (`membership_id`,`category_id`),
|
197 |
UNIQUE KEY `category_membership` (`category_id`,`membership_id`)
|
198 |
);
|
199 |
|
207 |
`membership_id` int(11) unsigned NOT NULL,
|
208 |
`page_id` int(11) unsigned NOT NULL,
|
209 |
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
210 |
+
PRIMARY KEY (`page_id`,`membership_id`),
|
211 |
UNIQUE KEY `membership_page` (`membership_id`,`page_id`)
|
212 |
);
|
213 |
|
includes/spam.php
ADDED
@@ -0,0 +1,192 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Code related to spam detection and prevention.
|
4 |
+
*/
|
5 |
+
// Constants. Define these in wp-config.php to override.
|
6 |
+
if ( ! defined( 'PMPRO_SPAM_ACTION_NUM_LIMIT' ) ) {
|
7 |
+
define( 'PMPRO_SPAM_ACTION_NUM_LIMIT', 10 );
|
8 |
+
}
|
9 |
+
if ( ! defined( 'PMPRO_SPAM_ACTION_TIME_LIMIT' ) ) {
|
10 |
+
define( 'PMPRO_SPAM_ACTION_TIME_LIMIT', 900 ); // in seconds
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Determine whether the current visitor a spammer.
|
15 |
+
*
|
16 |
+
* @since 2.7
|
17 |
+
*
|
18 |
+
* @return bool Whether the current visitor a spammer.
|
19 |
+
*/
|
20 |
+
function pmpro_is_spammer() {
|
21 |
+
$is_spammer = false;
|
22 |
+
|
23 |
+
$activity = pmpro_get_spam_activity();
|
24 |
+
if ( false !== $activity && count( $activity ) >= PMPRO_SPAM_ACTION_NUM_LIMIT ) {
|
25 |
+
$is_spammer = true;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Allow filtering whether the current visitor is a spammer.
|
30 |
+
*
|
31 |
+
* @since 2.7
|
32 |
+
*
|
33 |
+
* @param bool $is_spammer Whether the current visitor is a spammer.
|
34 |
+
* @param array $activity The list of potential spam activity.
|
35 |
+
*/
|
36 |
+
return apply_filters( 'pmpro_is_spammer', $is_spammer, $activity );
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Get the list of potential spam activity.
|
41 |
+
*
|
42 |
+
* @since 2.7
|
43 |
+
*
|
44 |
+
* @param string|null $ip The IP address to get activity for, or leave as null to attempt to determine current IP address.
|
45 |
+
*
|
46 |
+
* @return array|false The list of potential spam activity if successful, or false if IP could not be determined.
|
47 |
+
*/
|
48 |
+
function pmpro_get_spam_activity( $ip = null ) {
|
49 |
+
if ( empty( $ip ) ) {
|
50 |
+
$ip = pmpro_get_ip();
|
51 |
+
}
|
52 |
+
|
53 |
+
// If we can't determine the IP, let's bail.
|
54 |
+
if ( empty( $ip ) ) {
|
55 |
+
return false;
|
56 |
+
}
|
57 |
+
|
58 |
+
$ip = preg_replace( '/[^0-9a-fA-F:., ]/', '', $ip );
|
59 |
+
$transient_key = 'pmpro_spam_activity_' . $ip;
|
60 |
+
$activity = get_transient( $transient_key );
|
61 |
+
if ( empty( $activity ) || ! is_array( $activity ) ) {
|
62 |
+
$activity = [];
|
63 |
+
}
|
64 |
+
|
65 |
+
// Remove old items.
|
66 |
+
$new_activity = [];
|
67 |
+
$now = current_time( 'timestamp', true ); // UTC
|
68 |
+
foreach( $activity as $item ) {
|
69 |
+
// Determine whether this item is recent enough to include.
|
70 |
+
if ( $item > $now-( PMPRO_SPAM_ACTION_TIME_LIMIT ) ) {
|
71 |
+
$new_activity[] = $item;
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
+
return $new_activity;
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Track spam activity.
|
80 |
+
* When we hit a certain number, the spam flag will trigger.
|
81 |
+
* For now we are only tracking credit card declines their timestamps.
|
82 |
+
* IP address isn't a perfect way to track this, but it's the best we have.
|
83 |
+
*
|
84 |
+
* @since 2.7
|
85 |
+
*
|
86 |
+
* @param string|null $ip The IP address to track activity for, or leave as null to attempt to determine current IP address.
|
87 |
+
*
|
88 |
+
* @return bool True if the tracking of activity was successful, or false if IP could not be determined.
|
89 |
+
*/
|
90 |
+
function pmpro_track_spam_activity( $ip = null ) {
|
91 |
+
if ( empty( $ip ) ) {
|
92 |
+
$ip = pmpro_get_ip();
|
93 |
+
}
|
94 |
+
|
95 |
+
// If we can't determine the IP, let's bail.
|
96 |
+
if ( empty( $ip ) ) {
|
97 |
+
return false;
|
98 |
+
}
|
99 |
+
|
100 |
+
$activity = pmpro_get_spam_activity( $ip );
|
101 |
+
$now = current_time( 'timestamp', true ); // UTC
|
102 |
+
array_unshift( $activity, $now );
|
103 |
+
|
104 |
+
// If we have more than the limit, don't bother storing them.
|
105 |
+
if ( count( $activity ) > PMPRO_SPAM_ACTION_NUM_LIMIT ) {
|
106 |
+
rsort( $activity );
|
107 |
+
$activity = array_slice( $activity, 0, PMPRO_SPAM_ACTION_NUM_LIMIT );
|
108 |
+
}
|
109 |
+
|
110 |
+
// Save to transient.
|
111 |
+
$ip = preg_replace( '/[^0-9a-fA-F:., ]/', '', $ip );
|
112 |
+
$transient_key = 'pmpro_spam_activity_' . $ip;
|
113 |
+
set_transient( $transient_key, $activity, (int) PMPRO_SPAM_ACTION_TIME_LIMIT );
|
114 |
+
|
115 |
+
return true;
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Clears all stored spam activity for an IP address.
|
120 |
+
* Note that the pmpro_get_spam_activity function clears out old values
|
121 |
+
* automatically, and this should only be used to completely clear the activity.
|
122 |
+
*
|
123 |
+
* @since 2.7
|
124 |
+
*
|
125 |
+
* @param string|null $ip The IP address to clear activity for, or leave as null to attempt to determine current IP address.
|
126 |
+
*
|
127 |
+
* @return bool True if the clearing of activity was successful, or false if IP could not be determined.
|
128 |
+
*/
|
129 |
+
function pmpro_clear_spam_activity( $ip = null ) {
|
130 |
+
if ( empty( $ip ) ) {
|
131 |
+
$ip = pmpro_get_ip();
|
132 |
+
}
|
133 |
+
|
134 |
+
// If we can't determine the IP, let's bail.
|
135 |
+
if ( empty( $ip ) ) {
|
136 |
+
return false;
|
137 |
+
}
|
138 |
+
|
139 |
+
$transient_key = 'pmpro_spam_activity_' . $ip;
|
140 |
+
|
141 |
+
delete_transient( $transient_key );
|
142 |
+
|
143 |
+
return true;
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Track spam activity when checkouts or billing updates fail.
|
148 |
+
*
|
149 |
+
* @since 2.7
|
150 |
+
* @param MemberOrder $morder The order object used at checkout. We ignore it.
|
151 |
+
*/
|
152 |
+
function pmpro_track_failed_checkouts_for_spam( $morder ) {
|
153 |
+
// Bail if Spam Protection is disabled.
|
154 |
+
$spamprotection = pmpro_getOption("spamprotection");
|
155 |
+
if ( empty( $spamprotection ) ) {
|
156 |
+
return;
|
157 |
+
}
|
158 |
+
|
159 |
+
pmpro_track_spam_activity();
|
160 |
+
}
|
161 |
+
add_action( 'pmpro_checkout_processing_failed', 'pmpro_track_failed_checkouts_for_spam' );
|
162 |
+
add_action( 'pmpro_update_billing_failed', 'pmpro_track_failed_checkouts_for_spam' );
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Disable checkout and billing update forms for spammers.
|
166 |
+
*
|
167 |
+
* We're using the pmpro_required_billing_fields filter because it is
|
168 |
+
* consistently used on the checkout and update billing pages.
|
169 |
+
* The pmpro_setMessage() function sets the $pmpro_msgt value to error,
|
170 |
+
* which stops the forms from working and shows the corresponding error.
|
171 |
+
* We return the $required_fields parameter to keep the filter working.
|
172 |
+
*
|
173 |
+
* @since 2.7
|
174 |
+
*
|
175 |
+
* @param array $required_fields The list of required fields.
|
176 |
+
*
|
177 |
+
* @return array The list of required fields.
|
178 |
+
*/
|
179 |
+
function pmpro_disable_checkout_for_spammers( $required_fields ) {
|
180 |
+
// Bail if Spam Protection is disabled.
|
181 |
+
$spamprotection = pmpro_getOption("spamprotection");
|
182 |
+
if ( empty( $spamprotection ) ) {
|
183 |
+
return $required_fields;
|
184 |
+
}
|
185 |
+
|
186 |
+
if ( pmpro_was_checkout_form_submitted() && pmpro_is_spammer() ) {
|
187 |
+
pmpro_setMessage( __( 'Suspicious activity detected. Try again in a few minutes.', 'paid-memberships-pro' ), 'pmpro_error' );
|
188 |
+
}
|
189 |
+
|
190 |
+
return $required_fields;
|
191 |
+
}
|
192 |
+
add_filter( 'pmpro_required_billing_fields', 'pmpro_disable_checkout_for_spammers' );
|
includes/updates/upgrade_2_4.php
CHANGED
@@ -32,16 +32,7 @@ function pmpro_upgrade_2_4() {
|
|
32 |
pmpro_addUpdate( 'pmpro_upgrade_2_4_ajax' );
|
33 |
} else {
|
34 |
//less than 10, let's just do them now
|
35 |
-
$
|
36 |
-
require_once( ABSPATH . "/wp-includes/pluggable.php" );
|
37 |
-
foreach($orders as $order) {
|
38 |
-
$subscription = $stripe->getSubscription( $order );
|
39 |
-
|
40 |
-
if ( ! empty( $subscription ) ) {
|
41 |
-
$sqlQuery = "UPDATE $wpdb->pmpro_membership_orders SET subscription_transaction_id = '" . esc_sql( $subscription->id ) . "' WHERE id = '" . esc_sql( $order->id ) . "' LIMIT 1";
|
42 |
-
$wpdb->query( $sqlQuery );
|
43 |
-
}
|
44 |
-
}
|
45 |
}
|
46 |
}
|
47 |
|
@@ -75,20 +66,55 @@ function pmpro_upgrade_2_4_ajax() {
|
|
75 |
pmpro_removeUpdate('pmpro_upgrade_2_4_ajax');
|
76 |
delete_option( 'pmpro_upgrade_2_4_last_order_id' );
|
77 |
} else {
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
$wpdb->query( $sqlQuery );
|
|
|
87 |
}
|
88 |
-
|
89 |
-
$last_order_id = $order->id;
|
90 |
}
|
|
|
|
|
91 |
|
|
|
92 |
update_option( 'pmpro_upgrade_2_4_last_order_id', $last_order_id );
|
93 |
}
|
94 |
}
|
32 |
pmpro_addUpdate( 'pmpro_upgrade_2_4_ajax' );
|
33 |
} else {
|
34 |
//less than 10, let's just do them now
|
35 |
+
pmpro_upgrade_2_4_helper_get_subscriptions_for_orders( $orders, false );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
}
|
37 |
}
|
38 |
|
66 |
pmpro_removeUpdate('pmpro_upgrade_2_4_ajax');
|
67 |
delete_option( 'pmpro_upgrade_2_4_last_order_id' );
|
68 |
} else {
|
69 |
+
pmpro_upgrade_2_4_helper_get_subscriptions_for_orders( $orders, true );
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Populate subscription_ids for Stripe orders.
|
75 |
+
*
|
76 |
+
* @param array $orders to find subscription_id for.
|
77 |
+
* @param bool $update_last_order_id. Should be true if updating via ajax.
|
78 |
+
*/
|
79 |
+
function pmpro_upgrade_2_4_helper_get_subscriptions_for_orders( $orders, $update_last_order_id ) {
|
80 |
+
global $wpdb;
|
81 |
+
$stripe = new PMProGateway_stripe();
|
82 |
+
require_once( ABSPATH . "/wp-includes/pluggable.php" );
|
83 |
+
foreach($orders as $order) {
|
84 |
+
if ( empty( $order->code ) ) {
|
85 |
+
continue;
|
86 |
+
}
|
87 |
+
$customer = $stripe->get_customer_for_user( $order->user_id );
|
88 |
+
|
89 |
+
//no customer or no subscriptions?
|
90 |
+
if ( empty( $customer ) || empty( $customer->subscriptions ) ) {
|
91 |
+
continue;
|
92 |
+
}
|
93 |
+
|
94 |
+
//find subscription based on customer id and order/plan id
|
95 |
+
$subscriptions = $customer->subscriptions->all();
|
96 |
+
|
97 |
+
|
98 |
+
//no subscriptions
|
99 |
+
if ( empty( $subscriptions ) || empty( $subscriptions->data ) ) {
|
100 |
+
return false;
|
101 |
+
}
|
102 |
+
|
103 |
+
//we really want to test against the order codes of all orders with the same subscription_transaction_id (customer id)
|
104 |
+
$codes = $wpdb->get_col( "SELECT code FROM $wpdb->pmpro_membership_orders WHERE user_id = '" . esc_sql( $order->user_id ) . "' AND subscription_transaction_id = '' AND status NOT IN('refunded', 'review', 'token', 'error')" );
|
105 |
+
|
106 |
+
//find the one for this order
|
107 |
+
foreach ( $subscriptions->data as $sub ) {
|
108 |
+
if ( in_array( $sub->plan->id, $codes ) ) {
|
109 |
+
$sqlQuery = "UPDATE $wpdb->pmpro_membership_orders SET subscription_transaction_id = '" . esc_sql( $sub->id ) . "' WHERE id = '" . esc_sql( $order->id ) . "' LIMIT 1";
|
110 |
$wpdb->query( $sqlQuery );
|
111 |
+
break;
|
112 |
}
|
|
|
|
|
113 |
}
|
114 |
+
$last_order_id = $order->id;
|
115 |
+
}
|
116 |
|
117 |
+
if ( $update_last_order_id ) {
|
118 |
update_option( 'pmpro_upgrade_2_4_last_order_id', $last_order_id );
|
119 |
}
|
120 |
}
|
includes/updates/upgrade_2_6.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Upgrade to 2.6
|
4 |
+
* We changed the pmpro_cron_expire_memberships cron
|
5 |
+
* to run hourly instead of daily.
|
6 |
+
* To ensure that existing members still expire at least
|
7 |
+
* 1 calendar day after their expiration date, we are
|
8 |
+
* updating old expiration date timestamps to set
|
9 |
+
* the time component to 11:59. This way e.g.
|
10 |
+
* someone who checked out at 3pm on Dec 31 won't expire
|
11 |
+
* until Jan 1 at midnight.
|
12 |
+
* Going forward, we will always set the expiration time to 11:59
|
13 |
+
* unless the level is set up to expire hourly.
|
14 |
+
*/
|
15 |
+
function pmpro_upgrade_2_6() {
|
16 |
+
// Map email settings to new email template settings.
|
17 |
+
// Note: the old settings were true to enable, the new settings are true to disable.
|
18 |
+
$admin_checkout = pmpro_getOption( 'email_admin_checkout' );
|
19 |
+
if ( empty( $admin_checkout ) ) {
|
20 |
+
pmpro_setOption( 'email_checkout_check_admin_disabled', 'true' );
|
21 |
+
pmpro_setOption( 'email_checkout_express_admin_disabled', 'true' );
|
22 |
+
pmpro_setOption( 'email_checkout_free_admin_disabled', 'true' );
|
23 |
+
pmpro_setOption( 'email_checkout_freetrial_admin_disabled', 'true' );
|
24 |
+
pmpro_setOption( 'email_checkout_paid_admin_disabled', 'true' );
|
25 |
+
pmpro_setOption( 'email_checkout_trial_admin_disabled', 'true' );
|
26 |
+
}
|
27 |
+
$admin_changes = pmpro_getOption( 'email_admin_changes' );
|
28 |
+
if ( empty( $admin_changes ) ) {
|
29 |
+
pmpro_setOption( 'email_admin_change_admin_disabled', 'true' );
|
30 |
+
}
|
31 |
+
$admin_cancels = pmpro_getOption( 'email_admin_cancels' );
|
32 |
+
if ( empty( $admin_cancels ) ) {
|
33 |
+
pmpro_setOption( 'email_cancel_admin_disabled', 'true' );
|
34 |
+
}
|
35 |
+
$admin_billing = pmpro_getOption( 'email_admin_billing' );
|
36 |
+
if ( empty( $admin_billing ) ) {
|
37 |
+
pmpro_setOption( 'email_billing_admin_disabled', 'true' );
|
38 |
+
}
|
39 |
+
|
40 |
+
// Reschedule cron job for hourly checks.
|
41 |
+
$next = wp_next_scheduled( 'pmpro_cron_expire_memberships' );
|
42 |
+
if ( ! empty( $next ) ) {
|
43 |
+
wp_unschedule_event( $next, 'pmpro_cron_expire_memberships' );
|
44 |
+
}
|
45 |
+
pmpro_maybe_schedule_event( current_time( 'timestamp' ), 'hourly', 'pmpro_cron_expire_memberships' );
|
46 |
+
}
|
includes/upgradecheck.php
CHANGED
@@ -135,7 +135,7 @@ function pmpro_checkForUpgrades()
|
|
135 |
|
136 |
//fix subscription ids on stripe orders
|
137 |
require_once(PMPRO_DIR . "/includes/updates/upgrade_1_8_6_9.php"); //need to include this for AJAX calls
|
138 |
-
if($pmpro_db_version < 1.869) {
|
139 |
$pmpro_db_version = pmpro_upgrade_1_8_6_9();
|
140 |
}
|
141 |
|
@@ -144,27 +144,27 @@ function pmpro_checkForUpgrades()
|
|
144 |
require_once(PMPRO_DIR . "/includes/updates/upgrade_1_8_7.php");
|
145 |
$pmpro_db_version = pmpro_upgrade_1_8_7();
|
146 |
}
|
147 |
-
|
148 |
/*
|
149 |
v1.8.8
|
150 |
* Running the cron job cleanup again.
|
151 |
* Fixing old $0 Stripe orders.
|
152 |
* Fixing old Authorize.net orders with empty status.
|
153 |
-
*/
|
154 |
require_once(PMPRO_DIR . "/includes/updates/upgrade_1_8_8.php");
|
155 |
-
if($pmpro_db_version < 1.88) {
|
156 |
-
$pmpro_db_version = pmpro_upgrade_1_8_8();
|
157 |
}
|
158 |
-
|
159 |
/*
|
160 |
v1.8.9.1
|
161 |
* Fixing Stripe orders where user_id/membership_id = 0
|
162 |
* Updated in v1.9.2.2 to check for namespace compatibility first,
|
163 |
since the Stripe class isn't loaded for PHP < 5.3.29
|
164 |
-
*/
|
165 |
if (version_compare( PHP_VERSION, '5.3.29', '>=' )) {
|
166 |
require_once(PMPRO_DIR . "/includes/updates/upgrade_1_8_9_1.php");
|
167 |
-
if($pmpro_db_version < 1.891) {
|
168 |
$pmpro_db_version = pmpro_upgrade_1_8_9_1();
|
169 |
}
|
170 |
} elseif($pmpro_db_version < 1.891) {
|
@@ -177,18 +177,18 @@ function pmpro_checkForUpgrades()
|
|
177 |
*/
|
178 |
if($pmpro_db_version < 1.892) {
|
179 |
pmpro_db_delta();
|
180 |
-
|
181 |
$pmpro_db_version = 1.892;
|
182 |
pmpro_setOption("db_version", "1.892");
|
183 |
}
|
184 |
|
185 |
/*
|
186 |
v1.8.9.3 (db v1.91)
|
187 |
-
* Fixing incorrect start and end dates.
|
188 |
*/
|
189 |
require_once(PMPRO_DIR . "/includes/updates/upgrade_1_8_9_3.php");
|
190 |
if($pmpro_db_version < 1.91) {
|
191 |
-
$pmpro_db_version = pmpro_upgrade_1_8_9_3();
|
192 |
}
|
193 |
|
194 |
/*
|
@@ -198,7 +198,7 @@ function pmpro_checkForUpgrades()
|
|
198 |
*/
|
199 |
if($pmpro_db_version < 1.92) {
|
200 |
pmpro_db_delta();
|
201 |
-
|
202 |
$pmpro_db_version = 1.92;
|
203 |
pmpro_setOption("db_version", "1.92");
|
204 |
}
|
@@ -210,16 +210,16 @@ function pmpro_checkForUpgrades()
|
|
210 |
*/
|
211 |
if($pmpro_db_version < 1.93) {
|
212 |
pmpro_db_delta();
|
213 |
-
|
214 |
$pmpro_db_version = 1.93;
|
215 |
pmpro_setOption("db_version", "1.93");
|
216 |
}
|
217 |
|
218 |
-
require_once( PMPRO_DIR . "/includes/updates/upgrade_1_9_4.php" );
|
219 |
if($pmpro_db_version < 1.94) {
|
220 |
$pmpro_db_version = pmpro_upgrade_1_9_4();
|
221 |
}
|
222 |
-
|
223 |
if($pmpro_db_version < 1.944) {
|
224 |
pmpro_cleanup_memberships_users_table();
|
225 |
$pmpro_db_version = '1.944';
|
@@ -232,21 +232,51 @@ function pmpro_checkForUpgrades()
|
|
232 |
$pmpro_db_version = 2.1;
|
233 |
pmpro_setOption( 'db_version', '2.1' );
|
234 |
}
|
235 |
-
|
236 |
if ( $pmpro_db_version < 2.3 ) {
|
237 |
pmpro_maybe_schedule_event( strtotime( '10:30:00' ) - ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ), 'daily', 'pmpro_cron_admin_activity_email' );
|
238 |
pmpro_setOption( 'db_version', '2.3' );
|
239 |
}
|
240 |
-
|
241 |
/**
|
242 |
* Version 2.4
|
243 |
* Fixing subscription_transaction_id
|
244 |
* for orders created through a Stripe Update.
|
245 |
*/
|
246 |
-
require_once( PMPRO_DIR . "/includes/updates/upgrade_2_4.php" );
|
247 |
if($pmpro_db_version < 2.4) {
|
248 |
$pmpro_db_version = pmpro_upgrade_2_4();
|
249 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
250 |
}
|
251 |
|
252 |
function pmpro_db_delta()
|
@@ -264,6 +294,7 @@ function pmpro_db_delta()
|
|
264 |
$wpdb->pmpro_discount_codes_levels = $wpdb->prefix . 'pmpro_discount_codes_levels';
|
265 |
$wpdb->pmpro_discount_codes_uses = $wpdb->prefix . 'pmpro_discount_codes_uses';
|
266 |
$wpdb->pmpro_membership_levelmeta = $wpdb->prefix . 'pmpro_membership_levelmeta';
|
|
|
267 |
|
268 |
//wp_pmpro_membership_levels
|
269 |
$sqlQuery = "
|
@@ -281,7 +312,7 @@ function pmpro_db_delta()
|
|
281 |
`trial_limit` int(11) NOT NULL DEFAULT '0',
|
282 |
`allow_signups` tinyint(4) NOT NULL DEFAULT '1',
|
283 |
`expiration_number` int(10) unsigned NOT NULL,
|
284 |
-
`expiration_period` enum('Day','Week','Month','Year') NOT NULL,
|
285 |
PRIMARY KEY (`id`),
|
286 |
KEY `allow_signups` (`allow_signups`),
|
287 |
KEY `initial_payment` (`initial_payment`),
|
@@ -293,10 +324,10 @@ function pmpro_db_delta()
|
|
293 |
//wp_pmpro_membership_orders
|
294 |
$sqlQuery = "
|
295 |
CREATE TABLE `" . $wpdb->pmpro_membership_orders . "` (
|
296 |
-
`id`
|
297 |
`code` varchar(32) NOT NULL,
|
298 |
`session_id` varchar(64) NOT NULL DEFAULT '',
|
299 |
-
`user_id`
|
300 |
`membership_id` int(11) unsigned NOT NULL DEFAULT '0',
|
301 |
`paypal_token` varchar(64) NOT NULL DEFAULT '',
|
302 |
`billing_name` varchar(128) NOT NULL DEFAULT '',
|
@@ -309,7 +340,7 @@ function pmpro_db_delta()
|
|
309 |
`subtotal` varchar(16) NOT NULL DEFAULT '',
|
310 |
`tax` varchar(16) NOT NULL DEFAULT '',
|
311 |
`couponamount` varchar(16) NOT NULL DEFAULT '',
|
312 |
-
`checkout_id`
|
313 |
`certificate_id` int(11) NOT NULL DEFAULT '0',
|
314 |
`certificateamount` varchar(16) NOT NULL DEFAULT '',
|
315 |
`total` varchar(16) NOT NULL DEFAULT '',
|
@@ -349,9 +380,9 @@ function pmpro_db_delta()
|
|
349 |
$sqlQuery = "
|
350 |
CREATE TABLE `" . $wpdb->pmpro_memberships_categories . "` (
|
351 |
`membership_id` int(11) unsigned NOT NULL,
|
352 |
-
`category_id`
|
353 |
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
354 |
-
|
355 |
UNIQUE KEY `category_membership` (`category_id`,`membership_id`)
|
356 |
);
|
357 |
";
|
@@ -361,9 +392,9 @@ function pmpro_db_delta()
|
|
361 |
$sqlQuery = "
|
362 |
CREATE TABLE `" . $wpdb->pmpro_memberships_pages . "` (
|
363 |
`membership_id` int(11) unsigned NOT NULL,
|
364 |
-
`page_id`
|
365 |
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
366 |
-
|
367 |
UNIQUE KEY `membership_page` (`membership_id`,`page_id`)
|
368 |
);
|
369 |
";
|
@@ -373,9 +404,9 @@ function pmpro_db_delta()
|
|
373 |
$sqlQuery = "
|
374 |
CREATE TABLE `" . $wpdb->pmpro_memberships_users . "` (
|
375 |
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
376 |
-
`user_id`
|
377 |
`membership_id` int(11) unsigned NOT NULL,
|
378 |
-
`code_id`
|
379 |
`initial_payment` decimal(18,8) NOT NULL,
|
380 |
`billing_amount` decimal(18,8) NOT NULL,
|
381 |
`cycle_number` int(11) NOT NULL,
|
@@ -401,7 +432,7 @@ function pmpro_db_delta()
|
|
401 |
//wp_pmpro_discount_codes
|
402 |
$sqlQuery = "
|
403 |
CREATE TABLE `" . $wpdb->pmpro_discount_codes . "` (
|
404 |
-
`id`
|
405 |
`code` varchar(32) NOT NULL,
|
406 |
`starts` date NOT NULL,
|
407 |
`expires` date NOT NULL,
|
@@ -417,7 +448,7 @@ function pmpro_db_delta()
|
|
417 |
//wp_pmpro_discount_codes_levels
|
418 |
$sqlQuery = "
|
419 |
CREATE TABLE `" . $wpdb->pmpro_discount_codes_levels . "` (
|
420 |
-
`code_id`
|
421 |
`level_id` int(11) unsigned NOT NULL,
|
422 |
`initial_payment` decimal(18,8) NOT NULL DEFAULT '0.00',
|
423 |
`billing_amount` decimal(18,8) NOT NULL DEFAULT '0.00',
|
@@ -427,7 +458,7 @@ function pmpro_db_delta()
|
|
427 |
`trial_amount` decimal(18,8) NOT NULL DEFAULT '0.00',
|
428 |
`trial_limit` int(11) NOT NULL DEFAULT '0',
|
429 |
`expiration_number` int(10) unsigned NOT NULL,
|
430 |
-
`expiration_period` enum('Day','Week','Month','Year') NOT NULL,
|
431 |
PRIMARY KEY (`code_id`,`level_id`),
|
432 |
KEY `initial_payment` (`initial_payment`)
|
433 |
);
|
@@ -437,10 +468,10 @@ function pmpro_db_delta()
|
|
437 |
//wp_pmpro_discount_codes_uses
|
438 |
$sqlQuery = "
|
439 |
CREATE TABLE `" . $wpdb->pmpro_discount_codes_uses . "` (
|
440 |
-
`id`
|
441 |
-
`code_id`
|
442 |
-
`user_id`
|
443 |
-
`order_id`
|
444 |
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
445 |
PRIMARY KEY (`id`),
|
446 |
KEY `user_id` (`user_id`),
|
@@ -452,8 +483,8 @@ function pmpro_db_delta()
|
|
452 |
//pmpro_membership_levelmeta
|
453 |
$sqlQuery = "
|
454 |
CREATE TABLE `" . $wpdb->pmpro_membership_levelmeta . "` (
|
455 |
-
`meta_id`
|
456 |
-
`pmpro_membership_level_id` int(
|
457 |
`meta_key` varchar(255) NOT NULL,
|
458 |
`meta_value` longtext,
|
459 |
PRIMARY KEY (`meta_id`),
|
@@ -462,4 +493,18 @@ function pmpro_db_delta()
|
|
462 |
);
|
463 |
";
|
464 |
dbDelta($sqlQuery);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
465 |
}
|
135 |
|
136 |
//fix subscription ids on stripe orders
|
137 |
require_once(PMPRO_DIR . "/includes/updates/upgrade_1_8_6_9.php"); //need to include this for AJAX calls
|
138 |
+
if($pmpro_db_version < 1.869) {
|
139 |
$pmpro_db_version = pmpro_upgrade_1_8_6_9();
|
140 |
}
|
141 |
|
144 |
require_once(PMPRO_DIR . "/includes/updates/upgrade_1_8_7.php");
|
145 |
$pmpro_db_version = pmpro_upgrade_1_8_7();
|
146 |
}
|
147 |
+
|
148 |
/*
|
149 |
v1.8.8
|
150 |
* Running the cron job cleanup again.
|
151 |
* Fixing old $0 Stripe orders.
|
152 |
* Fixing old Authorize.net orders with empty status.
|
153 |
+
*/
|
154 |
require_once(PMPRO_DIR . "/includes/updates/upgrade_1_8_8.php");
|
155 |
+
if($pmpro_db_version < 1.88) {
|
156 |
+
$pmpro_db_version = pmpro_upgrade_1_8_8();
|
157 |
}
|
158 |
+
|
159 |
/*
|
160 |
v1.8.9.1
|
161 |
* Fixing Stripe orders where user_id/membership_id = 0
|
162 |
* Updated in v1.9.2.2 to check for namespace compatibility first,
|
163 |
since the Stripe class isn't loaded for PHP < 5.3.29
|
164 |
+
*/
|
165 |
if (version_compare( PHP_VERSION, '5.3.29', '>=' )) {
|
166 |
require_once(PMPRO_DIR . "/includes/updates/upgrade_1_8_9_1.php");
|
167 |
+
if($pmpro_db_version < 1.891) {
|
168 |
$pmpro_db_version = pmpro_upgrade_1_8_9_1();
|
169 |
}
|
170 |
} elseif($pmpro_db_version < 1.891) {
|
177 |
*/
|
178 |
if($pmpro_db_version < 1.892) {
|
179 |
pmpro_db_delta();
|
180 |
+
|
181 |
$pmpro_db_version = 1.892;
|
182 |
pmpro_setOption("db_version", "1.892");
|
183 |
}
|
184 |
|
185 |
/*
|
186 |
v1.8.9.3 (db v1.91)
|
187 |
+
* Fixing incorrect start and end dates.
|
188 |
*/
|
189 |
require_once(PMPRO_DIR . "/includes/updates/upgrade_1_8_9_3.php");
|
190 |
if($pmpro_db_version < 1.91) {
|
191 |
+
$pmpro_db_version = pmpro_upgrade_1_8_9_3();
|
192 |
}
|
193 |
|
194 |
/*
|
198 |
*/
|
199 |
if($pmpro_db_version < 1.92) {
|
200 |
pmpro_db_delta();
|
201 |
+
|
202 |
$pmpro_db_version = 1.92;
|
203 |
pmpro_setOption("db_version", "1.92");
|
204 |
}
|
210 |
*/
|
211 |
if($pmpro_db_version < 1.93) {
|
212 |
pmpro_db_delta();
|
213 |
+
|
214 |
$pmpro_db_version = 1.93;
|
215 |
pmpro_setOption("db_version", "1.93");
|
216 |
}
|
217 |
|
218 |
+
require_once( PMPRO_DIR . "/includes/updates/upgrade_1_9_4.php" );
|
219 |
if($pmpro_db_version < 1.94) {
|
220 |
$pmpro_db_version = pmpro_upgrade_1_9_4();
|
221 |
}
|
222 |
+
|
223 |
if($pmpro_db_version < 1.944) {
|
224 |
pmpro_cleanup_memberships_users_table();
|
225 |
$pmpro_db_version = '1.944';
|
232 |
$pmpro_db_version = 2.1;
|
233 |
pmpro_setOption( 'db_version', '2.1' );
|
234 |
}
|
235 |
+
|
236 |
if ( $pmpro_db_version < 2.3 ) {
|
237 |
pmpro_maybe_schedule_event( strtotime( '10:30:00' ) - ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ), 'daily', 'pmpro_cron_admin_activity_email' );
|
238 |
pmpro_setOption( 'db_version', '2.3' );
|
239 |
}
|
240 |
+
|
241 |
/**
|
242 |
* Version 2.4
|
243 |
* Fixing subscription_transaction_id
|
244 |
* for orders created through a Stripe Update.
|
245 |
*/
|
246 |
+
require_once( PMPRO_DIR . "/includes/updates/upgrade_2_4.php" );
|
247 |
if($pmpro_db_version < 2.4) {
|
248 |
$pmpro_db_version = pmpro_upgrade_2_4();
|
249 |
}
|
250 |
+
|
251 |
+
/**
|
252 |
+
* Version 2.5
|
253 |
+
* Running pmpro_db_delta to install the ordermeta table.
|
254 |
+
*/
|
255 |
+
if( $pmpro_db_version < 2.5 ) {
|
256 |
+
pmpro_db_delta();
|
257 |
+
$pmpro_db_version = 2.5;
|
258 |
+
pmpro_setOption( 'db_version', '2.5' );
|
259 |
+
}
|
260 |
+
|
261 |
+
/**
|
262 |
+
* Version 2.6
|
263 |
+
* Running pmpro_db_delta to update column types to bigint/etc
|
264 |
+
*/
|
265 |
+
require_once( PMPRO_DIR . "/includes/updates/upgrade_2_6.php" );
|
266 |
+
if( $pmpro_db_version < 2.6 ) {
|
267 |
+
pmpro_db_delta();
|
268 |
+
$pmpro_db_version = pmpro_upgrade_2_6();
|
269 |
+
pmpro_setOption( 'db_version', '2.6' );
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Version 2.7.1
|
274 |
+
* Running pmpro_db_delta to fix the primary key in a couple tables.
|
275 |
+
*/
|
276 |
+
if( $pmpro_db_version < 2.71 ) {
|
277 |
+
pmpro_db_delta();
|
278 |
+
pmpro_setOption( 'db_version', '2.71' );
|
279 |
+
}
|
280 |
}
|
281 |
|
282 |
function pmpro_db_delta()
|
294 |
$wpdb->pmpro_discount_codes_levels = $wpdb->prefix . 'pmpro_discount_codes_levels';
|
295 |
$wpdb->pmpro_discount_codes_uses = $wpdb->prefix . 'pmpro_discount_codes_uses';
|
296 |
$wpdb->pmpro_membership_levelmeta = $wpdb->prefix . 'pmpro_membership_levelmeta';
|
297 |
+
$wpdb->pmpro_membership_ordermeta = $wpdb->prefix . 'pmpro_membership_ordermeta';
|
298 |
|
299 |
//wp_pmpro_membership_levels
|
300 |
$sqlQuery = "
|
312 |
`trial_limit` int(11) NOT NULL DEFAULT '0',
|
313 |
`allow_signups` tinyint(4) NOT NULL DEFAULT '1',
|
314 |
`expiration_number` int(10) unsigned NOT NULL,
|
315 |
+
`expiration_period` enum('Hour','Day','Week','Month','Year') NOT NULL,
|
316 |
PRIMARY KEY (`id`),
|
317 |
KEY `allow_signups` (`allow_signups`),
|
318 |
KEY `initial_payment` (`initial_payment`),
|
324 |
//wp_pmpro_membership_orders
|
325 |
$sqlQuery = "
|
326 |
CREATE TABLE `" . $wpdb->pmpro_membership_orders . "` (
|
327 |
+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
328 |
`code` varchar(32) NOT NULL,
|
329 |
`session_id` varchar(64) NOT NULL DEFAULT '',
|
330 |
+
`user_id` bigint(20) unsigned NOT NULL DEFAULT '0',
|
331 |
`membership_id` int(11) unsigned NOT NULL DEFAULT '0',
|
332 |
`paypal_token` varchar(64) NOT NULL DEFAULT '',
|
333 |
`billing_name` varchar(128) NOT NULL DEFAULT '',
|
340 |
`subtotal` varchar(16) NOT NULL DEFAULT '',
|
341 |
`tax` varchar(16) NOT NULL DEFAULT '',
|
342 |
`couponamount` varchar(16) NOT NULL DEFAULT '',
|
343 |
+
`checkout_id` bigint(20) NOT NULL DEFAULT '0',
|
344 |
`certificate_id` int(11) NOT NULL DEFAULT '0',
|
345 |
`certificateamount` varchar(16) NOT NULL DEFAULT '',
|
346 |
`total` varchar(16) NOT NULL DEFAULT '',
|
380 |
$sqlQuery = "
|
381 |
CREATE TABLE `" . $wpdb->pmpro_memberships_categories . "` (
|
382 |
`membership_id` int(11) unsigned NOT NULL,
|
383 |
+
`category_id` bigint(20) unsigned NOT NULL,
|
384 |
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
385 |
+
PRIMARY KEY (`membership_id`,`category_id`),
|
386 |
UNIQUE KEY `category_membership` (`category_id`,`membership_id`)
|
387 |
);
|
388 |
";
|
392 |
$sqlQuery = "
|
393 |
CREATE TABLE `" . $wpdb->pmpro_memberships_pages . "` (
|
394 |
`membership_id` int(11) unsigned NOT NULL,
|
395 |
+
`page_id` bigint(20) unsigned NOT NULL,
|
396 |
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
397 |
+
PRIMARY KEY (`page_id`,`membership_id`),
|
398 |
UNIQUE KEY `membership_page` (`membership_id`,`page_id`)
|
399 |
);
|
400 |
";
|
404 |
$sqlQuery = "
|
405 |
CREATE TABLE `" . $wpdb->pmpro_memberships_users . "` (
|
406 |
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
407 |
+
`user_id` bigint(20) unsigned NOT NULL,
|
408 |
`membership_id` int(11) unsigned NOT NULL,
|
409 |
+
`code_id` bigint(20) unsigned NOT NULL,
|
410 |
`initial_payment` decimal(18,8) NOT NULL,
|
411 |
`billing_amount` decimal(18,8) NOT NULL,
|
412 |
`cycle_number` int(11) NOT NULL,
|
432 |
//wp_pmpro_discount_codes
|
433 |
$sqlQuery = "
|
434 |
CREATE TABLE `" . $wpdb->pmpro_discount_codes . "` (
|
435 |
+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
436 |
`code` varchar(32) NOT NULL,
|
437 |
`starts` date NOT NULL,
|
438 |
`expires` date NOT NULL,
|
448 |
//wp_pmpro_discount_codes_levels
|
449 |
$sqlQuery = "
|
450 |
CREATE TABLE `" . $wpdb->pmpro_discount_codes_levels . "` (
|
451 |
+
`code_id` bigint(20) unsigned NOT NULL,
|
452 |
`level_id` int(11) unsigned NOT NULL,
|
453 |
`initial_payment` decimal(18,8) NOT NULL DEFAULT '0.00',
|
454 |
`billing_amount` decimal(18,8) NOT NULL DEFAULT '0.00',
|
458 |
`trial_amount` decimal(18,8) NOT NULL DEFAULT '0.00',
|
459 |
`trial_limit` int(11) NOT NULL DEFAULT '0',
|
460 |
`expiration_number` int(10) unsigned NOT NULL,
|
461 |
+
`expiration_period` enum('Hour','Day','Week','Month','Year') NOT NULL,
|
462 |
PRIMARY KEY (`code_id`,`level_id`),
|
463 |
KEY `initial_payment` (`initial_payment`)
|
464 |
);
|
468 |
//wp_pmpro_discount_codes_uses
|
469 |
$sqlQuery = "
|
470 |
CREATE TABLE `" . $wpdb->pmpro_discount_codes_uses . "` (
|
471 |
+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
472 |
+
`code_id` bigint(20) unsigned NOT NULL,
|
473 |
+
`user_id` bigint(20) unsigned NOT NULL,
|
474 |
+
`order_id` bigint(20) unsigned NOT NULL,
|
475 |
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
476 |
PRIMARY KEY (`id`),
|
477 |
KEY `user_id` (`user_id`),
|
483 |
//pmpro_membership_levelmeta
|
484 |
$sqlQuery = "
|
485 |
CREATE TABLE `" . $wpdb->pmpro_membership_levelmeta . "` (
|
486 |
+
`meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
487 |
+
`pmpro_membership_level_id` int(11) unsigned NOT NULL,
|
488 |
`meta_key` varchar(255) NOT NULL,
|
489 |
`meta_value` longtext,
|
490 |
PRIMARY KEY (`meta_id`),
|
493 |
);
|
494 |
";
|
495 |
dbDelta($sqlQuery);
|
496 |
+
|
497 |
+
//pmpro_membership_ordermeta
|
498 |
+
$sqlQuery = "
|
499 |
+
CREATE TABLE `" . $wpdb->pmpro_membership_ordermeta . "` (
|
500 |
+
`meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
501 |
+
`pmpro_membership_order_id` int(11) unsigned NOT NULL,
|
502 |
+
`meta_key` varchar(255) NOT NULL,
|
503 |
+
`meta_value` longtext,
|
504 |
+
PRIMARY KEY (`meta_id`),
|
505 |
+
KEY `pmpro_membership_order_id` (`pmpro_membership_order_id`),
|
506 |
+
KEY `meta_key` (`meta_key`)
|
507 |
+
);
|
508 |
+
";
|
509 |
+
dbDelta($sqlQuery);
|
510 |
}
|
js/blocks.build.js
CHANGED
@@ -1 +1,1883 @@
|
|
1 |
-
!function(e){var t={};function r(c){if(t[c])return t[c].exports;var o=t[c]={i:c,l:!1,exports:{}};return e[c].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,c){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:c})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var c=Object.create(null);if(r.r(c),Object.defineProperty(c,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(c,o,function(t){return e[t]}.bind(null,o));return c},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=11)}([function(e,t){!function(){e.exports=this.wp.element}()},function(e,t){function r(t){return e.exports=r=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},r(t)}e.exports=r},function(e,t){e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},function(e,t){function r(e,t){for(var r=0;r<t.length;r++){var c=t[r];c.enumerable=c.enumerable||!1,c.configurable=!0,"value"in c&&(c.writable=!0),Object.defineProperty(e,c.key,c)}}e.exports=function(e,t,c){return t&&r(e.prototype,t),c&&r(e,c),e}},function(e,t,r){var c=r(8);e.exports=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&c(e,t)}},function(e,t,r){var c=r(9),o=r(10);e.exports=function(e,t){return!t||"object"!==c(t)&&"function"!=typeof t?o(e):t}},function(e,t){e.exports=function(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}},function(e,t){wp.i18n.setLocaleData({"":{}},"paid-memberships-pro")},function(e,t){function r(t,c){return e.exports=r=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},r(t,c)}e.exports=r},function(e,t){function r(t){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?e.exports=r=function(e){return typeof e}:e.exports=r=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(t)}e.exports=r},function(e,t){e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}},function(e,t,r){"use strict";r.r(t);var c=r(0),o=(r(7),r(6)),n=r.n(o),p=r(2),s=r.n(p),i=r(3),l=r.n(i),a=r(4),m=r.n(a),u=r(5),b=r.n(u),f=r(1),d=r.n(f);function h(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,c=d()(e);if(t){var o=d()(this).constructor;r=Reflect.construct(c,arguments,o)}else r=c.apply(this,arguments);return b()(this,r)}}var y=wp.i18n.__,v=wp.element.Component,g=wp.components,O=g.PanelBody,k=g.TextControl,j=g.SelectControl,w=wp.blockEditor.InspectorControls,C=function(e){m()(r,e);var t=h(r);function r(){return s()(this,r),t.apply(this,arguments)}return l()(r,[{key:"render",value:function(){var e=this.props,t=e.attributes,r=t.text,o=t.level,n=t.css_class,p=e.setAttributes;return Object(c.createElement)(w,null,Object(c.createElement)(O,null,Object(c.createElement)(k,{label:y("Button Text","paid-memberships-pro"),help:y("Text for checkout button","paid-memberships-pro"),value:r,onChange:function(e){return p({text:e})}})),Object(c.createElement)(O,null,Object(c.createElement)(j,{label:y("Level","paid-memberships-pro"),help:y("The level to link to for checkout button","paid-memberships-pro"),value:o,onChange:function(e){return p({level:e})},options:window.pmpro.all_level_values_and_labels})),Object(c.createElement)(O,null,Object(c.createElement)(k,{label:y("CSS Class","paid-memberships-pro"),help:y("Additional styling for checkout button","paid-memberships-pro"),value:n,onChange:function(e){return p({css_class:e})}})))}}]),r}(v);function E(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);t&&(c=c.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,c)}return r}function _(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?E(Object(r),!0).forEach((function(t){n()(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):E(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}var P=wp.i18n.__,M=wp.blocks.registerBlockType,N=wp.components,S=N.TextControl,x=N.SelectControl;M("pmpro/checkout-button",{title:P("Membership Checkout Button","paid-memberships-pro"),description:P("Displays a button-styled link to Membership Checkout for the specified level.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"migrate"},keywords:[P("pmpro","paid-memberships-pro"),P("buy","paid-memberships-pro"),P("level","paid-memberships-pro")],supports:{},attributes:{text:{type:"string",default:"Buy Now"},css_class:{type:"string",default:"pmpro_btn"},level:{type:"string"}},edit:function(e){var t=e.attributes,r=t.text,o=t.level,n=t.css_class,p=e.className,s=e.setAttributes,i=e.isSelected;return[i&&Object(c.createElement)(C,_({setAttributes:s},e)),Object(c.createElement)("div",{className:p},Object(c.createElement)("a",{class:n},r)),i&&Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)(S,{label:P("Button Text","paid-memberships-pro"),value:r,onChange:function(e){return s({text:e})}}),Object(c.createElement)(x,{label:P("Membership Level","paid-memberships-pro"),value:o,onChange:function(e){return s({level:e})},options:window.pmpro.all_level_values_and_labels}),Object(c.createElement)(S,{label:P("CSS Class","paid-memberships-pro"),value:n,onChange:function(e){return s({css_class:e})}}))]},save:function(){return null}});function D(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,c=d()(e);if(t){var o=d()(this).constructor;r=Reflect.construct(c,arguments,o)}else r=c.apply(this,arguments);return b()(this,r)}}var A=wp.i18n.__,B=wp.element.Component,L=wp.components,T=L.PanelBody,R=L.CheckboxControl,I=wp.blockEditor.InspectorControls,z=function(e){m()(r,e);var t=D(r);function r(){return s()(this,r),t.apply(this,arguments)}return l()(r,[{key:"render",value:function(){var e=this.props,t=e.attributes,r=t.membership,o=t.profile,n=t.invoices,p=t.links,s=e.setAttributes;return Object(c.createElement)(I,null,Object(c.createElement)(T,null,Object(c.createElement)(R,{label:A("Show 'My Memberships' Section","paid-memberships-pro"),checked:r,onChange:function(e){return s({membership:e})}})),Object(c.createElement)(T,null,Object(c.createElement)(R,{label:A("Show 'Profile' Section","paid-memberships-pro"),checked:o,onChange:function(e){return s({profile:e})}})),Object(c.createElement)(T,null,Object(c.createElement)(R,{label:A("Show 'Invoices' Section","paid-memberships-pro"),checked:n,onChange:function(e){return s({invoices:e})}})),Object(c.createElement)(T,null,Object(c.createElement)(R,{label:A("Show 'Member Links' Section","paid-memberships-pro"),checked:p,onChange:function(e){return s({links:e})}})))}}]),r}(B);function F(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);t&&(c=c.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,c)}return r}function q(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?F(Object(r),!0).forEach((function(t){n()(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):F(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}var W=wp.i18n.__,G=((0,wp.blocks.registerBlockType)("pmpro/account-page",{title:W("Membership Account Page","paid-memberships-pro"),description:W("Displays the sections of the Membership Account page as selected below.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"admin-users"},keywords:[W("pmpro","paid-memberships-pro")],supports:{},attributes:{membership:{type:"boolean",default:!1},profile:{type:"boolean",default:!1},invoices:{type:"boolean",default:!1},links:{type:"boolean",default:!1}},edit:function(e){var t=e.setAttributes;return[e.isSelected&&Object(c.createElement)(z,q({setAttributes:t},e)),Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},W("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"},W("Membership Account Page","paid-memberships-pro")))]},save:function(){return null}}),wp.i18n.__),H=((0,wp.blocks.registerBlockType)("pmpro/account-membership-section",{title:G("Membership Account: Memberships","paid-memberships-pro"),description:G("Displays the member's membership information.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"groups"},keywords:[G("pmpro","paid-memberships-pro")],supports:{},attributes:{},edit:function(){return[Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},G("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"},G("Membership Account: My Memberships","paid-memberships-pro")))]},save:function(){return null}}),wp.i18n.__),J=((0,wp.blocks.registerBlockType)("pmpro/account-profile-section",{title:H("Membership Account: Profile","paid-memberships-pro"),description:H("Displays the member's profile information.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"admin-users"},keywords:[H("pmpro","paid-memberships-pro")],supports:{},attributes:{},edit:function(){return[Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},H("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"},H("Membership Account: Profile","paid-memberships-pro")))]},save:function(){return null}}),wp.i18n.__),K=((0,wp.blocks.registerBlockType)("pmpro/account-invoices-section",{title:J("Membership Account: Invoices","paid-memberships-pro"),description:J("Displays the member's invoices.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"archive"},keywords:[J("pmpro","paid-memberships-pro")],supports:{},attributes:{},edit:function(){return[Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},J("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"}," ",J("Membership Account: Invoices","paid-memberships-pro")))]},save:function(){return null}}),wp.i18n.__),Q=((0,wp.blocks.registerBlockType)("pmpro/account-links-section",{title:K("Membership Account: Links","paid-memberships-pro"),description:K("Displays the member's member links. This block is only visible if other Add Ons or custom code have added links.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"external"},keywords:[K("pmpro","paid-memberships-pro")],supports:{},attributes:{},edit:function(){return[Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},K("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"},K("Membership Account: Member Links","paid-memberships-pro")))]},save:function(){return null}}),wp.i18n.__),U=((0,wp.blocks.registerBlockType)("pmpro/billing-page",{title:Q("Membership Billing Page","paid-memberships-pro"),description:Q("Displays the member's billing information and allows them to update the payment method.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"list-view"},keywords:[Q("pmpro","paid-memberships-pro")],supports:{},attributes:{},edit:function(){return[Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},Q("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"},Q("Membership Billing Page","paid-memberships-pro")))]},save:function(){return null}}),wp.i18n.__);(0,wp.blocks.registerBlockType)("pmpro/cancel-page",{title:U("Membership Cancel Page","paid-memberships-pro"),description:U("Generates the Membership Cancel page.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"no"},keywords:[U("pmpro","paid-memberships-pro")],supports:{},attributes:{},edit:function(){return[Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},U("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"},U("Membership Cancel Page","paid-memberships-pro")))]},save:function(){return null}});function V(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,c=d()(e);if(t){var o=d()(this).constructor;r=Reflect.construct(c,arguments,o)}else r=c.apply(this,arguments);return b()(this,r)}}var X=wp.i18n.__,Y=wp.element.Component,Z=wp.components,$=Z.PanelBody,ee=(Z.PanelRow,Z.SelectControl),te=wp.blockEditor.InspectorControls,re=function(e){m()(r,e);var t=V(r);function r(){return s()(this,r),t.apply(this,arguments)}return l()(r,[{key:"render",value:function(){var e=this.props,t=e.attributes.pmpro_default_level,r=e.setAttributes;return Object(c.createElement)(te,null,Object(c.createElement)($,null,Object(c.createElement)(ee,{label:X("Membership Level","paid-memberships-pro"),help:X("Choose a default level for Membership Checkout.","paid-memberships-pro"),value:t,onChange:function(e){return r({pmpro_default_level:e})},options:[""].concat(window.pmpro.all_level_values_and_labels)})))}}]),r}(Y);function ce(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);t&&(c=c.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,c)}return r}function oe(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?ce(Object(r),!0).forEach((function(t){n()(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):ce(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}var ne=wp.i18n.__,pe=wp.blocks.registerBlockType,se=wp.components.SelectControl,ie=(pe("pmpro/checkout-page",{title:ne("Membership Checkout Form","paid-memberships-pro"),description:ne("Displays the Membership Checkout form.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"list-view"},keywords:[ne("pmpro","paid-memberships-pro")],supports:{},attributes:{pmpro_default_level:{type:"string",source:"meta",meta:"pmpro_default_level"}},edit:function(e){var t=e.attributes.pmpro_default_level,r=(e.className,e.setAttributes);return[e.isSelected&&Object(c.createElement)(re,oe({setAttributes:r},e)),Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},ne("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"},ne("Membership Checkout Form","paid-memberships-pro")),Object(c.createElement)("hr",null),Object(c.createElement)(se,{label:ne("Membership Level","paid-memberships-pro"),value:t,onChange:function(e){return r({pmpro_default_level:e})},options:window.pmpro.all_level_values_and_labels}))]},save:function(){return null}}),wp.i18n.__),le=((0,wp.blocks.registerBlockType)("pmpro/confirmation-page",{title:ie("Membership Confirmation Page","paid-memberships-pro"),description:ie("Displays the member's Membership Confirmation after Membership Checkout.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"yes"},keywords:[ie("pmpro","paid-memberships-pro")],supports:{},attributes:{},edit:function(){return[Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},ie("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"},ie("Membership Confirmation Page","paid-memberships-pro")))]},save:function(){return null}}),wp.i18n.__),ae=((0,wp.blocks.registerBlockType)("pmpro/invoice-page",{title:le("Membership Invoice Page","paid-memberships-pro"),description:le("Displays the member's Membership Invoices.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"archive"},keywords:[le("pmpro","paid-memberships-pro")],supports:{},attributes:{},edit:function(){return[Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},le("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"},le("Membership Invoices","paid-memberships-pro")))]},save:function(){return null}}),wp.i18n.__),me=((0,wp.blocks.registerBlockType)("pmpro/levels-page",{title:ae("Membership Levels List","paid-memberships-pro"),description:ae("Displays a list of Membership Levels. To change the order, go to Memberships > Settings > Levels.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"list-view"},keywords:[ae("pmpro","paid-memberships-pro")],supports:{},attributes:{},edit:function(){return[Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},ae("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"},ae("Membership Levels List","paid-memberships-pro")))]},save:function(){return null}}),wp.i18n.__),ue=wp.blocks.registerBlockType,be=wp.components,fe=be.PanelBody,de=be.SelectControl,he=wp.blockEditor,ye=he.InspectorControls,ve=he.InnerBlocks,ge=[{value:0,label:"Non-Members"}].concat(pmpro.all_level_values_and_labels),Oe=(ue("pmpro/membership",{title:me("Require Membership Block","paid-memberships-pro"),description:me("Control the visibility of nested blocks for members or non-members.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"visibility"},keywords:[me("pmpro","paid-memberships-pro")],attributes:{levels:{type:"array",default:[]},uid:{type:"string",default:""}},edit:function(e){var t=e.attributes,r=t.levels,o=t.uid,n=e.setAttributes,p=e.isSelected;if(""==o){var s=Math.random()+"";n({uid:s})}return[p&&Object(c.createElement)(ye,null,Object(c.createElement)(fe,null,Object(c.createElement)(de,{multiple:!0,label:me("Select levels to show content to:","paid-memberships-pro"),value:r,onChange:function(e){n({levels:e})},options:ge}))),p&&Object(c.createElement)("div",{className:"pmpro-block-require-membership-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},me("Require Membership","paid-memberships-pro")),Object(c.createElement)(fe,null,Object(c.createElement)(de,{multiple:!0,label:me("Select levels to show content to:","paid-memberships-pro"),value:r,onChange:function(e){n({levels:e})},options:ge})),Object(c.createElement)(ve,{renderAppender:function(){return Object(c.createElement)(ve.ButtonBlockAppender,null)},templateLock:!1})),!p&&Object(c.createElement)("div",{className:"pmpro-block-require-membership-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},me("Require Membership","paid-memberships-pro")),Object(c.createElement)(ve,{renderAppender:function(){return Object(c.createElement)(ve.ButtonBlockAppender,null)},templateLock:!1}))]},save:function(e){var t=e.className;return Object(c.createElement)("div",{className:t},Object(c.createElement)(ve.Content,null))}}),wp.i18n.__);(0,wp.blocks.registerBlockType)("pmpro/member-profile-edit",{title:Oe("Member Profile Edit","paid-memberships-pro"),description:Oe("Allow member profile editing.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"admin-users"},keywords:[Oe("pmpro","paid-memberships-pro"),Oe("member","paid-memberships-pro"),Oe("profile","paid-memberships-pro")],edit:function(e){return Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},Oe("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"},Oe("Member Profile Edit","paid-memberships-pro")))},save:function(){return null}});function ke(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}();return function(){var r,c=d()(e);if(t){var o=d()(this).constructor;r=Reflect.construct(c,arguments,o)}else r=c.apply(this,arguments);return b()(this,r)}}var je,we=wp.i18n.__,Ce=wp.element.Component,Ee=wp.components,_e=Ee.PanelBody,Pe=(Ee.SelectControl,Ee.ToggleControl),Me=wp.blockEditor.InspectorControls,Ne=function(e){m()(r,e);var t=ke(r);function r(){return s()(this,r),t.apply(this,arguments)}return l()(r,[{key:"render",value:function(){var e=this,t=this.props,r=t.attributes,o=(t.setAttributes,r.display_if_logged_in),n=r.show_menu,p=r.show_logout_link;r.location;return Object(c.createElement)(Me,null,Object(c.createElement)(_e,null,Object(c.createElement)(Pe,{label:we("Display 'Welcome' content when logged in.","paid-memberships-pro"),checked:o,onChange:function(t){e.props.setAttributes({display_if_logged_in:t})}}),Object(c.createElement)(Pe,{label:we("Display the 'Log In Widget' menu.","paid-memberships-pro"),help:we("Assign the menu under Appearance > Menus."),checked:n,onChange:function(t){e.props.setAttributes({show_menu:t})}}),Object(c.createElement)(Pe,{label:we("Display a 'Log Out' link.","paid-memberships-pro"),checked:p,onChange:function(t){e.props.setAttributes({show_logout_link:t})}})))}}]),r}(Ce),Se=wp.i18n.__,xe=wp.blocks.registerBlockType,De=wp.element.Fragment;xe("pmpro/login-form",{title:Se("Log in Form","paid-memberships-pro"),description:Se("Displays a Log In Form for Paid Memberships Pro.","paid-memberships-pro"),category:"pmpro",icon:{background:"#2997c8",foreground:"#ffffff",src:"unlock"},keywords:[Se("pmpro","paid-memberships-pro"),Se("login","paid-memberships-pro"),Se("form","paid-memberships-pro"),Se("log in","paid-memberships-pro")],supports:{},edit:function(e){return[Object(c.createElement)(De,null,Object(c.createElement)(Ne,e),Object(c.createElement)("div",{className:"pmpro-block-element"},Object(c.createElement)("span",{className:"pmpro-block-title"},Se("Paid Memberships Pro","paid-memberships-pro")),Object(c.createElement)("span",{className:"pmpro-block-subtitle"},Se("Log in Form","paid-memberships-pro"))))]},save:function(){return null}});je=Object(c.createElement)("svg",{version:"1.1",id:"Layer_1",x:"0px",y:"0px",viewBox:"0 0 18 18"},Object(c.createElement)("path",{d:"M17.99,4.53c-0.35,0.12-0.7,0.26-1.06,0.4c-0.35,0.14-0.7,0.3-1.05,0.46c-0.35,0.16-0.69,0.33-1.03,0.51 c-0.34,0.18-0.68,0.37-1.02,0.56c-0.15,0.09-0.31,0.18-0.46,0.27c-0.15,0.09-0.3,0.19-0.45,0.28c-0.15,0.1-0.3,0.19-0.45,0.29 c-0.15,0.1-0.3,0.2-0.44,0.3c-0.08,0.05-0.16,0.11-0.23,0.16c-0.08,0.05-0.16,0.11-0.23,0.17c-0.08,0.06-0.15,0.11-0.23,0.17 c-0.08,0.06-0.15,0.11-0.23,0.17c-0.07,0.05-0.13,0.1-0.2,0.15c-0.07,0.05-0.13,0.1-0.2,0.15c-0.07,0.05-0.13,0.1-0.2,0.15 c-0.07,0.05-0.13,0.1-0.2,0.16c-0.04,0.03-0.09,0.07-0.13,0.1c-0.04,0.03-0.09,0.07-0.13,0.1C10,9.13,9.95,9.17,9.91,9.2 C9.87,9.24,9.83,9.27,9.79,9.31C9.77,9.32,9.75,9.33,9.74,9.35C9.72,9.36,9.71,9.37,9.69,9.39C9.67,9.4,9.66,9.42,9.64,9.43 C9.63,9.44,9.61,9.46,9.59,9.47C9.54,9.52,9.49,9.56,9.43,9.61C9.38,9.65,9.33,9.7,9.27,9.74C9.22,9.79,9.17,9.84,9.11,9.88 c-0.05,0.05-0.11,0.09-0.16,0.14c-0.27,0.24-0.54,0.49-0.81,0.75c-0.26,0.25-0.53,0.51-0.78,0.78c-0.26,0.26-0.51,0.53-0.76,0.81 c-0.25,0.27-0.49,0.55-0.73,0.84c-0.03,0.04-0.07,0.08-0.1,0.12c-0.03,0.04-0.07,0.08-0.1,0.12c-0.03,0.04-0.07,0.08-0.1,0.12 c-0.03,0.04-0.07,0.08-0.1,0.12c-0.03,0.04-0.07,0.08-0.1,0.12c-0.03,0.04-0.06,0.08-0.1,0.12c-0.03,0.04-0.06,0.08-0.1,0.12 c-0.03,0.04-0.06,0.08-0.1,0.12c0,0.01-0.01,0.01-0.01,0.02c0,0.01-0.01,0.01-0.01,0.02c0,0.01-0.01,0.01-0.01,0.02 c0,0.01-0.01,0.01-0.01,0.02c-0.03,0.03-0.05,0.07-0.08,0.1c-0.03,0.03-0.05,0.07-0.08,0.1c-0.03,0.03-0.05,0.07-0.08,0.11 c-0.03,0.03-0.05,0.07-0.08,0.11c-0.03,0.04-0.06,0.08-0.09,0.12c-0.03,0.04-0.06,0.08-0.09,0.12C4.5,14.96,4.47,15,4.44,15.05 c-0.03,0.04-0.06,0.08-0.09,0.13c0,0-0.01,0.01-0.01,0.01c0,0-0.01,0.01-0.01,0.01c0,0-0.01,0.01-0.01,0.01c0,0-0.01,0.01-0.01,0.01 c-0.15,0.22-0.31,0.44-0.46,0.67c-0.15,0.22-0.3,0.45-0.44,0.68c-0.14,0.23-0.29,0.46-0.43,0.7C2.85,17.52,2.71,17.76,2.58,18 c-0.08-0.19-0.16-0.38-0.23-0.56c-0.07-0.18-0.14-0.35-0.21-0.51c-0.07-0.16-0.13-0.32-0.19-0.47c-0.06-0.15-0.12-0.3-0.18-0.45 l-0.01,0.01l0.01-0.03c-0.01-0.03-0.02-0.05-0.03-0.08c-0.01-0.02-0.02-0.05-0.03-0.07c-0.01-0.02-0.02-0.05-0.03-0.07 c-0.01-0.02-0.02-0.05-0.03-0.07c0-0.01-0.01-0.02-0.01-0.02c0-0.01-0.01-0.02-0.01-0.02c0-0.01-0.01-0.02-0.01-0.02 c0-0.01-0.01-0.02-0.01-0.02c-0.01-0.02-0.01-0.04-0.02-0.05c-0.01-0.02-0.01-0.04-0.02-0.05c-0.01-0.02-0.01-0.04-0.02-0.05 c-0.01-0.02-0.01-0.04-0.02-0.05c-0.01-0.03-0.02-0.05-0.03-0.07c-0.01-0.02-0.02-0.05-0.03-0.07c-0.01-0.02-0.02-0.05-0.03-0.07 c-0.01-0.02-0.02-0.05-0.03-0.07c-0.01-0.02-0.02-0.05-0.03-0.07c-0.01-0.02-0.02-0.05-0.03-0.07c-0.01-0.02-0.02-0.05-0.03-0.07 c-0.01-0.02-0.02-0.05-0.03-0.07c-0.02-0.05-0.04-0.1-0.06-0.16c-0.02-0.05-0.04-0.1-0.06-0.16c-0.02-0.05-0.04-0.11-0.06-0.16 c-0.02-0.05-0.04-0.11-0.06-0.16c-0.08-0.23-0.16-0.47-0.25-0.72c-0.08-0.25-0.17-0.5-0.26-0.77c-0.09-0.27-0.18-0.55-0.27-0.84 c-0.09-0.29-0.19-0.6-0.29-0.93c0.05,0.07,0.1,0.15,0.15,0.22c0.05,0.07,0.1,0.14,0.14,0.2c0.05,0.07,0.09,0.13,0.14,0.19 c0.04,0.06,0.09,0.12,0.13,0.18c0.09,0.13,0.18,0.24,0.27,0.35c0.09,0.11,0.17,0.21,0.24,0.3c0.08,0.09,0.15,0.18,0.23,0.27 c0.07,0.09,0.15,0.17,0.22,0.25c0.02,0.02,0.03,0.04,0.05,0.06c0.02,0.02,0.03,0.04,0.05,0.06c0.02,0.02,0.03,0.04,0.05,0.06 c0.02,0.02,0.03,0.04,0.05,0.06c0.07,0.07,0.13,0.14,0.2,0.22c0.07,0.08,0.14,0.16,0.22,0.24c0.08,0.08,0.16,0.17,0.24,0.27 c0.09,0.1,0.18,0.2,0.27,0.31c0.01,0.01,0.02,0.02,0.03,0.03c0.01,0.01,0.02,0.02,0.03,0.03c0.01,0.01,0.02,0.02,0.03,0.04 c0.01,0.01,0.02,0.02,0.03,0.04c0.02-0.02,0.04-0.05,0.06-0.07c0.02-0.02,0.04-0.05,0.06-0.07c0.02-0.02,0.04-0.05,0.06-0.07 C2.96,14.03,2.98,14,3,13.98c0.03-0.03,0.05-0.06,0.08-0.09c0.03-0.03,0.05-0.06,0.08-0.09c0.03-0.03,0.05-0.06,0.08-0.09 c0.03-0.03,0.05-0.06,0.08-0.09c0.28-0.33,0.58-0.65,0.88-0.97c0.31-0.32,0.63-0.62,0.95-0.92c0.33-0.3,0.67-0.6,1.02-0.88 c0.35-0.29,0.72-0.57,1.09-0.84c0.06-0.04,0.11-0.08,0.17-0.12C7.49,9.83,7.55,9.79,7.6,9.75c0.06-0.04,0.11-0.08,0.17-0.12 c0.06-0.04,0.12-0.08,0.17-0.12C7.97,9.5,7.98,9.49,8,9.48c0.02-0.01,0.03-0.02,0.05-0.03C8.06,9.43,8.08,9.42,8.1,9.41 C8.11,9.4,8.13,9.38,8.14,9.37c0.05-0.03,0.1-0.06,0.14-0.1c0.05-0.03,0.1-0.06,0.14-0.1c0.05-0.03,0.1-0.06,0.14-0.1 c0.05-0.03,0.1-0.06,0.15-0.09C8.79,8.94,8.87,8.9,8.94,8.85C9.01,8.8,9.09,8.76,9.16,8.71c0.07-0.05,0.15-0.09,0.22-0.14 c0.07-0.05,0.15-0.09,0.22-0.14c0.09-0.05,0.17-0.11,0.26-0.16c0.09-0.05,0.17-0.1,0.26-0.16c0.09-0.05,0.18-0.1,0.27-0.15 c0.09-0.05,0.18-0.1,0.27-0.15c0.25-0.14,0.51-0.28,0.76-0.42c0.26-0.14,0.52-0.27,0.78-0.41c0.26-0.13,0.53-0.27,0.79-0.4 c0.27-0.13,0.54-0.26,0.81-0.38c0.01,0,0.02-0.01,0.03-0.01c0.01,0,0.02-0.01,0.03-0.01c0.01,0,0.02-0.01,0.03-0.01 c0.01,0,0.02-0.01,0.03-0.01c0.33-0.15,0.67-0.3,1-0.44c0.34-0.15,0.68-0.29,1.02-0.42c0.34-0.14,0.69-0.27,1.03-0.4 C17.31,4.77,17.65,4.64,17.99,4.53z M15.73,9.59l0.65,4.56l-10.4-0.05c-0.02,0.02-0.04,0.04-0.05,0.07 c-0.02,0.02-0.04,0.04-0.05,0.07c-0.02,0.02-0.04,0.04-0.05,0.07c-0.02,0.02-0.04,0.04-0.05,0.07c-0.02,0.02-0.03,0.04-0.05,0.06 c-0.02,0.02-0.03,0.04-0.05,0.06c-0.02,0.02-0.03,0.04-0.05,0.06c-0.02,0.02-0.03,0.04-0.05,0.06l11.23,0.2l-0.78-5.24L15.73,9.59z M6.75,13.2c-0.04,0.04-0.08,0.09-0.11,0.13c-0.04,0.04-0.08,0.09-0.11,0.13c-0.04,0.04-0.07,0.09-0.11,0.13l9.22-0.07L15.04,9.1 l-0.07-0.53l-0.39,0.04l0.55,4.3l-8.27,0.17C6.83,13.12,6.79,13.16,6.75,13.2z M13.78,7.66l-0.59,0.08 c-0.06,0.04-0.12,0.08-0.18,0.12c-0.06,0.04-0.12,0.08-0.18,0.12c-0.06,0.04-0.12,0.08-0.18,0.12c-0.06,0.04-0.12,0.08-0.18,0.12 c-0.08,0.05-0.16,0.11-0.24,0.16c-0.08,0.06-0.16,0.11-0.24,0.17c-0.08,0.06-0.16,0.11-0.24,0.17c-0.08,0.06-0.16,0.11-0.24,0.17 c-0.07,0.05-0.14,0.1-0.21,0.15c-0.07,0.05-0.14,0.1-0.21,0.15c-0.07,0.05-0.14,0.1-0.2,0.16c-0.07,0.05-0.14,0.11-0.2,0.16 c-0.04,0.03-0.09,0.07-0.13,0.1c-0.04,0.03-0.09,0.07-0.13,0.1c-0.04,0.04-0.09,0.07-0.13,0.11c-0.04,0.04-0.09,0.07-0.13,0.11 c-0.02,0.01-0.03,0.03-0.05,0.04c-0.02,0.01-0.03,0.03-0.05,0.04c-0.02,0.01-0.03,0.03-0.05,0.04c-0.02,0.01-0.03,0.03-0.05,0.04 c-0.06,0.05-0.11,0.09-0.16,0.14c-0.05,0.05-0.11,0.09-0.16,0.14c-0.05,0.05-0.11,0.09-0.16,0.14c-0.05,0.05-0.11,0.09-0.16,0.14 c-0.17,0.15-0.34,0.3-0.51,0.46c-0.17,0.16-0.33,0.31-0.5,0.47c-0.16,0.16-0.33,0.32-0.49,0.48c-0.16,0.16-0.32,0.33-0.48,0.49 l6.98-0.23l-0.48-4.16L13.78,7.66z M13.32,5.73c-0.06,0.03-0.11,0.05-0.17,0.08c-0.06,0.03-0.12,0.06-0.17,0.09 c-0.03,0.01-0.06,0.03-0.08,0.04c0,0,0,0,0,0c-0.02-0.01-0.04-0.03-0.06-0.04c-0.06-0.04-0.13-0.07-0.21-0.09 c-0.07-0.02-0.15-0.04-0.23-0.04c-0.08,0-0.16,0-0.24,0.01l-0.14,0.02c0.07-0.04,0.13-0.08,0.18-0.14c0.05-0.05,0.1-0.11,0.14-0.18 c0.04-0.06,0.06-0.13,0.08-0.2c0.02-0.07,0.02-0.15,0.01-0.22c-0.01-0.1-0.04-0.18-0.08-0.26c-0.05-0.08-0.11-0.14-0.18-0.19 c-0.07-0.05-0.16-0.08-0.25-0.1c-0.09-0.02-0.19-0.02-0.29,0c-0.1,0.02-0.19,0.06-0.27,0.11c-0.08,0.05-0.15,0.11-0.21,0.19 C11.08,4.9,11.03,4.98,11,5.07c-0.03,0.09-0.04,0.18-0.03,0.27c0.01,0.07,0.02,0.14,0.05,0.2c0.03,0.06,0.06,0.12,0.11,0.17 c0.05,0.05,0.1,0.09,0.16,0.12c0.06,0.03,0.13,0.06,0.2,0.07l-0.17,0.03C11.18,5.96,11.06,6,10.94,6.07 c-0.11,0.07-0.21,0.15-0.29,0.25c-0.08,0.1-0.14,0.21-0.19,0.33c-0.04,0.12-0.06,0.25-0.05,0.38l0.02,0.33 c-0.09,0.05-0.17,0.1-0.26,0.16c-0.02,0-0.05,0-0.07,0c0.02-0.01,0.04-0.02,0.06-0.03c-0.06-0.06-0.13-0.11-0.21-0.16 c-0.07-0.04-0.15-0.08-0.24-0.1C9.63,7.2,9.54,7.18,9.45,7.18c-0.09-0.01-0.18,0-0.27,0.01L9.01,7.21c0.08-0.05,0.16-0.1,0.23-0.17 C9.3,6.97,9.36,6.9,9.41,6.81C9.46,6.73,9.5,6.64,9.52,6.55c0.02-0.09,0.03-0.19,0.03-0.29C9.54,6.13,9.51,6.02,9.46,5.92 c-0.05-0.1-0.12-0.18-0.21-0.25C9.17,5.6,9.07,5.56,8.96,5.53c-0.11-0.02-0.22-0.03-0.34,0C8.5,5.55,8.39,5.6,8.29,5.66 C8.19,5.72,8.1,5.81,8.02,5.9C7.95,5.99,7.89,6.1,7.85,6.21C7.81,6.32,7.79,6.44,7.79,6.56c0,0.09,0.02,0.18,0.05,0.26 c0.03,0.08,0.07,0.16,0.12,0.22c0.05,0.07,0.11,0.12,0.18,0.17c0.07,0.04,0.15,0.08,0.23,0.1l-0.2,0.03 C8.01,7.37,7.85,7.42,7.72,7.51C7.58,7.59,7.46,7.7,7.35,7.82C7.25,7.95,7.17,8.1,7.11,8.25c-0.06,0.16-0.09,0.33-0.08,0.5 l0.01,0.74C6.98,9.53,6.93,9.58,6.88,9.62C6.81,9.49,6.74,9.38,6.65,9.28c-0.1-0.11-0.21-0.2-0.33-0.27 C6.2,8.94,6.07,8.89,5.93,8.87C5.8,8.84,5.66,8.83,5.51,8.85L5.3,8.88c0.1-0.06,0.2-0.13,0.29-0.22c0.09-0.09,0.16-0.19,0.23-0.3 c0.06-0.11,0.12-0.23,0.15-0.35C6,7.88,6.02,7.75,6.02,7.62c0-0.17-0.03-0.32-0.08-0.46C5.88,7.03,5.8,6.91,5.71,6.82 C5.61,6.73,5.5,6.67,5.37,6.63c-0.12-0.04-0.26-0.04-0.4-0.02c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0 c-0.14,0.03-0.28,0.08-0.4,0.16c-0.12,0.08-0.23,0.18-0.33,0.3C4.14,7.2,4.07,7.33,4.01,7.48c-0.06,0.15-0.09,0.3-0.1,0.46 c0,0.12,0.01,0.24,0.03,0.35c0.03,0.11,0.07,0.21,0.12,0.3c0.05,0.09,0.12,0.17,0.2,0.23c0.08,0.06,0.17,0.11,0.27,0.14L4.3,9 C4.1,9.03,3.92,9.09,3.75,9.2C3.58,9.3,3.43,9.44,3.3,9.6c-0.13,0.16-0.24,0.35-0.32,0.56c-0.08,0.21-0.13,0.43-0.14,0.67 l-0.12,2.26l-0.53-0.6l0.49-6.3C2.68,6.09,2.71,6,2.74,5.91c0.04-0.09,0.08-0.17,0.14-0.24c0.06-0.07,0.12-0.14,0.2-0.19 C3.15,5.44,3.23,5.4,3.32,5.38l0.71-0.17l0-0.02l0.18-0.04l0.06-1.19C4.3,3.56,4.39,3.15,4.55,2.77c0.16-0.38,0.37-0.75,0.64-1.08 C5.45,1.35,5.76,1.05,6.11,0.8c0.35-0.26,0.74-0.47,1.16-0.61C7.7,0.05,8.12-0.01,8.51,0c0.4,0.02,0.77,0.12,1.1,0.29 c0.33,0.18,0.62,0.43,0.83,0.75c0.21,0.33,0.35,0.73,0.38,1.19l0.1,1.36l0.3-0.07l0,0.02l0.89-0.21c0.13-0.03,0.25-0.03,0.36-0.02 c0.12,0.02,0.22,0.05,0.32,0.11c0.09,0.05,0.17,0.13,0.23,0.21c0.06,0.09,0.1,0.19,0.11,0.31L13.32,5.73z M9.46,3.96L9.4,2.61 C9.39,2.33,9.31,2.09,9.19,1.88C9.07,1.68,8.91,1.51,8.71,1.4C8.52,1.28,8.29,1.21,8.05,1.19C7.81,1.17,7.55,1.2,7.28,1.28 C7.01,1.37,6.76,1.49,6.53,1.65c-0.22,0.16-0.43,0.35-0.6,0.57C5.77,2.43,5.63,2.67,5.53,2.91c-0.1,0.25-0.16,0.5-0.17,0.76 L5.33,4.91L9.46,3.96z"})),wp.blocks.updateCategory("pmpro",{icon:je})}]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/******/ (function(modules) { // webpackBootstrap
|
2 |
+
/******/ // The module cache
|
3 |
+
/******/ var installedModules = {};
|
4 |
+
/******/
|
5 |
+
/******/ // The require function
|
6 |
+
/******/ function __webpack_require__(moduleId) {
|
7 |
+
/******/
|
8 |
+
/******/ // Check if module is in cache
|
9 |
+
/******/ if(installedModules[moduleId]) {
|
10 |
+
/******/ return installedModules[moduleId].exports;
|
11 |
+
/******/ }
|
12 |
+
/******/ // Create a new module (and put it into the cache)
|
13 |
+
/******/ var module = installedModules[moduleId] = {
|
14 |
+
/******/ i: moduleId,
|
15 |
+
/******/ l: false,
|
16 |
+
/******/ exports: {}
|
17 |
+
/******/ };
|
18 |
+
/******/
|
19 |
+
/******/ // Execute the module function
|
20 |
+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
21 |
+
/******/
|
22 |
+
/******/ // Flag the module as loaded
|
23 |
+
/******/ module.l = true;
|
24 |
+
/******/
|
25 |
+
/******/ // Return the exports of the module
|
26 |
+
/******/ return module.exports;
|
27 |
+
/******/ }
|
28 |
+
/******/
|
29 |
+
/******/
|
30 |
+
/******/ // expose the modules object (__webpack_modules__)
|
31 |
+
/******/ __webpack_require__.m = modules;
|
32 |
+
/******/
|
33 |
+
/******/ // expose the module cache
|
34 |
+
/******/ __webpack_require__.c = installedModules;
|
35 |
+
/******/
|
36 |
+
/******/ // define getter function for harmony exports
|
37 |
+
/******/ __webpack_require__.d = function(exports, name, getter) {
|
38 |
+
/******/ if(!__webpack_require__.o(exports, name)) {
|
39 |
+
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
40 |
+
/******/ }
|
41 |
+
/******/ };
|
42 |
+
/******/
|
43 |
+
/******/ // define __esModule on exports
|
44 |
+
/******/ __webpack_require__.r = function(exports) {
|
45 |
+
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
46 |
+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
47 |
+
/******/ }
|
48 |
+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
49 |
+
/******/ };
|
50 |
+
/******/
|
51 |
+
/******/ // create a fake namespace object
|
52 |
+
/******/ // mode & 1: value is a module id, require it
|
53 |
+
/******/ // mode & 2: merge all properties of value into the ns
|
54 |
+
/******/ // mode & 4: return value when already ns object
|
55 |
+
/******/ // mode & 8|1: behave like require
|
56 |
+
/******/ __webpack_require__.t = function(value, mode) {
|
57 |
+
/******/ if(mode & 1) value = __webpack_require__(value);
|
58 |
+
/******/ if(mode & 8) return value;
|
59 |
+
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
60 |
+
/******/ var ns = Object.create(null);
|
61 |
+
/******/ __webpack_require__.r(ns);
|
62 |
+
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
63 |
+
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
64 |
+
/******/ return ns;
|
65 |
+
/******/ };
|
66 |
+
/******/
|
67 |
+
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
68 |
+
/******/ __webpack_require__.n = function(module) {
|
69 |
+
/******/ var getter = module && module.__esModule ?
|
70 |
+
/******/ function getDefault() { return module['default']; } :
|
71 |
+
/******/ function getModuleExports() { return module; };
|
72 |
+
/******/ __webpack_require__.d(getter, 'a', getter);
|
73 |
+
/******/ return getter;
|
74 |
+
/******/ };
|
75 |
+
/******/
|
76 |
+
/******/ // Object.prototype.hasOwnProperty.call
|
77 |
+
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
78 |
+
/******/
|
79 |
+
/******/ // __webpack_public_path__
|
80 |
+
/******/ __webpack_require__.p = "";
|
81 |
+
/******/
|
82 |
+
/******/
|
83 |
+
/******/ // Load entry module and return exports
|
84 |
+
/******/ return __webpack_require__(__webpack_require__.s = "./blocks/blocks.js");
|
85 |
+
/******/ })
|
86 |
+
/************************************************************************/
|
87 |
+
/******/ ({
|
88 |
+
|
89 |
+
/***/ "./blocks/account-invoices-section/block.js":
|
90 |
+
/*!**************************************************!*\
|
91 |
+
!*** ./blocks/account-invoices-section/block.js ***!
|
92 |
+
\**************************************************/
|
93 |
+
/*! exports provided: default */
|
94 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
95 |
+
|
96 |
+
"use strict";
|
97 |
+
__webpack_require__.r(__webpack_exports__);
|
98 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
99 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
100 |
+
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Block: PMPro Membership Account: Invoices
|
104 |
+
*
|
105 |
+
* Displays the Membership Account > Invoices page section.
|
106 |
+
*
|
107 |
+
*/
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Internal block libraries
|
111 |
+
*/
|
112 |
+
var __ = wp.i18n.__;
|
113 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
114 |
+
/**
|
115 |
+
* Register block
|
116 |
+
*/
|
117 |
+
|
118 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/account-invoices-section', {
|
119 |
+
title: __('Membership Account: Invoices', 'paid-memberships-pro'),
|
120 |
+
description: __('Displays the member\'s invoices.', 'paid-memberships-pro'),
|
121 |
+
category: 'pmpro',
|
122 |
+
icon: {
|
123 |
+
background: '#2997c8',
|
124 |
+
foreground: '#ffffff',
|
125 |
+
src: 'archive'
|
126 |
+
},
|
127 |
+
keywords: [__('pmpro', 'paid-memberships-pro')],
|
128 |
+
supports: {},
|
129 |
+
attributes: {},
|
130 |
+
edit: function edit() {
|
131 |
+
return [Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
132 |
+
className: "pmpro-block-element"
|
133 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
134 |
+
className: "pmpro-block-title"
|
135 |
+
}, __('Paid Memberships Pro', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
136 |
+
className: "pmpro-block-subtitle"
|
137 |
+
}, " ", __('Membership Account: Invoices', 'paid-memberships-pro')))];
|
138 |
+
},
|
139 |
+
save: function save() {
|
140 |
+
return null;
|
141 |
+
}
|
142 |
+
}));
|
143 |
+
|
144 |
+
/***/ }),
|
145 |
+
|
146 |
+
/***/ "./blocks/account-links-section/block.js":
|
147 |
+
/*!***********************************************!*\
|
148 |
+
!*** ./blocks/account-links-section/block.js ***!
|
149 |
+
\***********************************************/
|
150 |
+
/*! exports provided: default */
|
151 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
152 |
+
|
153 |
+
"use strict";
|
154 |
+
__webpack_require__.r(__webpack_exports__);
|
155 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
156 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
157 |
+
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Block: PMPro Membership Account: Member Links
|
161 |
+
*
|
162 |
+
* Displays the Membership Account > Member Links page section.
|
163 |
+
*
|
164 |
+
*/
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Internal block libraries
|
168 |
+
*/
|
169 |
+
var __ = wp.i18n.__;
|
170 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
171 |
+
/**
|
172 |
+
* Register block
|
173 |
+
*/
|
174 |
+
|
175 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/account-links-section', {
|
176 |
+
title: __('Membership Account: Links', 'paid-memberships-pro'),
|
177 |
+
description: __('Displays the member\'s member links. This block is only visible if other Add Ons or custom code have added links.', 'paid-memberships-pro'),
|
178 |
+
category: 'pmpro',
|
179 |
+
icon: {
|
180 |
+
background: '#2997c8',
|
181 |
+
foreground: '#ffffff',
|
182 |
+
src: 'external'
|
183 |
+
},
|
184 |
+
keywords: [__('pmpro', 'paid-memberships-pro')],
|
185 |
+
supports: {},
|
186 |
+
attributes: {},
|
187 |
+
edit: function edit() {
|
188 |
+
return [Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
189 |
+
className: "pmpro-block-element"
|
190 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
191 |
+
className: "pmpro-block-title"
|
192 |
+
}, __('Paid Memberships Pro', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
193 |
+
className: "pmpro-block-subtitle"
|
194 |
+
}, __('Membership Account: Member Links', 'paid-memberships-pro')))];
|
195 |
+
},
|
196 |
+
save: function save() {
|
197 |
+
return null;
|
198 |
+
}
|
199 |
+
}));
|
200 |
+
|
201 |
+
/***/ }),
|
202 |
+
|
203 |
+
/***/ "./blocks/account-membership-section/block.js":
|
204 |
+
/*!****************************************************!*\
|
205 |
+
!*** ./blocks/account-membership-section/block.js ***!
|
206 |
+
\****************************************************/
|
207 |
+
/*! exports provided: default */
|
208 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
209 |
+
|
210 |
+
"use strict";
|
211 |
+
__webpack_require__.r(__webpack_exports__);
|
212 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
213 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
214 |
+
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Block: PMPro Membership Account: Memberships
|
218 |
+
*
|
219 |
+
* Displays the Membership Account > My Memberships page section.
|
220 |
+
*
|
221 |
+
*/
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Internal block libraries
|
225 |
+
*/
|
226 |
+
var __ = wp.i18n.__;
|
227 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
228 |
+
/**
|
229 |
+
* Register block
|
230 |
+
*/
|
231 |
+
|
232 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/account-membership-section', {
|
233 |
+
title: __('Membership Account: Memberships', 'paid-memberships-pro'),
|
234 |
+
description: __('Displays the member\'s membership information.', 'paid-memberships-pro'),
|
235 |
+
category: 'pmpro',
|
236 |
+
icon: {
|
237 |
+
background: '#2997c8',
|
238 |
+
foreground: '#ffffff',
|
239 |
+
src: 'groups'
|
240 |
+
},
|
241 |
+
keywords: [__('pmpro', 'paid-memberships-pro')],
|
242 |
+
supports: {},
|
243 |
+
attributes: {},
|
244 |
+
edit: function edit() {
|
245 |
+
return [Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
246 |
+
className: "pmpro-block-element"
|
247 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
248 |
+
className: "pmpro-block-title"
|
249 |
+
}, __('Paid Memberships Pro', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
250 |
+
className: "pmpro-block-subtitle"
|
251 |
+
}, __('Membership Account: My Memberships', 'paid-memberships-pro')))];
|
252 |
+
},
|
253 |
+
save: function save() {
|
254 |
+
return null;
|
255 |
+
}
|
256 |
+
}));
|
257 |
+
|
258 |
+
/***/ }),
|
259 |
+
|
260 |
+
/***/ "./blocks/account-page/block.js":
|
261 |
+
/*!**************************************!*\
|
262 |
+
!*** ./blocks/account-page/block.js ***!
|
263 |
+
\**************************************/
|
264 |
+
/*! exports provided: default */
|
265 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
266 |
+
|
267 |
+
"use strict";
|
268 |
+
__webpack_require__.r(__webpack_exports__);
|
269 |
+
/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "./node_modules/@babel/runtime/helpers/defineProperty.js");
|
270 |
+
/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__);
|
271 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
272 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__);
|
273 |
+
/* harmony import */ var _inspector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./inspector */ "./blocks/account-page/inspector.js");
|
274 |
+
|
275 |
+
|
276 |
+
|
277 |
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
278 |
+
|
279 |
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default()(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
280 |
+
|
281 |
+
/**
|
282 |
+
* Block: PMPro Membership Account
|
283 |
+
*
|
284 |
+
* Displays the Membership Account page.
|
285 |
+
*
|
286 |
+
*/
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Block dependencies
|
290 |
+
*/
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Internal block libraries
|
294 |
+
*/
|
295 |
+
|
296 |
+
var __ = wp.i18n.__;
|
297 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
298 |
+
/**
|
299 |
+
* Register block
|
300 |
+
*/
|
301 |
+
|
302 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/account-page', {
|
303 |
+
title: __('Membership Account Page', 'paid-memberships-pro'),
|
304 |
+
description: __('Displays the sections of the Membership Account page as selected below.', 'paid-memberships-pro'),
|
305 |
+
category: 'pmpro',
|
306 |
+
icon: {
|
307 |
+
background: '#2997c8',
|
308 |
+
foreground: '#ffffff',
|
309 |
+
src: 'admin-users'
|
310 |
+
},
|
311 |
+
keywords: [__('pmpro', 'paid-memberships-pro')],
|
312 |
+
supports: {},
|
313 |
+
attributes: {
|
314 |
+
membership: {
|
315 |
+
type: 'boolean',
|
316 |
+
default: false
|
317 |
+
},
|
318 |
+
profile: {
|
319 |
+
type: 'boolean',
|
320 |
+
default: false
|
321 |
+
},
|
322 |
+
invoices: {
|
323 |
+
type: 'boolean',
|
324 |
+
default: false
|
325 |
+
},
|
326 |
+
links: {
|
327 |
+
type: 'boolean',
|
328 |
+
default: false
|
329 |
+
}
|
330 |
+
},
|
331 |
+
edit: function edit(props) {
|
332 |
+
var setAttributes = props.setAttributes,
|
333 |
+
isSelected = props.isSelected;
|
334 |
+
return [isSelected && Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(_inspector__WEBPACK_IMPORTED_MODULE_2__["default"], _objectSpread({
|
335 |
+
setAttributes: setAttributes
|
336 |
+
}, props)), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("div", {
|
337 |
+
className: "pmpro-block-element"
|
338 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("span", {
|
339 |
+
className: "pmpro-block-title"
|
340 |
+
}, __('Paid Memberships Pro', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("span", {
|
341 |
+
className: "pmpro-block-subtitle"
|
342 |
+
}, __('Membership Account Page', 'paid-memberships-pro')))];
|
343 |
+
},
|
344 |
+
save: function save() {
|
345 |
+
return null;
|
346 |
+
}
|
347 |
+
}));
|
348 |
+
|
349 |
+
/***/ }),
|
350 |
+
|
351 |
+
/***/ "./blocks/account-page/inspector.js":
|
352 |
+
/*!******************************************!*\
|
353 |
+
!*** ./blocks/account-page/inspector.js ***!
|
354 |
+
\******************************************/
|
355 |
+
/*! exports provided: default */
|
356 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
357 |
+
|
358 |
+
"use strict";
|
359 |
+
__webpack_require__.r(__webpack_exports__);
|
360 |
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Inspector; });
|
361 |
+
/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/classCallCheck */ "./node_modules/@babel/runtime/helpers/classCallCheck.js");
|
362 |
+
/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0__);
|
363 |
+
/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/createClass */ "./node_modules/@babel/runtime/helpers/createClass.js");
|
364 |
+
/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1__);
|
365 |
+
/* harmony import */ var _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/inherits */ "./node_modules/@babel/runtime/helpers/inherits.js");
|
366 |
+
/* harmony import */ var _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2__);
|
367 |
+
/* harmony import */ var _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime/helpers/possibleConstructorReturn */ "./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js");
|
368 |
+
/* harmony import */ var _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3__);
|
369 |
+
/* harmony import */ var _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @babel/runtime/helpers/getPrototypeOf */ "./node_modules/@babel/runtime/helpers/getPrototypeOf.js");
|
370 |
+
/* harmony import */ var _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4__);
|
371 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
372 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__);
|
373 |
+
|
374 |
+
|
375 |
+
|
376 |
+
|
377 |
+
|
378 |
+
|
379 |
+
|
380 |
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4___default()(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4___default()(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3___default()(this, result); }; }
|
381 |
+
|
382 |
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
383 |
+
|
384 |
+
/**
|
385 |
+
* Internal block libraries
|
386 |
+
*/
|
387 |
+
var __ = wp.i18n.__;
|
388 |
+
var Component = wp.element.Component;
|
389 |
+
var _wp$components = wp.components,
|
390 |
+
PanelBody = _wp$components.PanelBody,
|
391 |
+
CheckboxControl = _wp$components.CheckboxControl;
|
392 |
+
var InspectorControls = wp.blockEditor.InspectorControls;
|
393 |
+
/**
|
394 |
+
* Create an Inspector Controls wrapper Component
|
395 |
+
*/
|
396 |
+
|
397 |
+
var Inspector = /*#__PURE__*/function (_Component) {
|
398 |
+
_babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2___default()(Inspector, _Component);
|
399 |
+
|
400 |
+
var _super = _createSuper(Inspector);
|
401 |
+
|
402 |
+
function Inspector() {
|
403 |
+
_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0___default()(this, Inspector);
|
404 |
+
|
405 |
+
return _super.apply(this, arguments);
|
406 |
+
}
|
407 |
+
|
408 |
+
_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1___default()(Inspector, [{
|
409 |
+
key: "render",
|
410 |
+
value: function render() {
|
411 |
+
var _this$props = this.props,
|
412 |
+
_this$props$attribute = _this$props.attributes,
|
413 |
+
membership = _this$props$attribute.membership,
|
414 |
+
profile = _this$props$attribute.profile,
|
415 |
+
invoices = _this$props$attribute.invoices,
|
416 |
+
links = _this$props$attribute.links,
|
417 |
+
setAttributes = _this$props.setAttributes;
|
418 |
+
return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(InspectorControls, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(PanelBody, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(CheckboxControl, {
|
419 |
+
label: __("Show 'My Memberships' Section", 'paid-memberships-pro'),
|
420 |
+
checked: membership,
|
421 |
+
onChange: function onChange(membership) {
|
422 |
+
return setAttributes({
|
423 |
+
membership: membership
|
424 |
+
});
|
425 |
+
}
|
426 |
+
})), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(PanelBody, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(CheckboxControl, {
|
427 |
+
label: __("Show 'Profile' Section", 'paid-memberships-pro'),
|
428 |
+
checked: profile,
|
429 |
+
onChange: function onChange(profile) {
|
430 |
+
return setAttributes({
|
431 |
+
profile: profile
|
432 |
+
});
|
433 |
+
}
|
434 |
+
})), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(PanelBody, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(CheckboxControl, {
|
435 |
+
label: __("Show 'Invoices' Section", 'paid-memberships-pro'),
|
436 |
+
checked: invoices,
|
437 |
+
onChange: function onChange(invoices) {
|
438 |
+
return setAttributes({
|
439 |
+
invoices: invoices
|
440 |
+
});
|
441 |
+
}
|
442 |
+
})), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(PanelBody, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(CheckboxControl, {
|
443 |
+
label: __("Show 'Member Links' Section", 'paid-memberships-pro'),
|
444 |
+
checked: links,
|
445 |
+
onChange: function onChange(links) {
|
446 |
+
return setAttributes({
|
447 |
+
links: links
|
448 |
+
});
|
449 |
+
}
|
450 |
+
})));
|
451 |
+
}
|
452 |
+
}]);
|
453 |
+
|
454 |
+
return Inspector;
|
455 |
+
}(Component);
|
456 |
+
|
457 |
+
|
458 |
+
|
459 |
+
/***/ }),
|
460 |
+
|
461 |
+
/***/ "./blocks/account-profile-section/block.js":
|
462 |
+
/*!*************************************************!*\
|
463 |
+
!*** ./blocks/account-profile-section/block.js ***!
|
464 |
+
\*************************************************/
|
465 |
+
/*! exports provided: default */
|
466 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
467 |
+
|
468 |
+
"use strict";
|
469 |
+
__webpack_require__.r(__webpack_exports__);
|
470 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
471 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
472 |
+
|
473 |
+
|
474 |
+
/**
|
475 |
+
* Block: PMPro Checkout Button
|
476 |
+
*
|
477 |
+
* Add a styled link to the PMPro checkout page for a
|
478 |
+
* specific level.
|
479 |
+
*
|
480 |
+
*/
|
481 |
+
|
482 |
+
/**
|
483 |
+
* Internal block libraries
|
484 |
+
*/
|
485 |
+
var __ = wp.i18n.__;
|
486 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
487 |
+
/**
|
488 |
+
* Register block
|
489 |
+
*/
|
490 |
+
|
491 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/account-profile-section', {
|
492 |
+
title: __('Membership Account: Profile', 'paid-memberships-pro'),
|
493 |
+
description: __('Displays the member\'s profile information.', 'paid-memberships-pro'),
|
494 |
+
category: 'pmpro',
|
495 |
+
icon: {
|
496 |
+
background: '#2997c8',
|
497 |
+
foreground: '#ffffff',
|
498 |
+
src: 'admin-users'
|
499 |
+
},
|
500 |
+
keywords: [__('pmpro', 'paid-memberships-pro')],
|
501 |
+
supports: {},
|
502 |
+
attributes: {},
|
503 |
+
edit: function edit() {
|
504 |
+
return [Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
505 |
+
className: "pmpro-block-element"
|
506 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
507 |
+
className: "pmpro-block-title"
|
508 |
+
}, __('Paid Memberships Pro', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
509 |
+
className: "pmpro-block-subtitle"
|
510 |
+
}, __('Membership Account: Profile', 'paid-memberships-pro')))];
|
511 |
+
},
|
512 |
+
save: function save() {
|
513 |
+
return null;
|
514 |
+
}
|
515 |
+
}));
|
516 |
+
|
517 |
+
/***/ }),
|
518 |
+
|
519 |
+
/***/ "./blocks/billing-page/block.js":
|
520 |
+
/*!**************************************!*\
|
521 |
+
!*** ./blocks/billing-page/block.js ***!
|
522 |
+
\**************************************/
|
523 |
+
/*! exports provided: default */
|
524 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
525 |
+
|
526 |
+
"use strict";
|
527 |
+
__webpack_require__.r(__webpack_exports__);
|
528 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
529 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
530 |
+
|
531 |
+
|
532 |
+
/**
|
533 |
+
* Block: PMPro Membership Billing
|
534 |
+
*
|
535 |
+
* Displays the Membership Billing page and form.
|
536 |
+
*
|
537 |
+
*/
|
538 |
+
|
539 |
+
/**
|
540 |
+
* Internal block libraries
|
541 |
+
*/
|
542 |
+
var __ = wp.i18n.__;
|
543 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
544 |
+
/**
|
545 |
+
* Register block
|
546 |
+
*/
|
547 |
+
|
548 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/billing-page', {
|
549 |
+
title: __('Membership Billing Page', 'paid-memberships-pro'),
|
550 |
+
description: __('Displays the member\'s billing information and allows them to update the payment method.', 'paid-memberships-pro'),
|
551 |
+
category: 'pmpro',
|
552 |
+
icon: {
|
553 |
+
background: '#2997c8',
|
554 |
+
foreground: '#ffffff',
|
555 |
+
src: 'list-view'
|
556 |
+
},
|
557 |
+
keywords: [__('pmpro', 'paid-memberships-pro')],
|
558 |
+
supports: {},
|
559 |
+
attributes: {},
|
560 |
+
edit: function edit() {
|
561 |
+
return [Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
562 |
+
className: "pmpro-block-element"
|
563 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
564 |
+
className: "pmpro-block-title"
|
565 |
+
}, __('Paid Memberships Pro', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
566 |
+
className: "pmpro-block-subtitle"
|
567 |
+
}, __('Membership Billing Page', 'paid-memberships-pro')))];
|
568 |
+
},
|
569 |
+
save: function save() {
|
570 |
+
return null;
|
571 |
+
}
|
572 |
+
}));
|
573 |
+
|
574 |
+
/***/ }),
|
575 |
+
|
576 |
+
/***/ "./blocks/blocks.js":
|
577 |
+
/*!**************************!*\
|
578 |
+
!*** ./blocks/blocks.js ***!
|
579 |
+
\**************************/
|
580 |
+
/*! no exports provided */
|
581 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
582 |
+
|
583 |
+
"use strict";
|
584 |
+
__webpack_require__.r(__webpack_exports__);
|
585 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
586 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
587 |
+
/* harmony import */ var _i18n_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./i18n.js */ "./blocks/i18n.js");
|
588 |
+
/* harmony import */ var _i18n_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_i18n_js__WEBPACK_IMPORTED_MODULE_1__);
|
589 |
+
/* harmony import */ var _checkout_button_block_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./checkout-button/block.js */ "./blocks/checkout-button/block.js");
|
590 |
+
/* harmony import */ var _account_page_block_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./account-page/block.js */ "./blocks/account-page/block.js");
|
591 |
+
/* harmony import */ var _account_membership_section_block_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./account-membership-section/block.js */ "./blocks/account-membership-section/block.js");
|
592 |
+
/* harmony import */ var _account_profile_section_block_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./account-profile-section/block.js */ "./blocks/account-profile-section/block.js");
|
593 |
+
/* harmony import */ var _account_invoices_section_block_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./account-invoices-section/block.js */ "./blocks/account-invoices-section/block.js");
|
594 |
+
/* harmony import */ var _account_links_section_block_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./account-links-section/block.js */ "./blocks/account-links-section/block.js");
|
595 |
+
/* harmony import */ var _billing_page_block_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./billing-page/block.js */ "./blocks/billing-page/block.js");
|
596 |
+
/* harmony import */ var _cancel_page_block_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./cancel-page/block.js */ "./blocks/cancel-page/block.js");
|
597 |
+
/* harmony import */ var _checkout_page_block_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./checkout-page/block.js */ "./blocks/checkout-page/block.js");
|
598 |
+
/* harmony import */ var _confirmation_page_block_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./confirmation-page/block.js */ "./blocks/confirmation-page/block.js");
|
599 |
+
/* harmony import */ var _invoice_page_block_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./invoice-page/block.js */ "./blocks/invoice-page/block.js");
|
600 |
+
/* harmony import */ var _levels_page_block_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./levels-page/block.js */ "./blocks/levels-page/block.js");
|
601 |
+
/* harmony import */ var _membership_block_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./membership/block.js */ "./blocks/membership/block.js");
|
602 |
+
/* harmony import */ var _member_profile_edit_block_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./member-profile-edit/block.js */ "./blocks/member-profile-edit/block.js");
|
603 |
+
/* harmony import */ var _login_block_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./login/block.js */ "./blocks/login/block.js");
|
604 |
+
|
605 |
+
|
606 |
+
/**
|
607 |
+
* Import internationalization
|
608 |
+
*/
|
609 |
+
|
610 |
+
/**
|
611 |
+
* Import registerBlockType blocks
|
612 |
+
*/
|
613 |
+
|
614 |
+
|
615 |
+
|
616 |
+
|
617 |
+
|
618 |
+
|
619 |
+
|
620 |
+
|
621 |
+
|
622 |
+
|
623 |
+
|
624 |
+
|
625 |
+
|
626 |
+
|
627 |
+
|
628 |
+
|
629 |
+
|
630 |
+
(function () {
|
631 |
+
var PMProSVG = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("svg", {
|
632 |
+
version: "1.1",
|
633 |
+
id: "Layer_1",
|
634 |
+
x: "0px",
|
635 |
+
y: "0px",
|
636 |
+
viewBox: "0 0 18 18"
|
637 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("path", {
|
638 |
+
d: "M17.99,4.53c-0.35,0.12-0.7,0.26-1.06,0.4c-0.35,0.14-0.7,0.3-1.05,0.46c-0.35,0.16-0.69,0.33-1.03,0.51 c-0.34,0.18-0.68,0.37-1.02,0.56c-0.15,0.09-0.31,0.18-0.46,0.27c-0.15,0.09-0.3,0.19-0.45,0.28c-0.15,0.1-0.3,0.19-0.45,0.29 c-0.15,0.1-0.3,0.2-0.44,0.3c-0.08,0.05-0.16,0.11-0.23,0.16c-0.08,0.05-0.16,0.11-0.23,0.17c-0.08,0.06-0.15,0.11-0.23,0.17 c-0.08,0.06-0.15,0.11-0.23,0.17c-0.07,0.05-0.13,0.1-0.2,0.15c-0.07,0.05-0.13,0.1-0.2,0.15c-0.07,0.05-0.13,0.1-0.2,0.15 c-0.07,0.05-0.13,0.1-0.2,0.16c-0.04,0.03-0.09,0.07-0.13,0.1c-0.04,0.03-0.09,0.07-0.13,0.1C10,9.13,9.95,9.17,9.91,9.2 C9.87,9.24,9.83,9.27,9.79,9.31C9.77,9.32,9.75,9.33,9.74,9.35C9.72,9.36,9.71,9.37,9.69,9.39C9.67,9.4,9.66,9.42,9.64,9.43 C9.63,9.44,9.61,9.46,9.59,9.47C9.54,9.52,9.49,9.56,9.43,9.61C9.38,9.65,9.33,9.7,9.27,9.74C9.22,9.79,9.17,9.84,9.11,9.88 c-0.05,0.05-0.11,0.09-0.16,0.14c-0.27,0.24-0.54,0.49-0.81,0.75c-0.26,0.25-0.53,0.51-0.78,0.78c-0.26,0.26-0.51,0.53-0.76,0.81 c-0.25,0.27-0.49,0.55-0.73,0.84c-0.03,0.04-0.07,0.08-0.1,0.12c-0.03,0.04-0.07,0.08-0.1,0.12c-0.03,0.04-0.07,0.08-0.1,0.12 c-0.03,0.04-0.07,0.08-0.1,0.12c-0.03,0.04-0.07,0.08-0.1,0.12c-0.03,0.04-0.06,0.08-0.1,0.12c-0.03,0.04-0.06,0.08-0.1,0.12 c-0.03,0.04-0.06,0.08-0.1,0.12c0,0.01-0.01,0.01-0.01,0.02c0,0.01-0.01,0.01-0.01,0.02c0,0.01-0.01,0.01-0.01,0.02 c0,0.01-0.01,0.01-0.01,0.02c-0.03,0.03-0.05,0.07-0.08,0.1c-0.03,0.03-0.05,0.07-0.08,0.1c-0.03,0.03-0.05,0.07-0.08,0.11 c-0.03,0.03-0.05,0.07-0.08,0.11c-0.03,0.04-0.06,0.08-0.09,0.12c-0.03,0.04-0.06,0.08-0.09,0.12C4.5,14.96,4.47,15,4.44,15.05 c-0.03,0.04-0.06,0.08-0.09,0.13c0,0-0.01,0.01-0.01,0.01c0,0-0.01,0.01-0.01,0.01c0,0-0.01,0.01-0.01,0.01c0,0-0.01,0.01-0.01,0.01 c-0.15,0.22-0.31,0.44-0.46,0.67c-0.15,0.22-0.3,0.45-0.44,0.68c-0.14,0.23-0.29,0.46-0.43,0.7C2.85,17.52,2.71,17.76,2.58,18 c-0.08-0.19-0.16-0.38-0.23-0.56c-0.07-0.18-0.14-0.35-0.21-0.51c-0.07-0.16-0.13-0.32-0.19-0.47c-0.06-0.15-0.12-0.3-0.18-0.45 l-0.01,0.01l0.01-0.03c-0.01-0.03-0.02-0.05-0.03-0.08c-0.01-0.02-0.02-0.05-0.03-0.07c-0.01-0.02-0.02-0.05-0.03-0.07 c-0.01-0.02-0.02-0.05-0.03-0.07c0-0.01-0.01-0.02-0.01-0.02c0-0.01-0.01-0.02-0.01-0.02c0-0.01-0.01-0.02-0.01-0.02 c0-0.01-0.01-0.02-0.01-0.02c-0.01-0.02-0.01-0.04-0.02-0.05c-0.01-0.02-0.01-0.04-0.02-0.05c-0.01-0.02-0.01-0.04-0.02-0.05 c-0.01-0.02-0.01-0.04-0.02-0.05c-0.01-0.03-0.02-0.05-0.03-0.07c-0.01-0.02-0.02-0.05-0.03-0.07c-0.01-0.02-0.02-0.05-0.03-0.07 c-0.01-0.02-0.02-0.05-0.03-0.07c-0.01-0.02-0.02-0.05-0.03-0.07c-0.01-0.02-0.02-0.05-0.03-0.07c-0.01-0.02-0.02-0.05-0.03-0.07 c-0.01-0.02-0.02-0.05-0.03-0.07c-0.02-0.05-0.04-0.1-0.06-0.16c-0.02-0.05-0.04-0.1-0.06-0.16c-0.02-0.05-0.04-0.11-0.06-0.16 c-0.02-0.05-0.04-0.11-0.06-0.16c-0.08-0.23-0.16-0.47-0.25-0.72c-0.08-0.25-0.17-0.5-0.26-0.77c-0.09-0.27-0.18-0.55-0.27-0.84 c-0.09-0.29-0.19-0.6-0.29-0.93c0.05,0.07,0.1,0.15,0.15,0.22c0.05,0.07,0.1,0.14,0.14,0.2c0.05,0.07,0.09,0.13,0.14,0.19 c0.04,0.06,0.09,0.12,0.13,0.18c0.09,0.13,0.18,0.24,0.27,0.35c0.09,0.11,0.17,0.21,0.24,0.3c0.08,0.09,0.15,0.18,0.23,0.27 c0.07,0.09,0.15,0.17,0.22,0.25c0.02,0.02,0.03,0.04,0.05,0.06c0.02,0.02,0.03,0.04,0.05,0.06c0.02,0.02,0.03,0.04,0.05,0.06 c0.02,0.02,0.03,0.04,0.05,0.06c0.07,0.07,0.13,0.14,0.2,0.22c0.07,0.08,0.14,0.16,0.22,0.24c0.08,0.08,0.16,0.17,0.24,0.27 c0.09,0.1,0.18,0.2,0.27,0.31c0.01,0.01,0.02,0.02,0.03,0.03c0.01,0.01,0.02,0.02,0.03,0.03c0.01,0.01,0.02,0.02,0.03,0.04 c0.01,0.01,0.02,0.02,0.03,0.04c0.02-0.02,0.04-0.05,0.06-0.07c0.02-0.02,0.04-0.05,0.06-0.07c0.02-0.02,0.04-0.05,0.06-0.07 C2.96,14.03,2.98,14,3,13.98c0.03-0.03,0.05-0.06,0.08-0.09c0.03-0.03,0.05-0.06,0.08-0.09c0.03-0.03,0.05-0.06,0.08-0.09 c0.03-0.03,0.05-0.06,0.08-0.09c0.28-0.33,0.58-0.65,0.88-0.97c0.31-0.32,0.63-0.62,0.95-0.92c0.33-0.3,0.67-0.6,1.02-0.88 c0.35-0.29,0.72-0.57,1.09-0.84c0.06-0.04,0.11-0.08,0.17-0.12C7.49,9.83,7.55,9.79,7.6,9.75c0.06-0.04,0.11-0.08,0.17-0.12 c0.06-0.04,0.12-0.08,0.17-0.12C7.97,9.5,7.98,9.49,8,9.48c0.02-0.01,0.03-0.02,0.05-0.03C8.06,9.43,8.08,9.42,8.1,9.41 C8.11,9.4,8.13,9.38,8.14,9.37c0.05-0.03,0.1-0.06,0.14-0.1c0.05-0.03,0.1-0.06,0.14-0.1c0.05-0.03,0.1-0.06,0.14-0.1 c0.05-0.03,0.1-0.06,0.15-0.09C8.79,8.94,8.87,8.9,8.94,8.85C9.01,8.8,9.09,8.76,9.16,8.71c0.07-0.05,0.15-0.09,0.22-0.14 c0.07-0.05,0.15-0.09,0.22-0.14c0.09-0.05,0.17-0.11,0.26-0.16c0.09-0.05,0.17-0.1,0.26-0.16c0.09-0.05,0.18-0.1,0.27-0.15 c0.09-0.05,0.18-0.1,0.27-0.15c0.25-0.14,0.51-0.28,0.76-0.42c0.26-0.14,0.52-0.27,0.78-0.41c0.26-0.13,0.53-0.27,0.79-0.4 c0.27-0.13,0.54-0.26,0.81-0.38c0.01,0,0.02-0.01,0.03-0.01c0.01,0,0.02-0.01,0.03-0.01c0.01,0,0.02-0.01,0.03-0.01 c0.01,0,0.02-0.01,0.03-0.01c0.33-0.15,0.67-0.3,1-0.44c0.34-0.15,0.68-0.29,1.02-0.42c0.34-0.14,0.69-0.27,1.03-0.4 C17.31,4.77,17.65,4.64,17.99,4.53z M15.73,9.59l0.65,4.56l-10.4-0.05c-0.02,0.02-0.04,0.04-0.05,0.07 c-0.02,0.02-0.04,0.04-0.05,0.07c-0.02,0.02-0.04,0.04-0.05,0.07c-0.02,0.02-0.04,0.04-0.05,0.07c-0.02,0.02-0.03,0.04-0.05,0.06 c-0.02,0.02-0.03,0.04-0.05,0.06c-0.02,0.02-0.03,0.04-0.05,0.06c-0.02,0.02-0.03,0.04-0.05,0.06l11.23,0.2l-0.78-5.24L15.73,9.59z M6.75,13.2c-0.04,0.04-0.08,0.09-0.11,0.13c-0.04,0.04-0.08,0.09-0.11,0.13c-0.04,0.04-0.07,0.09-0.11,0.13l9.22-0.07L15.04,9.1 l-0.07-0.53l-0.39,0.04l0.55,4.3l-8.27,0.17C6.83,13.12,6.79,13.16,6.75,13.2z M13.78,7.66l-0.59,0.08 c-0.06,0.04-0.12,0.08-0.18,0.12c-0.06,0.04-0.12,0.08-0.18,0.12c-0.06,0.04-0.12,0.08-0.18,0.12c-0.06,0.04-0.12,0.08-0.18,0.12 c-0.08,0.05-0.16,0.11-0.24,0.16c-0.08,0.06-0.16,0.11-0.24,0.17c-0.08,0.06-0.16,0.11-0.24,0.17c-0.08,0.06-0.16,0.11-0.24,0.17 c-0.07,0.05-0.14,0.1-0.21,0.15c-0.07,0.05-0.14,0.1-0.21,0.15c-0.07,0.05-0.14,0.1-0.2,0.16c-0.07,0.05-0.14,0.11-0.2,0.16 c-0.04,0.03-0.09,0.07-0.13,0.1c-0.04,0.03-0.09,0.07-0.13,0.1c-0.04,0.04-0.09,0.07-0.13,0.11c-0.04,0.04-0.09,0.07-0.13,0.11 c-0.02,0.01-0.03,0.03-0.05,0.04c-0.02,0.01-0.03,0.03-0.05,0.04c-0.02,0.01-0.03,0.03-0.05,0.04c-0.02,0.01-0.03,0.03-0.05,0.04 c-0.06,0.05-0.11,0.09-0.16,0.14c-0.05,0.05-0.11,0.09-0.16,0.14c-0.05,0.05-0.11,0.09-0.16,0.14c-0.05,0.05-0.11,0.09-0.16,0.14 c-0.17,0.15-0.34,0.3-0.51,0.46c-0.17,0.16-0.33,0.31-0.5,0.47c-0.16,0.16-0.33,0.32-0.49,0.48c-0.16,0.16-0.32,0.33-0.48,0.49 l6.98-0.23l-0.48-4.16L13.78,7.66z M13.32,5.73c-0.06,0.03-0.11,0.05-0.17,0.08c-0.06,0.03-0.12,0.06-0.17,0.09 c-0.03,0.01-0.06,0.03-0.08,0.04c0,0,0,0,0,0c-0.02-0.01-0.04-0.03-0.06-0.04c-0.06-0.04-0.13-0.07-0.21-0.09 c-0.07-0.02-0.15-0.04-0.23-0.04c-0.08,0-0.16,0-0.24,0.01l-0.14,0.02c0.07-0.04,0.13-0.08,0.18-0.14c0.05-0.05,0.1-0.11,0.14-0.18 c0.04-0.06,0.06-0.13,0.08-0.2c0.02-0.07,0.02-0.15,0.01-0.22c-0.01-0.1-0.04-0.18-0.08-0.26c-0.05-0.08-0.11-0.14-0.18-0.19 c-0.07-0.05-0.16-0.08-0.25-0.1c-0.09-0.02-0.19-0.02-0.29,0c-0.1,0.02-0.19,0.06-0.27,0.11c-0.08,0.05-0.15,0.11-0.21,0.19 C11.08,4.9,11.03,4.98,11,5.07c-0.03,0.09-0.04,0.18-0.03,0.27c0.01,0.07,0.02,0.14,0.05,0.2c0.03,0.06,0.06,0.12,0.11,0.17 c0.05,0.05,0.1,0.09,0.16,0.12c0.06,0.03,0.13,0.06,0.2,0.07l-0.17,0.03C11.18,5.96,11.06,6,10.94,6.07 c-0.11,0.07-0.21,0.15-0.29,0.25c-0.08,0.1-0.14,0.21-0.19,0.33c-0.04,0.12-0.06,0.25-0.05,0.38l0.02,0.33 c-0.09,0.05-0.17,0.1-0.26,0.16c-0.02,0-0.05,0-0.07,0c0.02-0.01,0.04-0.02,0.06-0.03c-0.06-0.06-0.13-0.11-0.21-0.16 c-0.07-0.04-0.15-0.08-0.24-0.1C9.63,7.2,9.54,7.18,9.45,7.18c-0.09-0.01-0.18,0-0.27,0.01L9.01,7.21c0.08-0.05,0.16-0.1,0.23-0.17 C9.3,6.97,9.36,6.9,9.41,6.81C9.46,6.73,9.5,6.64,9.52,6.55c0.02-0.09,0.03-0.19,0.03-0.29C9.54,6.13,9.51,6.02,9.46,5.92 c-0.05-0.1-0.12-0.18-0.21-0.25C9.17,5.6,9.07,5.56,8.96,5.53c-0.11-0.02-0.22-0.03-0.34,0C8.5,5.55,8.39,5.6,8.29,5.66 C8.19,5.72,8.1,5.81,8.02,5.9C7.95,5.99,7.89,6.1,7.85,6.21C7.81,6.32,7.79,6.44,7.79,6.56c0,0.09,0.02,0.18,0.05,0.26 c0.03,0.08,0.07,0.16,0.12,0.22c0.05,0.07,0.11,0.12,0.18,0.17c0.07,0.04,0.15,0.08,0.23,0.1l-0.2,0.03 C8.01,7.37,7.85,7.42,7.72,7.51C7.58,7.59,7.46,7.7,7.35,7.82C7.25,7.95,7.17,8.1,7.11,8.25c-0.06,0.16-0.09,0.33-0.08,0.5 l0.01,0.74C6.98,9.53,6.93,9.58,6.88,9.62C6.81,9.49,6.74,9.38,6.65,9.28c-0.1-0.11-0.21-0.2-0.33-0.27 C6.2,8.94,6.07,8.89,5.93,8.87C5.8,8.84,5.66,8.83,5.51,8.85L5.3,8.88c0.1-0.06,0.2-0.13,0.29-0.22c0.09-0.09,0.16-0.19,0.23-0.3 c0.06-0.11,0.12-0.23,0.15-0.35C6,7.88,6.02,7.75,6.02,7.62c0-0.17-0.03-0.32-0.08-0.46C5.88,7.03,5.8,6.91,5.71,6.82 C5.61,6.73,5.5,6.67,5.37,6.63c-0.12-0.04-0.26-0.04-0.4-0.02c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0,0,0,0,0 c-0.14,0.03-0.28,0.08-0.4,0.16c-0.12,0.08-0.23,0.18-0.33,0.3C4.14,7.2,4.07,7.33,4.01,7.48c-0.06,0.15-0.09,0.3-0.1,0.46 c0,0.12,0.01,0.24,0.03,0.35c0.03,0.11,0.07,0.21,0.12,0.3c0.05,0.09,0.12,0.17,0.2,0.23c0.08,0.06,0.17,0.11,0.27,0.14L4.3,9 C4.1,9.03,3.92,9.09,3.75,9.2C3.58,9.3,3.43,9.44,3.3,9.6c-0.13,0.16-0.24,0.35-0.32,0.56c-0.08,0.21-0.13,0.43-0.14,0.67 l-0.12,2.26l-0.53-0.6l0.49-6.3C2.68,6.09,2.71,6,2.74,5.91c0.04-0.09,0.08-0.17,0.14-0.24c0.06-0.07,0.12-0.14,0.2-0.19 C3.15,5.44,3.23,5.4,3.32,5.38l0.71-0.17l0-0.02l0.18-0.04l0.06-1.19C4.3,3.56,4.39,3.15,4.55,2.77c0.16-0.38,0.37-0.75,0.64-1.08 C5.45,1.35,5.76,1.05,6.11,0.8c0.35-0.26,0.74-0.47,1.16-0.61C7.7,0.05,8.12-0.01,8.51,0c0.4,0.02,0.77,0.12,1.1,0.29 c0.33,0.18,0.62,0.43,0.83,0.75c0.21,0.33,0.35,0.73,0.38,1.19l0.1,1.36l0.3-0.07l0,0.02l0.89-0.21c0.13-0.03,0.25-0.03,0.36-0.02 c0.12,0.02,0.22,0.05,0.32,0.11c0.09,0.05,0.17,0.13,0.23,0.21c0.06,0.09,0.1,0.19,0.11,0.31L13.32,5.73z M9.46,3.96L9.4,2.61 C9.39,2.33,9.31,2.09,9.19,1.88C9.07,1.68,8.91,1.51,8.71,1.4C8.52,1.28,8.29,1.21,8.05,1.19C7.81,1.17,7.55,1.2,7.28,1.28 C7.01,1.37,6.76,1.49,6.53,1.65c-0.22,0.16-0.43,0.35-0.6,0.57C5.77,2.43,5.63,2.67,5.53,2.91c-0.1,0.25-0.16,0.5-0.17,0.76 L5.33,4.91L9.46,3.96z"
|
639 |
+
}));
|
640 |
+
wp.blocks.updateCategory('pmpro', {
|
641 |
+
icon: PMProSVG
|
642 |
+
});
|
643 |
+
})();
|
644 |
+
|
645 |
+
/***/ }),
|
646 |
+
|
647 |
+
/***/ "./blocks/cancel-page/block.js":
|
648 |
+
/*!*************************************!*\
|
649 |
+
!*** ./blocks/cancel-page/block.js ***!
|
650 |
+
\*************************************/
|
651 |
+
/*! exports provided: default */
|
652 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
653 |
+
|
654 |
+
"use strict";
|
655 |
+
__webpack_require__.r(__webpack_exports__);
|
656 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
657 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
658 |
+
|
659 |
+
|
660 |
+
/**
|
661 |
+
* Block: PMPro Membership Cancel
|
662 |
+
*
|
663 |
+
* Displays the Membership Cancel page.
|
664 |
+
*
|
665 |
+
*/
|
666 |
+
|
667 |
+
/**
|
668 |
+
* Internal block libraries
|
669 |
+
*/
|
670 |
+
var __ = wp.i18n.__;
|
671 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
672 |
+
/**
|
673 |
+
* Register block
|
674 |
+
*/
|
675 |
+
|
676 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/cancel-page', {
|
677 |
+
title: __('Membership Cancel Page', 'paid-memberships-pro'),
|
678 |
+
description: __('Generates the Membership Cancel page.', 'paid-memberships-pro'),
|
679 |
+
category: 'pmpro',
|
680 |
+
icon: {
|
681 |
+
background: '#2997c8',
|
682 |
+
foreground: '#ffffff',
|
683 |
+
src: 'no'
|
684 |
+
},
|
685 |
+
keywords: [__('pmpro', 'paid-memberships-pro')],
|
686 |
+
supports: {},
|
687 |
+
attributes: {},
|
688 |
+
edit: function edit() {
|
689 |
+
return [Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
690 |
+
className: "pmpro-block-element"
|
691 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
692 |
+
className: "pmpro-block-title"
|
693 |
+
}, __('Paid Memberships Pro', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
694 |
+
className: "pmpro-block-subtitle"
|
695 |
+
}, __('Membership Cancel Page', 'paid-memberships-pro')))];
|
696 |
+
},
|
697 |
+
save: function save() {
|
698 |
+
return null;
|
699 |
+
}
|
700 |
+
}));
|
701 |
+
|
702 |
+
/***/ }),
|
703 |
+
|
704 |
+
/***/ "./blocks/checkout-button/block.js":
|
705 |
+
/*!*****************************************!*\
|
706 |
+
!*** ./blocks/checkout-button/block.js ***!
|
707 |
+
\*****************************************/
|
708 |
+
/*! exports provided: default */
|
709 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
710 |
+
|
711 |
+
"use strict";
|
712 |
+
__webpack_require__.r(__webpack_exports__);
|
713 |
+
/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "./node_modules/@babel/runtime/helpers/defineProperty.js");
|
714 |
+
/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__);
|
715 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
716 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__);
|
717 |
+
/* harmony import */ var _inspector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./inspector */ "./blocks/checkout-button/inspector.js");
|
718 |
+
|
719 |
+
|
720 |
+
|
721 |
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
722 |
+
|
723 |
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default()(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
724 |
+
|
725 |
+
/**
|
726 |
+
* Block: PMPro Checkout Button
|
727 |
+
*
|
728 |
+
* Add a styled link to the PMPro checkout page for a specific level.
|
729 |
+
*
|
730 |
+
*/
|
731 |
+
|
732 |
+
/**
|
733 |
+
* Block dependencies
|
734 |
+
*/
|
735 |
+
|
736 |
+
/**
|
737 |
+
* Internal block libraries
|
738 |
+
*/
|
739 |
+
|
740 |
+
var __ = wp.i18n.__;
|
741 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
742 |
+
var _wp$components = wp.components,
|
743 |
+
TextControl = _wp$components.TextControl,
|
744 |
+
SelectControl = _wp$components.SelectControl;
|
745 |
+
/**
|
746 |
+
* Register block
|
747 |
+
*/
|
748 |
+
|
749 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/checkout-button', {
|
750 |
+
title: __('Membership Checkout Button', 'paid-memberships-pro'),
|
751 |
+
description: __('Displays a button-styled link to Membership Checkout for the specified level.', 'paid-memberships-pro'),
|
752 |
+
category: 'pmpro',
|
753 |
+
icon: {
|
754 |
+
background: '#2997c8',
|
755 |
+
foreground: '#ffffff',
|
756 |
+
src: 'migrate'
|
757 |
+
},
|
758 |
+
keywords: [__('pmpro', 'paid-memberships-pro'), __('buy', 'paid-memberships-pro'), __('level', 'paid-memberships-pro')],
|
759 |
+
supports: {},
|
760 |
+
attributes: {
|
761 |
+
text: {
|
762 |
+
type: 'string',
|
763 |
+
default: 'Buy Now'
|
764 |
+
},
|
765 |
+
css_class: {
|
766 |
+
type: 'string',
|
767 |
+
default: 'pmpro_btn'
|
768 |
+
},
|
769 |
+
level: {
|
770 |
+
type: 'string'
|
771 |
+
}
|
772 |
+
},
|
773 |
+
edit: function edit(props) {
|
774 |
+
var _props$attributes = props.attributes,
|
775 |
+
text = _props$attributes.text,
|
776 |
+
level = _props$attributes.level,
|
777 |
+
css_class = _props$attributes.css_class,
|
778 |
+
className = props.className,
|
779 |
+
setAttributes = props.setAttributes,
|
780 |
+
isSelected = props.isSelected;
|
781 |
+
return [isSelected && Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(_inspector__WEBPACK_IMPORTED_MODULE_2__["default"], _objectSpread({
|
782 |
+
setAttributes: setAttributes
|
783 |
+
}, props)), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("div", {
|
784 |
+
className: className
|
785 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("a", {
|
786 |
+
class: css_class
|
787 |
+
}, text)), isSelected && Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("div", {
|
788 |
+
className: "pmpro-block-element"
|
789 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(TextControl, {
|
790 |
+
label: __('Button Text', 'paid-memberships-pro'),
|
791 |
+
value: text,
|
792 |
+
onChange: function onChange(text) {
|
793 |
+
return setAttributes({
|
794 |
+
text: text
|
795 |
+
});
|
796 |
+
}
|
797 |
+
}), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(SelectControl, {
|
798 |
+
label: __('Membership Level', 'paid-memberships-pro'),
|
799 |
+
value: level,
|
800 |
+
onChange: function onChange(level) {
|
801 |
+
return setAttributes({
|
802 |
+
level: level
|
803 |
+
});
|
804 |
+
},
|
805 |
+
options: window.pmpro.all_level_values_and_labels
|
806 |
+
}), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(TextControl, {
|
807 |
+
label: __('CSS Class', 'paid-memberships-pro'),
|
808 |
+
value: css_class,
|
809 |
+
onChange: function onChange(css_class) {
|
810 |
+
return setAttributes({
|
811 |
+
css_class: css_class
|
812 |
+
});
|
813 |
+
}
|
814 |
+
}))];
|
815 |
+
},
|
816 |
+
save: function save() {
|
817 |
+
return null;
|
818 |
+
}
|
819 |
+
}));
|
820 |
+
|
821 |
+
/***/ }),
|
822 |
+
|
823 |
+
/***/ "./blocks/checkout-button/inspector.js":
|
824 |
+
/*!*********************************************!*\
|
825 |
+
!*** ./blocks/checkout-button/inspector.js ***!
|
826 |
+
\*********************************************/
|
827 |
+
/*! exports provided: default */
|
828 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
829 |
+
|
830 |
+
"use strict";
|
831 |
+
__webpack_require__.r(__webpack_exports__);
|
832 |
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Inspector; });
|
833 |
+
/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/classCallCheck */ "./node_modules/@babel/runtime/helpers/classCallCheck.js");
|
834 |
+
/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0__);
|
835 |
+
/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/createClass */ "./node_modules/@babel/runtime/helpers/createClass.js");
|
836 |
+
/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1__);
|
837 |
+
/* harmony import */ var _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/inherits */ "./node_modules/@babel/runtime/helpers/inherits.js");
|
838 |
+
/* harmony import */ var _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2__);
|
839 |
+
/* harmony import */ var _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime/helpers/possibleConstructorReturn */ "./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js");
|
840 |
+
/* harmony import */ var _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3__);
|
841 |
+
/* harmony import */ var _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @babel/runtime/helpers/getPrototypeOf */ "./node_modules/@babel/runtime/helpers/getPrototypeOf.js");
|
842 |
+
/* harmony import */ var _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4__);
|
843 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
844 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__);
|
845 |
+
|
846 |
+
|
847 |
+
|
848 |
+
|
849 |
+
|
850 |
+
|
851 |
+
|
852 |
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4___default()(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4___default()(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3___default()(this, result); }; }
|
853 |
+
|
854 |
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
855 |
+
|
856 |
+
/**
|
857 |
+
* Internal block libraries
|
858 |
+
*/
|
859 |
+
var __ = wp.i18n.__;
|
860 |
+
var Component = wp.element.Component;
|
861 |
+
var _wp$components = wp.components,
|
862 |
+
PanelBody = _wp$components.PanelBody,
|
863 |
+
TextControl = _wp$components.TextControl,
|
864 |
+
SelectControl = _wp$components.SelectControl;
|
865 |
+
var InspectorControls = wp.blockEditor.InspectorControls;
|
866 |
+
/**
|
867 |
+
* Create an Inspector Controls wrapper Component
|
868 |
+
*/
|
869 |
+
|
870 |
+
var Inspector = /*#__PURE__*/function (_Component) {
|
871 |
+
_babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2___default()(Inspector, _Component);
|
872 |
+
|
873 |
+
var _super = _createSuper(Inspector);
|
874 |
+
|
875 |
+
function Inspector() {
|
876 |
+
_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0___default()(this, Inspector);
|
877 |
+
|
878 |
+
return _super.apply(this, arguments);
|
879 |
+
}
|
880 |
+
|
881 |
+
_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1___default()(Inspector, [{
|
882 |
+
key: "render",
|
883 |
+
value: function render() {
|
884 |
+
var _this$props = this.props,
|
885 |
+
_this$props$attribute = _this$props.attributes,
|
886 |
+
text = _this$props$attribute.text,
|
887 |
+
level = _this$props$attribute.level,
|
888 |
+
css_class = _this$props$attribute.css_class,
|
889 |
+
setAttributes = _this$props.setAttributes;
|
890 |
+
return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(InspectorControls, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(PanelBody, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(TextControl, {
|
891 |
+
label: __('Button Text', 'paid-memberships-pro'),
|
892 |
+
help: __('Text for checkout button', 'paid-memberships-pro'),
|
893 |
+
value: text,
|
894 |
+
onChange: function onChange(text) {
|
895 |
+
return setAttributes({
|
896 |
+
text: text
|
897 |
+
});
|
898 |
+
}
|
899 |
+
})), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(PanelBody, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(SelectControl, {
|
900 |
+
label: __('Level', 'paid-memberships-pro'),
|
901 |
+
help: __('The level to link to for checkout button', 'paid-memberships-pro'),
|
902 |
+
value: level,
|
903 |
+
onChange: function onChange(level) {
|
904 |
+
return setAttributes({
|
905 |
+
level: level
|
906 |
+
});
|
907 |
+
},
|
908 |
+
options: window.pmpro.all_level_values_and_labels
|
909 |
+
})), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(PanelBody, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(TextControl, {
|
910 |
+
label: __('CSS Class', 'paid-memberships-pro'),
|
911 |
+
help: __('Additional styling for checkout button', 'paid-memberships-pro'),
|
912 |
+
value: css_class,
|
913 |
+
onChange: function onChange(css_class) {
|
914 |
+
return setAttributes({
|
915 |
+
css_class: css_class
|
916 |
+
});
|
917 |
+
}
|
918 |
+
})));
|
919 |
+
}
|
920 |
+
}]);
|
921 |
+
|
922 |
+
return Inspector;
|
923 |
+
}(Component);
|
924 |
+
|
925 |
+
|
926 |
+
|
927 |
+
/***/ }),
|
928 |
+
|
929 |
+
/***/ "./blocks/checkout-page/block.js":
|
930 |
+
/*!***************************************!*\
|
931 |
+
!*** ./blocks/checkout-page/block.js ***!
|
932 |
+
\***************************************/
|
933 |
+
/*! exports provided: default */
|
934 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
935 |
+
|
936 |
+
"use strict";
|
937 |
+
__webpack_require__.r(__webpack_exports__);
|
938 |
+
/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "./node_modules/@babel/runtime/helpers/defineProperty.js");
|
939 |
+
/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__);
|
940 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
941 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__);
|
942 |
+
/* harmony import */ var _inspector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./inspector */ "./blocks/checkout-page/inspector.js");
|
943 |
+
|
944 |
+
|
945 |
+
|
946 |
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
947 |
+
|
948 |
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default()(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
949 |
+
|
950 |
+
/**
|
951 |
+
* Block: PMPro Membership Checkout
|
952 |
+
*
|
953 |
+
* Displays the Membership Checkout form.
|
954 |
+
*
|
955 |
+
*/
|
956 |
+
|
957 |
+
/**
|
958 |
+
* Block dependencies
|
959 |
+
*/
|
960 |
+
|
961 |
+
/**
|
962 |
+
* Internal block libraries
|
963 |
+
*/
|
964 |
+
|
965 |
+
var __ = wp.i18n.__;
|
966 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
967 |
+
var SelectControl = wp.components.SelectControl;
|
968 |
+
/**
|
969 |
+
* Register block
|
970 |
+
*/
|
971 |
+
|
972 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/checkout-page', {
|
973 |
+
title: __('Membership Checkout Form', 'paid-memberships-pro'),
|
974 |
+
description: __('Displays the Membership Checkout form.', 'paid-memberships-pro'),
|
975 |
+
category: 'pmpro',
|
976 |
+
icon: {
|
977 |
+
background: '#2997c8',
|
978 |
+
foreground: '#ffffff',
|
979 |
+
src: 'list-view'
|
980 |
+
},
|
981 |
+
keywords: [__('pmpro', 'paid-memberships-pro')],
|
982 |
+
supports: {},
|
983 |
+
attributes: {
|
984 |
+
pmpro_default_level: {
|
985 |
+
type: 'string',
|
986 |
+
source: 'meta',
|
987 |
+
meta: 'pmpro_default_level'
|
988 |
+
}
|
989 |
+
},
|
990 |
+
edit: function edit(props) {
|
991 |
+
var pmpro_default_level = props.attributes.pmpro_default_level,
|
992 |
+
className = props.className,
|
993 |
+
setAttributes = props.setAttributes,
|
994 |
+
isSelected = props.isSelected;
|
995 |
+
return [isSelected && Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(_inspector__WEBPACK_IMPORTED_MODULE_2__["default"], _objectSpread({
|
996 |
+
setAttributes: setAttributes
|
997 |
+
}, props)), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("div", {
|
998 |
+
className: "pmpro-block-element"
|
999 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("span", {
|
1000 |
+
className: "pmpro-block-title"
|
1001 |
+
}, __('Paid Memberships Pro', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("span", {
|
1002 |
+
className: "pmpro-block-subtitle"
|
1003 |
+
}, __('Membership Checkout Form', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("hr", null), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(SelectControl, {
|
1004 |
+
label: __('Membership Level', 'paid-memberships-pro'),
|
1005 |
+
value: pmpro_default_level,
|
1006 |
+
onChange: function onChange(pmpro_default_level) {
|
1007 |
+
return setAttributes({
|
1008 |
+
pmpro_default_level: pmpro_default_level
|
1009 |
+
});
|
1010 |
+
},
|
1011 |
+
options: window.pmpro.all_level_values_and_labels
|
1012 |
+
}))];
|
1013 |
+
},
|
1014 |
+
save: function save() {
|
1015 |
+
return null;
|
1016 |
+
}
|
1017 |
+
}));
|
1018 |
+
|
1019 |
+
/***/ }),
|
1020 |
+
|
1021 |
+
/***/ "./blocks/checkout-page/inspector.js":
|
1022 |
+
/*!*******************************************!*\
|
1023 |
+
!*** ./blocks/checkout-page/inspector.js ***!
|
1024 |
+
\*******************************************/
|
1025 |
+
/*! exports provided: default */
|
1026 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1027 |
+
|
1028 |
+
"use strict";
|
1029 |
+
__webpack_require__.r(__webpack_exports__);
|
1030 |
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Inspector; });
|
1031 |
+
/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/classCallCheck */ "./node_modules/@babel/runtime/helpers/classCallCheck.js");
|
1032 |
+
/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0__);
|
1033 |
+
/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/createClass */ "./node_modules/@babel/runtime/helpers/createClass.js");
|
1034 |
+
/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1__);
|
1035 |
+
/* harmony import */ var _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/inherits */ "./node_modules/@babel/runtime/helpers/inherits.js");
|
1036 |
+
/* harmony import */ var _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2__);
|
1037 |
+
/* harmony import */ var _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime/helpers/possibleConstructorReturn */ "./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js");
|
1038 |
+
/* harmony import */ var _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3__);
|
1039 |
+
/* harmony import */ var _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @babel/runtime/helpers/getPrototypeOf */ "./node_modules/@babel/runtime/helpers/getPrototypeOf.js");
|
1040 |
+
/* harmony import */ var _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4__);
|
1041 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
1042 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__);
|
1043 |
+
|
1044 |
+
|
1045 |
+
|
1046 |
+
|
1047 |
+
|
1048 |
+
|
1049 |
+
|
1050 |
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4___default()(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4___default()(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3___default()(this, result); }; }
|
1051 |
+
|
1052 |
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
1053 |
+
|
1054 |
+
/**
|
1055 |
+
* Internal block libraries
|
1056 |
+
*/
|
1057 |
+
var __ = wp.i18n.__;
|
1058 |
+
var Component = wp.element.Component;
|
1059 |
+
var _wp$components = wp.components,
|
1060 |
+
PanelBody = _wp$components.PanelBody,
|
1061 |
+
PanelRow = _wp$components.PanelRow,
|
1062 |
+
SelectControl = _wp$components.SelectControl;
|
1063 |
+
var InspectorControls = wp.blockEditor.InspectorControls;
|
1064 |
+
/**
|
1065 |
+
* Create an Inspector Controls wrapper Component
|
1066 |
+
*/
|
1067 |
+
|
1068 |
+
var Inspector = /*#__PURE__*/function (_Component) {
|
1069 |
+
_babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2___default()(Inspector, _Component);
|
1070 |
+
|
1071 |
+
var _super = _createSuper(Inspector);
|
1072 |
+
|
1073 |
+
function Inspector() {
|
1074 |
+
_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0___default()(this, Inspector);
|
1075 |
+
|
1076 |
+
return _super.apply(this, arguments);
|
1077 |
+
}
|
1078 |
+
|
1079 |
+
_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1___default()(Inspector, [{
|
1080 |
+
key: "render",
|
1081 |
+
value: function render() {
|
1082 |
+
var _this$props = this.props,
|
1083 |
+
pmpro_default_level = _this$props.attributes.pmpro_default_level,
|
1084 |
+
setAttributes = _this$props.setAttributes;
|
1085 |
+
return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(InspectorControls, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(PanelBody, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(SelectControl, {
|
1086 |
+
label: __('Membership Level', 'paid-memberships-pro'),
|
1087 |
+
help: __('Choose a default level for Membership Checkout.', 'paid-memberships-pro'),
|
1088 |
+
value: pmpro_default_level,
|
1089 |
+
onChange: function onChange(pmpro_default_level) {
|
1090 |
+
return setAttributes({
|
1091 |
+
pmpro_default_level: pmpro_default_level
|
1092 |
+
});
|
1093 |
+
},
|
1094 |
+
options: [''].concat(window.pmpro.all_level_values_and_labels)
|
1095 |
+
})));
|
1096 |
+
}
|
1097 |
+
}]);
|
1098 |
+
|
1099 |
+
return Inspector;
|
1100 |
+
}(Component);
|
1101 |
+
|
1102 |
+
|
1103 |
+
|
1104 |
+
/***/ }),
|
1105 |
+
|
1106 |
+
/***/ "./blocks/confirmation-page/block.js":
|
1107 |
+
/*!*******************************************!*\
|
1108 |
+
!*** ./blocks/confirmation-page/block.js ***!
|
1109 |
+
\*******************************************/
|
1110 |
+
/*! exports provided: default */
|
1111 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1112 |
+
|
1113 |
+
"use strict";
|
1114 |
+
__webpack_require__.r(__webpack_exports__);
|
1115 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
1116 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
1117 |
+
|
1118 |
+
|
1119 |
+
/**
|
1120 |
+
* Block: PMPro Membership Confirmation
|
1121 |
+
*
|
1122 |
+
* Displays the Membership Confirmation template.
|
1123 |
+
*
|
1124 |
+
*/
|
1125 |
+
|
1126 |
+
/**
|
1127 |
+
* Internal block libraries
|
1128 |
+
*/
|
1129 |
+
var __ = wp.i18n.__;
|
1130 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
1131 |
+
/**
|
1132 |
+
* Register block
|
1133 |
+
*/
|
1134 |
+
|
1135 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/confirmation-page', {
|
1136 |
+
title: __('Membership Confirmation Page', 'paid-memberships-pro'),
|
1137 |
+
description: __('Displays the member\'s Membership Confirmation after Membership Checkout.', 'paid-memberships-pro'),
|
1138 |
+
category: 'pmpro',
|
1139 |
+
icon: {
|
1140 |
+
background: '#2997c8',
|
1141 |
+
foreground: '#ffffff',
|
1142 |
+
src: 'yes'
|
1143 |
+
},
|
1144 |
+
keywords: [__('pmpro', 'paid-memberships-pro')],
|
1145 |
+
supports: {},
|
1146 |
+
attributes: {},
|
1147 |
+
edit: function edit() {
|
1148 |
+
return [Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
1149 |
+
className: "pmpro-block-element"
|
1150 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
1151 |
+
className: "pmpro-block-title"
|
1152 |
+
}, __('Paid Memberships Pro', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
1153 |
+
className: "pmpro-block-subtitle"
|
1154 |
+
}, __('Membership Confirmation Page', 'paid-memberships-pro')))];
|
1155 |
+
},
|
1156 |
+
save: function save() {
|
1157 |
+
return null;
|
1158 |
+
}
|
1159 |
+
}));
|
1160 |
+
|
1161 |
+
/***/ }),
|
1162 |
+
|
1163 |
+
/***/ "./blocks/i18n.js":
|
1164 |
+
/*!************************!*\
|
1165 |
+
!*** ./blocks/i18n.js ***!
|
1166 |
+
\************************/
|
1167 |
+
/*! no static exports found */
|
1168 |
+
/***/ (function(module, exports) {
|
1169 |
+
|
1170 |
+
wp.i18n.setLocaleData({
|
1171 |
+
'': {}
|
1172 |
+
}, 'paid-memberships-pro');
|
1173 |
+
|
1174 |
+
/***/ }),
|
1175 |
+
|
1176 |
+
/***/ "./blocks/invoice-page/block.js":
|
1177 |
+
/*!**************************************!*\
|
1178 |
+
!*** ./blocks/invoice-page/block.js ***!
|
1179 |
+
\**************************************/
|
1180 |
+
/*! exports provided: default */
|
1181 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1182 |
+
|
1183 |
+
"use strict";
|
1184 |
+
__webpack_require__.r(__webpack_exports__);
|
1185 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
1186 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
1187 |
+
|
1188 |
+
|
1189 |
+
/**
|
1190 |
+
* Block: PMPro Membership Invoices
|
1191 |
+
*
|
1192 |
+
* Displays the Membership Invoices template.
|
1193 |
+
*
|
1194 |
+
*/
|
1195 |
+
|
1196 |
+
/**
|
1197 |
+
* Internal block libraries
|
1198 |
+
*/
|
1199 |
+
var __ = wp.i18n.__;
|
1200 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
1201 |
+
/**
|
1202 |
+
* Register block
|
1203 |
+
*/
|
1204 |
+
|
1205 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/invoice-page', {
|
1206 |
+
title: __('Membership Invoice Page', 'paid-memberships-pro'),
|
1207 |
+
description: __('Displays the member\'s Membership Invoices.', 'paid-memberships-pro'),
|
1208 |
+
category: 'pmpro',
|
1209 |
+
icon: {
|
1210 |
+
background: '#2997c8',
|
1211 |
+
foreground: '#ffffff',
|
1212 |
+
src: 'archive'
|
1213 |
+
},
|
1214 |
+
keywords: [__('pmpro', 'paid-memberships-pro')],
|
1215 |
+
supports: {},
|
1216 |
+
attributes: {},
|
1217 |
+
edit: function edit() {
|
1218 |
+
return [Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
1219 |
+
className: "pmpro-block-element"
|
1220 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
1221 |
+
className: "pmpro-block-title"
|
1222 |
+
}, __('Paid Memberships Pro', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
1223 |
+
className: "pmpro-block-subtitle"
|
1224 |
+
}, __('Membership Invoices', 'paid-memberships-pro')))];
|
1225 |
+
},
|
1226 |
+
save: function save() {
|
1227 |
+
return null;
|
1228 |
+
}
|
1229 |
+
}));
|
1230 |
+
|
1231 |
+
/***/ }),
|
1232 |
+
|
1233 |
+
/***/ "./blocks/levels-page/block.js":
|
1234 |
+
/*!*************************************!*\
|
1235 |
+
!*** ./blocks/levels-page/block.js ***!
|
1236 |
+
\*************************************/
|
1237 |
+
/*! exports provided: default */
|
1238 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1239 |
+
|
1240 |
+
"use strict";
|
1241 |
+
__webpack_require__.r(__webpack_exports__);
|
1242 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
1243 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
1244 |
+
|
1245 |
+
|
1246 |
+
/**
|
1247 |
+
* Block: PMPro Membership Levels
|
1248 |
+
*
|
1249 |
+
* Displays the Membership Levels template.
|
1250 |
+
*
|
1251 |
+
*/
|
1252 |
+
|
1253 |
+
/**
|
1254 |
+
* Internal block libraries
|
1255 |
+
*/
|
1256 |
+
var __ = wp.i18n.__;
|
1257 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
1258 |
+
/**
|
1259 |
+
* Register block
|
1260 |
+
*/
|
1261 |
+
|
1262 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/levels-page', {
|
1263 |
+
title: __('Membership Levels List', 'paid-memberships-pro'),
|
1264 |
+
description: __('Displays a list of Membership Levels. To change the order, go to Memberships > Settings > Levels.', 'paid-memberships-pro'),
|
1265 |
+
category: 'pmpro',
|
1266 |
+
icon: {
|
1267 |
+
background: '#2997c8',
|
1268 |
+
foreground: '#ffffff',
|
1269 |
+
src: 'list-view'
|
1270 |
+
},
|
1271 |
+
keywords: [__('pmpro', 'paid-memberships-pro')],
|
1272 |
+
supports: {},
|
1273 |
+
attributes: {},
|
1274 |
+
edit: function edit() {
|
1275 |
+
return [Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
1276 |
+
className: "pmpro-block-element"
|
1277 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
1278 |
+
className: "pmpro-block-title"
|
1279 |
+
}, __('Paid Memberships Pro', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
1280 |
+
className: "pmpro-block-subtitle"
|
1281 |
+
}, __('Membership Levels List', 'paid-memberships-pro')))];
|
1282 |
+
},
|
1283 |
+
save: function save() {
|
1284 |
+
return null;
|
1285 |
+
}
|
1286 |
+
}));
|
1287 |
+
|
1288 |
+
/***/ }),
|
1289 |
+
|
1290 |
+
/***/ "./blocks/login/block.js":
|
1291 |
+
/*!*******************************!*\
|
1292 |
+
!*** ./blocks/login/block.js ***!
|
1293 |
+
\*******************************/
|
1294 |
+
/*! exports provided: default */
|
1295 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1296 |
+
|
1297 |
+
"use strict";
|
1298 |
+
__webpack_require__.r(__webpack_exports__);
|
1299 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
1300 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
1301 |
+
/* harmony import */ var _inspector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./inspector */ "./blocks/login/inspector.js");
|
1302 |
+
|
1303 |
+
|
1304 |
+
/**
|
1305 |
+
* Block: PMPro Login Form
|
1306 |
+
*
|
1307 |
+
* Add a login form to any page or post.
|
1308 |
+
*
|
1309 |
+
*/
|
1310 |
+
|
1311 |
+
/**
|
1312 |
+
* Block dependencies
|
1313 |
+
*/
|
1314 |
+
|
1315 |
+
/**
|
1316 |
+
* Internal block libraries
|
1317 |
+
*/
|
1318 |
+
|
1319 |
+
var __ = wp.i18n.__;
|
1320 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
1321 |
+
var Fragment = wp.element.Fragment;
|
1322 |
+
/**
|
1323 |
+
* Register block
|
1324 |
+
*/
|
1325 |
+
|
1326 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType("pmpro/login-form", {
|
1327 |
+
title: __("Log in Form", "paid-memberships-pro"),
|
1328 |
+
description: __("Displays a Log In Form for Paid Memberships Pro.", "paid-memberships-pro"),
|
1329 |
+
category: "pmpro",
|
1330 |
+
icon: {
|
1331 |
+
background: "#2997c8",
|
1332 |
+
foreground: "#ffffff",
|
1333 |
+
src: "unlock"
|
1334 |
+
},
|
1335 |
+
keywords: [__("pmpro", "paid-memberships-pro"), __("login", "paid-memberships-pro"), __("form", "paid-memberships-pro"), __("log in", "paid-memberships-pro")],
|
1336 |
+
supports: {},
|
1337 |
+
edit: function edit(props) {
|
1338 |
+
return [Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(Fragment, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_inspector__WEBPACK_IMPORTED_MODULE_1__["default"], props), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
1339 |
+
className: "pmpro-block-element"
|
1340 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
1341 |
+
className: "pmpro-block-title"
|
1342 |
+
}, __("Paid Memberships Pro", "paid-memberships-pro")), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
1343 |
+
className: "pmpro-block-subtitle"
|
1344 |
+
}, __("Log in Form", "paid-memberships-pro"))))];
|
1345 |
+
},
|
1346 |
+
save: function save() {
|
1347 |
+
return null;
|
1348 |
+
}
|
1349 |
+
}));
|
1350 |
+
|
1351 |
+
/***/ }),
|
1352 |
+
|
1353 |
+
/***/ "./blocks/login/inspector.js":
|
1354 |
+
/*!***********************************!*\
|
1355 |
+
!*** ./blocks/login/inspector.js ***!
|
1356 |
+
\***********************************/
|
1357 |
+
/*! exports provided: default */
|
1358 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1359 |
+
|
1360 |
+
"use strict";
|
1361 |
+
__webpack_require__.r(__webpack_exports__);
|
1362 |
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Inspector; });
|
1363 |
+
/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/classCallCheck */ "./node_modules/@babel/runtime/helpers/classCallCheck.js");
|
1364 |
+
/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0__);
|
1365 |
+
/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/createClass */ "./node_modules/@babel/runtime/helpers/createClass.js");
|
1366 |
+
/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1__);
|
1367 |
+
/* harmony import */ var _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/inherits */ "./node_modules/@babel/runtime/helpers/inherits.js");
|
1368 |
+
/* harmony import */ var _babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2__);
|
1369 |
+
/* harmony import */ var _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime/helpers/possibleConstructorReturn */ "./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js");
|
1370 |
+
/* harmony import */ var _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3__);
|
1371 |
+
/* harmony import */ var _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @babel/runtime/helpers/getPrototypeOf */ "./node_modules/@babel/runtime/helpers/getPrototypeOf.js");
|
1372 |
+
/* harmony import */ var _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4__);
|
1373 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
1374 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__);
|
1375 |
+
|
1376 |
+
|
1377 |
+
|
1378 |
+
|
1379 |
+
|
1380 |
+
|
1381 |
+
|
1382 |
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4___default()(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _babel_runtime_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_4___default()(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _babel_runtime_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_3___default()(this, result); }; }
|
1383 |
+
|
1384 |
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
1385 |
+
|
1386 |
+
/**
|
1387 |
+
* Internal block libraries
|
1388 |
+
*/
|
1389 |
+
var __ = wp.i18n.__;
|
1390 |
+
var Component = wp.element.Component;
|
1391 |
+
var _wp$components = wp.components,
|
1392 |
+
PanelBody = _wp$components.PanelBody,
|
1393 |
+
SelectControl = _wp$components.SelectControl,
|
1394 |
+
ToggleControl = _wp$components.ToggleControl;
|
1395 |
+
var InspectorControls = wp.blockEditor.InspectorControls;
|
1396 |
+
/**
|
1397 |
+
* Create an Inspector Controls wrapper Component
|
1398 |
+
*/
|
1399 |
+
|
1400 |
+
var Inspector = /*#__PURE__*/function (_Component) {
|
1401 |
+
_babel_runtime_helpers_inherits__WEBPACK_IMPORTED_MODULE_2___default()(Inspector, _Component);
|
1402 |
+
|
1403 |
+
var _super = _createSuper(Inspector);
|
1404 |
+
|
1405 |
+
function Inspector() {
|
1406 |
+
_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_0___default()(this, Inspector);
|
1407 |
+
|
1408 |
+
return _super.apply(this, arguments);
|
1409 |
+
}
|
1410 |
+
|
1411 |
+
_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_1___default()(Inspector, [{
|
1412 |
+
key: "render",
|
1413 |
+
value: function render() {
|
1414 |
+
var _this = this;
|
1415 |
+
|
1416 |
+
var _this$props = this.props,
|
1417 |
+
attributes = _this$props.attributes,
|
1418 |
+
setAttributes = _this$props.setAttributes;
|
1419 |
+
var display_if_logged_in = attributes.display_if_logged_in,
|
1420 |
+
show_menu = attributes.show_menu,
|
1421 |
+
show_logout_link = attributes.show_logout_link,
|
1422 |
+
location = attributes.location;
|
1423 |
+
return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(InspectorControls, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(PanelBody, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(ToggleControl, {
|
1424 |
+
label: __("Display 'Welcome' content when logged in.", "paid-memberships-pro"),
|
1425 |
+
checked: display_if_logged_in,
|
1426 |
+
onChange: function onChange(value) {
|
1427 |
+
_this.props.setAttributes({
|
1428 |
+
display_if_logged_in: value
|
1429 |
+
});
|
1430 |
+
}
|
1431 |
+
}), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(ToggleControl, {
|
1432 |
+
label: __("Display the 'Log In Widget' menu.", "paid-memberships-pro"),
|
1433 |
+
help: __("Assign the menu under Appearance > Menus."),
|
1434 |
+
checked: show_menu,
|
1435 |
+
onChange: function onChange(value) {
|
1436 |
+
_this.props.setAttributes({
|
1437 |
+
show_menu: value
|
1438 |
+
});
|
1439 |
+
}
|
1440 |
+
}), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_5__["createElement"])(ToggleControl, {
|
1441 |
+
label: __("Display a 'Log Out' link.", "paid-memberships-pro"),
|
1442 |
+
checked: show_logout_link,
|
1443 |
+
onChange: function onChange(value) {
|
1444 |
+
_this.props.setAttributes({
|
1445 |
+
show_logout_link: value
|
1446 |
+
});
|
1447 |
+
}
|
1448 |
+
})));
|
1449 |
+
}
|
1450 |
+
}]);
|
1451 |
+
|
1452 |
+
return Inspector;
|
1453 |
+
}(Component);
|
1454 |
+
|
1455 |
+
|
1456 |
+
|
1457 |
+
/***/ }),
|
1458 |
+
|
1459 |
+
/***/ "./blocks/member-profile-edit/block.js":
|
1460 |
+
/*!*********************************************!*\
|
1461 |
+
!*** ./blocks/member-profile-edit/block.js ***!
|
1462 |
+
\*********************************************/
|
1463 |
+
/*! exports provided: default */
|
1464 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1465 |
+
|
1466 |
+
"use strict";
|
1467 |
+
__webpack_require__.r(__webpack_exports__);
|
1468 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
1469 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
1470 |
+
|
1471 |
+
|
1472 |
+
/**
|
1473 |
+
* Block: PMPro Member Profile Edit
|
1474 |
+
*
|
1475 |
+
*
|
1476 |
+
*/
|
1477 |
+
|
1478 |
+
/**
|
1479 |
+
* Internal block libraries
|
1480 |
+
*/
|
1481 |
+
var __ = wp.i18n.__;
|
1482 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
1483 |
+
/**
|
1484 |
+
* Register block
|
1485 |
+
*/
|
1486 |
+
|
1487 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType("pmpro/member-profile-edit", {
|
1488 |
+
title: __("Member Profile Edit", "paid-memberships-pro"),
|
1489 |
+
description: __("Allow member profile editing.", "paid-memberships-pro"),
|
1490 |
+
category: "pmpro",
|
1491 |
+
icon: {
|
1492 |
+
background: "#2997c8",
|
1493 |
+
foreground: "#ffffff",
|
1494 |
+
src: "admin-users"
|
1495 |
+
},
|
1496 |
+
keywords: [__("pmpro", "paid-memberships-pro"), __("member", "paid-memberships-pro"), __("profile", "paid-memberships-pro")],
|
1497 |
+
edit: function edit(props) {
|
1498 |
+
return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
1499 |
+
className: "pmpro-block-element"
|
1500 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
1501 |
+
className: "pmpro-block-title"
|
1502 |
+
}, __("Paid Memberships Pro", "paid-memberships-pro")), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
1503 |
+
className: "pmpro-block-subtitle"
|
1504 |
+
}, __("Member Profile Edit", "paid-memberships-pro")));
|
1505 |
+
},
|
1506 |
+
save: function save() {
|
1507 |
+
return null;
|
1508 |
+
}
|
1509 |
+
}));
|
1510 |
+
|
1511 |
+
/***/ }),
|
1512 |
+
|
1513 |
+
/***/ "./blocks/membership/block.js":
|
1514 |
+
/*!************************************!*\
|
1515 |
+
!*** ./blocks/membership/block.js ***!
|
1516 |
+
\************************************/
|
1517 |
+
/*! exports provided: default */
|
1518 |
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1519 |
+
|
1520 |
+
"use strict";
|
1521 |
+
__webpack_require__.r(__webpack_exports__);
|
1522 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
|
1523 |
+
/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
|
1524 |
+
|
1525 |
+
|
1526 |
+
/**
|
1527 |
+
* Block: PMPro Membership
|
1528 |
+
*
|
1529 |
+
*
|
1530 |
+
*/
|
1531 |
+
|
1532 |
+
/**
|
1533 |
+
* Internal block libraries
|
1534 |
+
*/
|
1535 |
+
var __ = wp.i18n.__;
|
1536 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
1537 |
+
var _wp$components = wp.components,
|
1538 |
+
PanelBody = _wp$components.PanelBody,
|
1539 |
+
CheckboxControl = _wp$components.CheckboxControl;
|
1540 |
+
var _wp$blockEditor = wp.blockEditor,
|
1541 |
+
InspectorControls = _wp$blockEditor.InspectorControls,
|
1542 |
+
InnerBlocks = _wp$blockEditor.InnerBlocks;
|
1543 |
+
var all_levels = [{
|
1544 |
+
value: 0,
|
1545 |
+
label: "Non-Members"
|
1546 |
+
}].concat(pmpro.all_level_values_and_labels);
|
1547 |
+
/**
|
1548 |
+
* Register block
|
1549 |
+
*/
|
1550 |
+
|
1551 |
+
/* harmony default export */ __webpack_exports__["default"] = (registerBlockType('pmpro/membership', {
|
1552 |
+
title: __('Require Membership Block', 'paid-memberships-pro'),
|
1553 |
+
description: __('Control the visibility of nested blocks for members or non-members.', 'paid-memberships-pro'),
|
1554 |
+
category: 'pmpro',
|
1555 |
+
icon: {
|
1556 |
+
background: '#2997c8',
|
1557 |
+
foreground: '#ffffff',
|
1558 |
+
src: 'visibility'
|
1559 |
+
},
|
1560 |
+
keywords: [__('pmpro', 'paid-memberships-pro')],
|
1561 |
+
attributes: {
|
1562 |
+
levels: {
|
1563 |
+
type: 'array',
|
1564 |
+
default: []
|
1565 |
+
},
|
1566 |
+
uid: {
|
1567 |
+
type: 'string',
|
1568 |
+
default: ''
|
1569 |
+
}
|
1570 |
+
},
|
1571 |
+
edit: function edit(props) {
|
1572 |
+
var _props$attributes = props.attributes,
|
1573 |
+
levels = _props$attributes.levels,
|
1574 |
+
uid = _props$attributes.uid,
|
1575 |
+
setAttributes = props.setAttributes,
|
1576 |
+
isSelected = props.isSelected;
|
1577 |
+
|
1578 |
+
if (uid == '') {
|
1579 |
+
var rand = Math.random() + "";
|
1580 |
+
setAttributes({
|
1581 |
+
uid: rand
|
1582 |
+
});
|
1583 |
+
} // Build an array of checkboxes for each level.
|
1584 |
+
|
1585 |
+
|
1586 |
+
var checkboxes = all_levels.map(function (level) {
|
1587 |
+
function setLevelsAttribute(nowChecked) {
|
1588 |
+
if (nowChecked && !levels.some(function (levelID) {
|
1589 |
+
return levelID == level.value;
|
1590 |
+
})) {
|
1591 |
+
// Add the level.
|
1592 |
+
var newLevels = levels.slice();
|
1593 |
+
newLevels.push(level.value + '');
|
1594 |
+
setAttributes({
|
1595 |
+
levels: newLevels
|
1596 |
+
});
|
1597 |
+
} else if (!nowChecked && levels.some(function (levelID) {
|
1598 |
+
return levelID == level.value;
|
1599 |
+
})) {
|
1600 |
+
// Remove the level.
|
1601 |
+
var _newLevels = levels.filter(function (levelID) {
|
1602 |
+
return levelID != level.value;
|
1603 |
+
});
|
1604 |
+
|
1605 |
+
setAttributes({
|
1606 |
+
levels: _newLevels
|
1607 |
+
});
|
1608 |
+
}
|
1609 |
+
}
|
1610 |
+
|
1611 |
+
return [Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(CheckboxControl, {
|
1612 |
+
label: level.label,
|
1613 |
+
checked: levels.some(function (levelID) {
|
1614 |
+
return levelID == level.value;
|
1615 |
+
}),
|
1616 |
+
onChange: setLevelsAttribute
|
1617 |
+
})];
|
1618 |
+
});
|
1619 |
+
return [isSelected && Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(InspectorControls, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(PanelBody, null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
1620 |
+
class: "pmpro-block-inspector-scrollable"
|
1621 |
+
}, checkboxes))), isSelected && Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
1622 |
+
className: "pmpro-block-require-membership-element"
|
1623 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
1624 |
+
className: "pmpro-block-title"
|
1625 |
+
}, __('Require Membership', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(PanelBody, null, checkboxes), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(InnerBlocks, {
|
1626 |
+
renderAppender: function renderAppender() {
|
1627 |
+
return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(InnerBlocks.ButtonBlockAppender, null);
|
1628 |
+
},
|
1629 |
+
templateLock: false
|
1630 |
+
})), !isSelected && Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
1631 |
+
className: "pmpro-block-require-membership-element"
|
1632 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
|
1633 |
+
className: "pmpro-block-title"
|
1634 |
+
}, __('Require Membership', 'paid-memberships-pro')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(InnerBlocks, {
|
1635 |
+
renderAppender: function renderAppender() {
|
1636 |
+
return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(InnerBlocks.ButtonBlockAppender, null);
|
1637 |
+
},
|
1638 |
+
templateLock: false
|
1639 |
+
}))];
|
1640 |
+
},
|
1641 |
+
save: function save(props) {
|
1642 |
+
var className = props.className;
|
1643 |
+
return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
|
1644 |
+
className: className
|
1645 |
+
}, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(InnerBlocks.Content, null));
|
1646 |
+
}
|
1647 |
+
}));
|
1648 |
+
|
1649 |
+
/***/ }),
|
1650 |
+
|
1651 |
+
/***/ "./node_modules/@babel/runtime/helpers/assertThisInitialized.js":
|
1652 |
+
/*!**********************************************************************!*\
|
1653 |
+
!*** ./node_modules/@babel/runtime/helpers/assertThisInitialized.js ***!
|
1654 |
+
\**********************************************************************/
|
1655 |
+
/*! no static exports found */
|
1656 |
+
/***/ (function(module, exports) {
|
1657 |
+
|
1658 |
+
function _assertThisInitialized(self) {
|
1659 |
+
if (self === void 0) {
|
1660 |
+
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
1661 |
+
}
|
1662 |
+
|
1663 |
+
return self;
|
1664 |
+
}
|
1665 |
+
|
1666 |
+
module.exports = _assertThisInitialized;
|
1667 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1668 |
+
|
1669 |
+
/***/ }),
|
1670 |
+
|
1671 |
+
/***/ "./node_modules/@babel/runtime/helpers/classCallCheck.js":
|
1672 |
+
/*!***************************************************************!*\
|
1673 |
+
!*** ./node_modules/@babel/runtime/helpers/classCallCheck.js ***!
|
1674 |
+
\***************************************************************/
|
1675 |
+
/*! no static exports found */
|
1676 |
+
/***/ (function(module, exports) {
|
1677 |
+
|
1678 |
+
function _classCallCheck(instance, Constructor) {
|
1679 |
+
if (!(instance instanceof Constructor)) {
|
1680 |
+
throw new TypeError("Cannot call a class as a function");
|
1681 |
+
}
|
1682 |
+
}
|
1683 |
+
|
1684 |
+
module.exports = _classCallCheck;
|
1685 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1686 |
+
|
1687 |
+
/***/ }),
|
1688 |
+
|
1689 |
+
/***/ "./node_modules/@babel/runtime/helpers/createClass.js":
|
1690 |
+
/*!************************************************************!*\
|
1691 |
+
!*** ./node_modules/@babel/runtime/helpers/createClass.js ***!
|
1692 |
+
\************************************************************/
|
1693 |
+
/*! no static exports found */
|
1694 |
+
/***/ (function(module, exports) {
|
1695 |
+
|
1696 |
+
function _defineProperties(target, props) {
|
1697 |
+
for (var i = 0; i < props.length; i++) {
|
1698 |
+
var descriptor = props[i];
|
1699 |
+
descriptor.enumerable = descriptor.enumerable || false;
|
1700 |
+
descriptor.configurable = true;
|
1701 |
+
if ("value" in descriptor) descriptor.writable = true;
|
1702 |
+
Object.defineProperty(target, descriptor.key, descriptor);
|
1703 |
+
}
|
1704 |
+
}
|
1705 |
+
|
1706 |
+
function _createClass(Constructor, protoProps, staticProps) {
|
1707 |
+
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
1708 |
+
if (staticProps) _defineProperties(Constructor, staticProps);
|
1709 |
+
return Constructor;
|
1710 |
+
}
|
1711 |
+
|
1712 |
+
module.exports = _createClass;
|
1713 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1714 |
+
|
1715 |
+
/***/ }),
|
1716 |
+
|
1717 |
+
/***/ "./node_modules/@babel/runtime/helpers/defineProperty.js":
|
1718 |
+
/*!***************************************************************!*\
|
1719 |
+
!*** ./node_modules/@babel/runtime/helpers/defineProperty.js ***!
|
1720 |
+
\***************************************************************/
|
1721 |
+
/*! no static exports found */
|
1722 |
+
/***/ (function(module, exports) {
|
1723 |
+
|
1724 |
+
function _defineProperty(obj, key, value) {
|
1725 |
+
if (key in obj) {
|
1726 |
+
Object.defineProperty(obj, key, {
|
1727 |
+
value: value,
|
1728 |
+
enumerable: true,
|
1729 |
+
configurable: true,
|
1730 |
+
writable: true
|
1731 |
+
});
|
1732 |
+
} else {
|
1733 |
+
obj[key] = value;
|
1734 |
+
}
|
1735 |
+
|
1736 |
+
return obj;
|
1737 |
+
}
|
1738 |
+
|
1739 |
+
module.exports = _defineProperty;
|
1740 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1741 |
+
|
1742 |
+
/***/ }),
|
1743 |
+
|
1744 |
+
/***/ "./node_modules/@babel/runtime/helpers/getPrototypeOf.js":
|
1745 |
+
/*!***************************************************************!*\
|
1746 |
+
!*** ./node_modules/@babel/runtime/helpers/getPrototypeOf.js ***!
|
1747 |
+
\***************************************************************/
|
1748 |
+
/*! no static exports found */
|
1749 |
+
/***/ (function(module, exports) {
|
1750 |
+
|
1751 |
+
function _getPrototypeOf(o) {
|
1752 |
+
module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
|
1753 |
+
return o.__proto__ || Object.getPrototypeOf(o);
|
1754 |
+
};
|
1755 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1756 |
+
return _getPrototypeOf(o);
|
1757 |
+
}
|
1758 |
+
|
1759 |
+
module.exports = _getPrototypeOf;
|
1760 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1761 |
+
|
1762 |
+
/***/ }),
|
1763 |
+
|
1764 |
+
/***/ "./node_modules/@babel/runtime/helpers/inherits.js":
|
1765 |
+
/*!*********************************************************!*\
|
1766 |
+
!*** ./node_modules/@babel/runtime/helpers/inherits.js ***!
|
1767 |
+
\*********************************************************/
|
1768 |
+
/*! no static exports found */
|
1769 |
+
/***/ (function(module, exports, __webpack_require__) {
|
1770 |
+
|
1771 |
+
var setPrototypeOf = __webpack_require__(/*! ./setPrototypeOf.js */ "./node_modules/@babel/runtime/helpers/setPrototypeOf.js");
|
1772 |
+
|
1773 |
+
function _inherits(subClass, superClass) {
|
1774 |
+
if (typeof superClass !== "function" && superClass !== null) {
|
1775 |
+
throw new TypeError("Super expression must either be null or a function");
|
1776 |
+
}
|
1777 |
+
|
1778 |
+
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
1779 |
+
constructor: {
|
1780 |
+
value: subClass,
|
1781 |
+
writable: true,
|
1782 |
+
configurable: true
|
1783 |
+
}
|
1784 |
+
});
|
1785 |
+
if (superClass) setPrototypeOf(subClass, superClass);
|
1786 |
+
}
|
1787 |
+
|
1788 |
+
module.exports = _inherits;
|
1789 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1790 |
+
|
1791 |
+
/***/ }),
|
1792 |
+
|
1793 |
+
/***/ "./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js":
|
1794 |
+
/*!**************************************************************************!*\
|
1795 |
+
!*** ./node_modules/@babel/runtime/helpers/possibleConstructorReturn.js ***!
|
1796 |
+
\**************************************************************************/
|
1797 |
+
/*! no static exports found */
|
1798 |
+
/***/ (function(module, exports, __webpack_require__) {
|
1799 |
+
|
1800 |
+
var _typeof = __webpack_require__(/*! @babel/runtime/helpers/typeof */ "./node_modules/@babel/runtime/helpers/typeof.js")["default"];
|
1801 |
+
|
1802 |
+
var assertThisInitialized = __webpack_require__(/*! ./assertThisInitialized.js */ "./node_modules/@babel/runtime/helpers/assertThisInitialized.js");
|
1803 |
+
|
1804 |
+
function _possibleConstructorReturn(self, call) {
|
1805 |
+
if (call && (_typeof(call) === "object" || typeof call === "function")) {
|
1806 |
+
return call;
|
1807 |
+
}
|
1808 |
+
|
1809 |
+
return assertThisInitialized(self);
|
1810 |
+
}
|
1811 |
+
|
1812 |
+
module.exports = _possibleConstructorReturn;
|
1813 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1814 |
+
|
1815 |
+
/***/ }),
|
1816 |
+
|
1817 |
+
/***/ "./node_modules/@babel/runtime/helpers/setPrototypeOf.js":
|
1818 |
+
/*!***************************************************************!*\
|
1819 |
+
!*** ./node_modules/@babel/runtime/helpers/setPrototypeOf.js ***!
|
1820 |
+
\***************************************************************/
|
1821 |
+
/*! no static exports found */
|
1822 |
+
/***/ (function(module, exports) {
|
1823 |
+
|
1824 |
+
function _setPrototypeOf(o, p) {
|
1825 |
+
module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
|
1826 |
+
o.__proto__ = p;
|
1827 |
+
return o;
|
1828 |
+
};
|
1829 |
+
|
1830 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1831 |
+
return _setPrototypeOf(o, p);
|
1832 |
+
}
|
1833 |
+
|
1834 |
+
module.exports = _setPrototypeOf;
|
1835 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1836 |
+
|
1837 |
+
/***/ }),
|
1838 |
+
|
1839 |
+
/***/ "./node_modules/@babel/runtime/helpers/typeof.js":
|
1840 |
+
/*!*******************************************************!*\
|
1841 |
+
!*** ./node_modules/@babel/runtime/helpers/typeof.js ***!
|
1842 |
+
\*******************************************************/
|
1843 |
+
/*! no static exports found */
|
1844 |
+
/***/ (function(module, exports) {
|
1845 |
+
|
1846 |
+
function _typeof(obj) {
|
1847 |
+
"@babel/helpers - typeof";
|
1848 |
+
|
1849 |
+
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
|
1850 |
+
module.exports = _typeof = function _typeof(obj) {
|
1851 |
+
return typeof obj;
|
1852 |
+
};
|
1853 |
+
|
1854 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1855 |
+
} else {
|
1856 |
+
module.exports = _typeof = function _typeof(obj) {
|
1857 |
+
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
1858 |
+
};
|
1859 |
+
|
1860 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1861 |
+
}
|
1862 |
+
|
1863 |
+
return _typeof(obj);
|
1864 |
+
}
|
1865 |
+
|
1866 |
+
module.exports = _typeof;
|
1867 |
+
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
1868 |
+
|
1869 |
+
/***/ }),
|
1870 |
+
|
1871 |
+
/***/ "@wordpress/element":
|
1872 |
+
/*!*********************************!*\
|
1873 |
+
!*** external ["wp","element"] ***!
|
1874 |
+
\*********************************/
|
1875 |
+
/*! no static exports found */
|
1876 |
+
/***/ (function(module, exports) {
|
1877 |
+
|
1878 |
+
(function() { module.exports = window["wp"]["element"]; }());
|
1879 |
+
|
1880 |
+
/***/ })
|
1881 |
+
|
1882 |
+
/******/ });
|
1883 |
+
//# sourceMappingURL=blocks.build.js.map
|
js/pmpro-admin.js
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
* @param text The prompt, i.e. are you sure?
|
5 |
* @param url The url to redirect to.
|
6 |
*/
|
7 |
-
function pmpro_askfirst( text, url ) {
|
8 |
var answer = window.confirm( text );
|
9 |
|
10 |
if ( answer ) {
|
@@ -43,7 +43,7 @@ function pmpro_toggle_elements_by_selector( selector, checked ) {
|
|
43 |
* @since v2.1
|
44 |
*/
|
45 |
jQuery(document).ready(function() {
|
46 |
-
jQuery( 'input[pmpro_toggle_trigger_for]' ).
|
47 |
pmpro_toggle_elements_by_selector( jQuery( this ).attr( 'pmpro_toggle_trigger_for' ), jQuery( this ).prop( 'checked' ) );
|
48 |
});
|
49 |
});
|
@@ -81,20 +81,19 @@ jQuery(document).ready(function() {
|
|
81 |
}
|
82 |
|
83 |
// Disable the webhook buttons if the API keys aren't complete yet.
|
84 |
-
jQuery('#stripe_publishablekey,#stripe_secretkey').
|
85 |
pmpro_stripe_check_api_keys();
|
86 |
-
});
|
87 |
-
|
88 |
|
89 |
// AJAX call to create webhook.
|
90 |
-
|
91 |
event.preventDefault();
|
92 |
|
93 |
var postData = {
|
94 |
action: 'pmpro_stripe_create_webhook',
|
95 |
-
|
96 |
}
|
97 |
-
|
98 |
jQuery.ajax({
|
99 |
type: "POST",
|
100 |
data: postData,
|
@@ -120,12 +119,12 @@ jQuery(document).ready(function() {
|
|
120 |
});
|
121 |
|
122 |
// AJAX call to delete webhook.
|
123 |
-
|
124 |
event.preventDefault();
|
125 |
|
126 |
var postData = {
|
127 |
action: 'pmpro_stripe_delete_webhook',
|
128 |
-
|
129 |
}
|
130 |
|
131 |
jQuery.ajax({
|
@@ -150,16 +149,294 @@ jQuery(document).ready(function() {
|
|
150 |
}
|
151 |
}
|
152 |
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
});
|
154 |
});
|
155 |
|
156 |
// Disable the webhook buttons if the API keys aren't complete yet.
|
157 |
-
function pmpro_stripe_check_api_keys() {
|
158 |
-
if( jQuery('#stripe_publishablekey').val().length > 0 && jQuery('#stripe_secretkey').val().length > 0 ) {
|
159 |
jQuery('#pmpro_stripe_create_webhook').removeClass('disabled');
|
160 |
jQuery('#pmpro_stripe_create_webhook').addClass('button-secondary');
|
161 |
} else {
|
162 |
jQuery('#pmpro_stripe_create_webhook').removeClass('button-secondary');
|
163 |
jQuery('#pmpro_stripe_create_webhook').addClass('disabled');
|
164 |
}
|
165 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* @param text The prompt, i.e. are you sure?
|
5 |
* @param url The url to redirect to.
|
6 |
*/
|
7 |
+
function pmpro_askfirst( text, url ) {
|
8 |
var answer = window.confirm( text );
|
9 |
|
10 |
if ( answer ) {
|
43 |
* @since v2.1
|
44 |
*/
|
45 |
jQuery(document).ready(function() {
|
46 |
+
jQuery( 'input[pmpro_toggle_trigger_for]' ).on( 'change', function() {
|
47 |
pmpro_toggle_elements_by_selector( jQuery( this ).attr( 'pmpro_toggle_trigger_for' ), jQuery( this ).prop( 'checked' ) );
|
48 |
});
|
49 |
});
|
81 |
}
|
82 |
|
83 |
// Disable the webhook buttons if the API keys aren't complete yet.
|
84 |
+
jQuery('#stripe_publishablekey,#stripe_secretkey').on('change keyup', function() {
|
85 |
pmpro_stripe_check_api_keys();
|
86 |
+
});
|
87 |
+
pmpro_stripe_check_api_keys();
|
88 |
|
89 |
// AJAX call to create webhook.
|
90 |
+
jQuery('#pmpro_stripe_create_webhook').on( 'click', function(event){
|
91 |
event.preventDefault();
|
92 |
|
93 |
var postData = {
|
94 |
action: 'pmpro_stripe_create_webhook',
|
95 |
+
secretkey: pmpro_stripe_get_secretkey(),
|
96 |
}
|
|
|
97 |
jQuery.ajax({
|
98 |
type: "POST",
|
99 |
data: postData,
|
119 |
});
|
120 |
|
121 |
// AJAX call to delete webhook.
|
122 |
+
jQuery('#pmpro_stripe_delete_webhook').on( 'click', function(event){
|
123 |
event.preventDefault();
|
124 |
|
125 |
var postData = {
|
126 |
action: 'pmpro_stripe_delete_webhook',
|
127 |
+
secretkey: pmpro_stripe_get_secretkey(),
|
128 |
}
|
129 |
|
130 |
jQuery.ajax({
|
149 |
}
|
150 |
}
|
151 |
})
|
152 |
+
});
|
153 |
+
|
154 |
+
// AJAX call to rebuild webhook.
|
155 |
+
jQuery('#pmpro_stripe_rebuild_webhook').on( 'click', function(event){
|
156 |
+
event.preventDefault();
|
157 |
+
|
158 |
+
var postData = {
|
159 |
+
action: 'pmpro_stripe_rebuild_webhook',
|
160 |
+
secretkey: pmpro_stripe_get_secretkey(),
|
161 |
+
}
|
162 |
+
|
163 |
+
jQuery.ajax({
|
164 |
+
type: "POST",
|
165 |
+
data: postData,
|
166 |
+
url: ajaxurl,
|
167 |
+
success: function( response ) {
|
168 |
+
response = jQuery.parseJSON( response );
|
169 |
+
///console.log( response );
|
170 |
+
|
171 |
+
jQuery( '#pmpro_stripe_webhook_notice' ).parent('div').removeClass('error')
|
172 |
+
jQuery( '#pmpro_stripe_webhook_notice' ).parent('div').removeClass('notice-success')
|
173 |
+
|
174 |
+
if ( response.notice ) {
|
175 |
+
jQuery('#pmpro_stripe_webhook_notice').parent('div').addClass(response.notice);
|
176 |
+
}
|
177 |
+
if ( response.message ) {
|
178 |
+
jQuery('#pmpro_stripe_webhook_notice').html(response.message);
|
179 |
+
}
|
180 |
+
if ( response.success ) {
|
181 |
+
jQuery('#pmpro_stripe_create_webhook').hide();
|
182 |
+
}
|
183 |
+
}
|
184 |
+
})
|
185 |
});
|
186 |
});
|
187 |
|
188 |
// Disable the webhook buttons if the API keys aren't complete yet.
|
189 |
+
function pmpro_stripe_check_api_keys() {
|
190 |
+
if( ( jQuery('#stripe_publishablekey').val().length > 0 && jQuery('#stripe_secretkey').val().length > 0 ) || jQuery('#live_stripe_connect_secretkey').val().length > 0 ) {
|
191 |
jQuery('#pmpro_stripe_create_webhook').removeClass('disabled');
|
192 |
jQuery('#pmpro_stripe_create_webhook').addClass('button-secondary');
|
193 |
} else {
|
194 |
jQuery('#pmpro_stripe_create_webhook').removeClass('button-secondary');
|
195 |
jQuery('#pmpro_stripe_create_webhook').addClass('disabled');
|
196 |
}
|
197 |
+
}
|
198 |
+
|
199 |
+
function pmpro_stripe_get_secretkey() {
|
200 |
+
// We can't do the webhook calls with the Connect keys anyway,
|
201 |
+
// so we just look for the legacy key here.
|
202 |
+
if ( jQuery('#stripe_secretkey').val().length > 0 ) {
|
203 |
+
return jQuery('#stripe_secretkey').val();
|
204 |
+
} else {
|
205 |
+
return '';
|
206 |
+
}
|
207 |
+
}
|
208 |
+
|
209 |
+
// EMAIL TEMPLATES.
|
210 |
+
jQuery(document).ready(function($) {
|
211 |
+
|
212 |
+
/* Variables */
|
213 |
+
var template, disabled, $subject, $editor, $testemail;
|
214 |
+
$subject = $("#pmpro_email_template_subject").closest("tr");
|
215 |
+
$editor = $("#wp-email_template_body-wrap");
|
216 |
+
$testemail = $("#test_email_address").closest("tr");
|
217 |
+
|
218 |
+
$(".hide-while-loading").hide();
|
219 |
+
$(".controls").hide();
|
220 |
+
|
221 |
+
/* PMPro Email Template Switcher */
|
222 |
+
$("#pmpro_email_template_switcher").change(function() {
|
223 |
+
|
224 |
+
$(".status_message").hide();
|
225 |
+
template = $(this).val();
|
226 |
+
|
227 |
+
//get template data
|
228 |
+
if (template)
|
229 |
+
pmpro_get_template(template);
|
230 |
+
else {
|
231 |
+
$(".hide-while-loading").hide();
|
232 |
+
$(".controls").hide();
|
233 |
+
}
|
234 |
+
});
|
235 |
+
|
236 |
+
$("#pmpro_submit_template_data").click(function() {
|
237 |
+
pmpro_save_template()
|
238 |
+
});
|
239 |
+
|
240 |
+
$("#pmpro_reset_template_data").click(function() {
|
241 |
+
pmpro_reset_template();
|
242 |
+
});
|
243 |
+
|
244 |
+
$("#pmpro_email_template_disable").click(function(e) {
|
245 |
+
pmpro_disable_template();
|
246 |
+
});
|
247 |
+
|
248 |
+
$("#send_test_email").click(function(e) {
|
249 |
+
pmpro_save_template().done(setTimeout(function(){pmpro_send_test_email();}, '1000'));
|
250 |
+
});
|
251 |
+
|
252 |
+
/* Functions */
|
253 |
+
function pmpro_get_template(template) {
|
254 |
+
|
255 |
+
//hide stuff and show ajax spinner
|
256 |
+
$(".hide-while-loading").hide();
|
257 |
+
$("#pmproet-spinner").show();
|
258 |
+
|
259 |
+
//get template data
|
260 |
+
$data = {
|
261 |
+
template: template,
|
262 |
+
action: 'pmpro_email_templates_get_template_data',
|
263 |
+
security: $('input[name=security]').val()
|
264 |
+
};
|
265 |
+
|
266 |
+
//console.log( $data );
|
267 |
+
|
268 |
+
$.post(ajaxurl, $data, function(response) {
|
269 |
+
var template_data = JSON.parse(response);
|
270 |
+
|
271 |
+
//show/hide stuff
|
272 |
+
$("#pmproet-spinner").hide();
|
273 |
+
$(".controls").show();
|
274 |
+
$(".hide-while-loading").show();
|
275 |
+
$(".status").hide();
|
276 |
+
|
277 |
+
//change disable text
|
278 |
+
if (template == 'header' || template === 'footer') {
|
279 |
+
|
280 |
+
$subject.hide();
|
281 |
+
$testemail.hide();
|
282 |
+
|
283 |
+
if(template == 'header')
|
284 |
+
$("#disable_label").text("Disable email header for all PMPro emails?");
|
285 |
+
else
|
286 |
+
$("#disable_label").text("Disable email footer for all PMPro emails?");
|
287 |
+
|
288 |
+
//hide description
|
289 |
+
$("#disable_description").hide();
|
290 |
+
}
|
291 |
+
else {
|
292 |
+
$testemail.show();
|
293 |
+
$("#disable_label").text("Disable this email?");
|
294 |
+
$("#disable_description").show().text("PMPro emails with this template will not be sent.");
|
295 |
+
}
|
296 |
+
|
297 |
+
// populate help text, subject, and body
|
298 |
+
$('#pmpro_email_template_help_text').text(template_data['help_text']);
|
299 |
+
$('#pmpro_email_template_subject').val(template_data['subject']);
|
300 |
+
$('#pmpro_email_template_body').val(template_data['body']);
|
301 |
+
|
302 |
+
// disable form
|
303 |
+
disabled = template_data['disabled'];
|
304 |
+
pmpro_toggle_form_disabled(disabled);
|
305 |
+
});
|
306 |
+
}
|
307 |
+
|
308 |
+
function pmpro_save_template() {
|
309 |
+
|
310 |
+
$("#submit_template_data").attr("disabled", true);
|
311 |
+
$(".status").hide();
|
312 |
+
// console.log(template);
|
313 |
+
|
314 |
+
$data = {
|
315 |
+
template: template,
|
316 |
+
subject: $("#pmpro_email_template_subject").val(),
|
317 |
+
body: $("#pmpro_email_template_body").val(),
|
318 |
+
action: 'pmpro_email_templates_save_template_data',
|
319 |
+
security: $('input[name=security]').val()
|
320 |
+
};
|
321 |
+
$.post(ajaxurl, $data, function(response) {
|
322 |
+
if(response != 0) {
|
323 |
+
$(".status_message_wrapper").addClass('updated');
|
324 |
+
}
|
325 |
+
else {
|
326 |
+
$(".status_message_wrapper").addClass("error");
|
327 |
+
}
|
328 |
+
$("#submit_template_data").attr("disabled", false);
|
329 |
+
$(".status_message").html(response);
|
330 |
+
$(".status").show();
|
331 |
+
$(".status_message").show();
|
332 |
+
});
|
333 |
+
|
334 |
+
return $.Deferred().resolve();
|
335 |
+
}
|
336 |
+
|
337 |
+
function pmpro_reset_template() {
|
338 |
+
|
339 |
+
var r = confirm('Are you sure? Your current template settings will be deleted permanently.');
|
340 |
+
|
341 |
+
if(!r) return false;
|
342 |
+
|
343 |
+
$data = {
|
344 |
+
template: template,
|
345 |
+
action: 'pmpro_email_templates_reset_template_data',
|
346 |
+
security: $('input[name=security]').val()
|
347 |
+
};
|
348 |
+
$.post(ajaxurl, $data, function(response) {
|
349 |
+
var template_data = $.parseJSON(response);
|
350 |
+
$('#pmpro_email_template_subject').val(template_data['subject']);
|
351 |
+
$('#pmpro_email_template_body').val(template_data['body']);
|
352 |
+
});
|
353 |
+
|
354 |
+
return true;
|
355 |
+
}
|
356 |
+
|
357 |
+
function pmpro_disable_template() {
|
358 |
+
|
359 |
+
//update wp_options
|
360 |
+
data = {
|
361 |
+
template: template,
|
362 |
+
action: 'pmpro_email_templates_disable_template',
|
363 |
+
disabled: $("#pmpro_email_template_disable").is(":checked"),
|
364 |
+
security: $('input[name=security]').val()
|
365 |
+
};
|
366 |
+
|
367 |
+
$.post(ajaxurl, data, function(response) {
|
368 |
+
|
369 |
+
response = JSON.parse(response);
|
370 |
+
|
371 |
+
//failure
|
372 |
+
if(response['result'] == false) {
|
373 |
+
$(".status_message_wrapper").addClass("error");
|
374 |
+
$(".status_message").show().text("There was an error updating your template settings.");
|
375 |
+
}
|
376 |
+
else {
|
377 |
+
if(response['status'] == 'true') {
|
378 |
+
$(".status_message_wrapper").addClass("updated");
|
379 |
+
$(".status_message").show().text("Template Disabled");
|
380 |
+
}
|
381 |
+
else {
|
382 |
+
$(".status_message_wrapper").addClass("updated");
|
383 |
+
$(".status_message").show().text("Template Enabled");
|
384 |
+
}
|
385 |
+
}
|
386 |
+
|
387 |
+
$(".hide-while-loading").show();
|
388 |
+
|
389 |
+
disabled = response['status'];
|
390 |
+
|
391 |
+
pmpro_toggle_form_disabled(disabled);
|
392 |
+
});
|
393 |
+
}
|
394 |
+
|
395 |
+
function pmpro_send_test_email() {
|
396 |
+
|
397 |
+
//hide stuff and show ajax spinner
|
398 |
+
$(".hide-while-loading").hide();
|
399 |
+
$("#pmproet-spinner").show();
|
400 |
+
|
401 |
+
data = {
|
402 |
+
template: template,
|
403 |
+
email: $("#test_email_address").val(),
|
404 |
+
action: 'pmpro_email_templates_send_test',
|
405 |
+
security: $('input[name=security]').val()
|
406 |
+
};
|
407 |
+
|
408 |
+
$.post(ajaxurl, data, function(success) {
|
409 |
+
//show/hide stuff
|
410 |
+
$("#pmproet-spinner").hide();
|
411 |
+
$(".controls").show();
|
412 |
+
$(".hide-while-loading").show();
|
413 |
+
|
414 |
+
if(success) {
|
415 |
+
$(".status_message_wrapper").addClass("updated").removeClass("error");
|
416 |
+
$(".status_message").show().text("Test email sent successfully.");
|
417 |
+
}
|
418 |
+
else {
|
419 |
+
$(".status_message_wrapper").addClass("error").removeClass("updated");
|
420 |
+
$(".status_message").show().text("Test email failed.");
|
421 |
+
}
|
422 |
+
|
423 |
+
})
|
424 |
+
}
|
425 |
+
|
426 |
+
function pmpro_toggle_form_disabled(disabled) {
|
427 |
+
if(disabled == 'true') {
|
428 |
+
$("#pmpro_email_template_disable").prop('checked', true);
|
429 |
+
$("#pmpro_email_template_body").attr('readonly', 'readonly').attr('disabled', 'disabled');
|
430 |
+
$("#pmpro_email_template_subject").attr('readonly', 'readonly').attr('disabled', 'disabled');
|
431 |
+
$(".controls").hide();
|
432 |
+
}
|
433 |
+
else {
|
434 |
+
$("#pmpro_email_template_disable").prop('checked', false);
|
435 |
+
$("#pmpro_email_template_body").removeAttr('readonly','readonly').removeAttr('disabled', 'disabled');
|
436 |
+
$("#pmpro_email_template_subject").removeAttr('readonly','readonly').removeAttr('disabled', 'disabled');
|
437 |
+
$(".controls").show();
|
438 |
+
}
|
439 |
+
|
440 |
+
}
|
441 |
+
|
442 |
+
});
|
js/pmpro-login.js
CHANGED
@@ -12,7 +12,13 @@ jQuery(document).ready(function(){
|
|
12 |
|
13 |
var strength;
|
14 |
if ( pass1 != '' ) {
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
} else {
|
17 |
strength = -1;
|
18 |
}
|
@@ -66,4 +72,4 @@ jQuery(document).ready(function(){
|
|
66 |
pmpro_check_password_strength( jQuery( '#pass1' ) );
|
67 |
});
|
68 |
}
|
69 |
-
});
|
12 |
|
13 |
var strength;
|
14 |
if ( pass1 != '' ) {
|
15 |
+
// Call the disallowed list method corresponding to appropriate WP version.
|
16 |
+
const disallowedList = ( 'function' == typeof wp.passwordStrength.userInputDisallowedList )
|
17 |
+
? wp.passwordStrength.userInputDisallowedList()
|
18 |
+
: wp.passwordStrength.userInputBlacklist();
|
19 |
+
|
20 |
+
strength = wp.passwordStrength.meter( pass1, disallowedList, pass1 );
|
21 |
+
|
22 |
} else {
|
23 |
strength = -1;
|
24 |
}
|
72 |
pmpro_check_password_strength( jQuery( '#pass1' ) );
|
73 |
});
|
74 |
}
|
75 |
+
});
|
js/pmpro-stripe.js
CHANGED
@@ -5,10 +5,19 @@ jQuery( document ).ready( function( $ ) {
|
|
5 |
|
6 |
var stripe, elements, cardNumber, cardExpiry, cardCvc;
|
7 |
|
8 |
-
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
elements = stripe.elements();
|
11 |
|
|
|
|
|
|
|
12 |
// Create Elements.
|
13 |
cardNumber = elements.create('cardNumber');
|
14 |
cardExpiry = elements.create('cardExpiry');
|
@@ -25,35 +34,39 @@ jQuery( document ).ready( function( $ ) {
|
|
25 |
cardCvc.mount('#CVV');
|
26 |
}
|
27 |
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
if ( 'undefined' !== typeof( pmproStripe.paymentIntent ) ) {
|
30 |
if ( 'requires_action' === pmproStripe.paymentIntent.status ) {
|
31 |
-
|
32 |
-
$('input[type=submit]', this).attr('disabled', 'disabled');
|
33 |
-
$('input[type=image]', this).attr('disabled', 'disabled');
|
34 |
-
$('#pmpro_processing_message').css('visibility', 'visible');
|
35 |
stripe.handleCardAction( pmproStripe.paymentIntent.client_secret )
|
36 |
-
.then(
|
37 |
}
|
38 |
}
|
39 |
-
|
40 |
-
// Handle authentication for subscription if required.
|
41 |
if ( 'undefined' !== typeof( pmproStripe.setupIntent ) ) {
|
42 |
if ( 'requires_action' === pmproStripe.setupIntent.status ) {
|
43 |
-
|
44 |
-
$('input[type=submit]', this).attr('disabled', 'disabled');
|
45 |
-
$('input[type=image]', this).attr('disabled', 'disabled');
|
46 |
-
$('#pmpro_processing_message').css('visibility', 'visible');
|
47 |
stripe.handleCardSetup( pmproStripe.setupIntent.client_secret )
|
48 |
-
.then(
|
49 |
}
|
50 |
}
|
51 |
|
|
|
|
|
|
|
52 |
// Set require billing var if not set yet.
|
53 |
if ( typeof pmpro_require_billing === 'undefined' ) {
|
54 |
pmpro_require_billing = pmproStripe.pmpro_require_billing;
|
55 |
}
|
56 |
-
|
57 |
$( '.pmpro_form' ).submit( function( event ) {
|
58 |
var name, address;
|
59 |
|
@@ -62,7 +75,7 @@ jQuery( document ).ready( function( $ ) {
|
|
62 |
|
63 |
// Double check in case a discount code made the level free.
|
64 |
if ( typeof pmpro_require_billing === 'undefined' || pmpro_require_billing ) {
|
65 |
-
|
66 |
if ( pmproStripe.verifyAddress ) {
|
67 |
address = {
|
68 |
line1: $( '#baddress1' ).val(),
|
@@ -78,13 +91,14 @@ jQuery( document ).ready( function( $ ) {
|
|
78 |
if ( $( '#bfirstname' ).length && $( '#blastname' ).length ) {
|
79 |
name = $.trim( $( '#bfirstname' ).val() + ' ' + $( '#blastname' ).val() );
|
80 |
}
|
81 |
-
|
|
|
82 |
stripe.createPaymentMethod( 'card', cardNumber, {
|
83 |
billing_details: {
|
84 |
address: address,
|
85 |
name: name,
|
86 |
}
|
87 |
-
}).then(
|
88 |
|
89 |
// Prevent the form from submitting with the default action.
|
90 |
return false;
|
@@ -94,15 +108,102 @@ jQuery( document ).ready( function( $ ) {
|
|
94 |
}
|
95 |
});
|
96 |
|
97 |
-
|
98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
-
var form, data, card, paymentMethodId
|
101 |
|
102 |
form = $('#pmpro_form, .pmpro_form');
|
103 |
|
104 |
if (response.error) {
|
105 |
-
|
106 |
// Re-enable the submit button.
|
107 |
$('.pmpro_btn-submit-checkout,.pmpro_btn-submit').removeAttr('disabled');
|
108 |
|
@@ -113,7 +214,7 @@ jQuery( document ).ready( function( $ ) {
|
|
113 |
$( '#pmpro_message' ).text( response.error.message ).addClass( 'pmpro_error' ).removeClass( 'pmpro_alert' ).removeClass( 'pmpro_success' ).show();
|
114 |
|
115 |
} else if ( response.paymentMethod ) {
|
116 |
-
|
117 |
paymentMethodId = response.paymentMethod.id;
|
118 |
card = response.paymentMethod.card;
|
119 |
|
@@ -136,14 +237,10 @@ jQuery( document ).ready( function( $ ) {
|
|
136 |
form.get(0).submit();
|
137 |
|
138 |
} else if ( response.paymentIntent || response.setupIntent ) {
|
139 |
-
|
140 |
// success message
|
141 |
$( '#pmpro_message' ).text( pmproStripe.msgAuthenticationValidated ).addClass( 'pmpro_success' ).removeClass( 'pmpro_alert' ).removeClass( 'pmpro_error' ).show();
|
142 |
-
|
143 |
-
customerId = pmproStripe.paymentIntent
|
144 |
-
? pmproStripe.paymentIntent.customer
|
145 |
-
: pmproStripe.setupIntent.customer;
|
146 |
-
|
147 |
paymentMethodId = pmproStripe.paymentIntent
|
148 |
? pmproStripe.paymentIntent.payment_method.id
|
149 |
: pmproStripe.setupIntent.payment_method.id;
|
@@ -152,17 +249,13 @@ jQuery( document ).ready( function( $ ) {
|
|
152 |
? pmproStripe.paymentIntent.payment_method.card
|
153 |
: pmproStripe.setupIntent.payment_method.card;
|
154 |
|
155 |
-
|
156 |
form.append( '<input type="hidden" name="payment_intent_id" value="' + pmproStripe.paymentIntent.id + '" />' );
|
157 |
}
|
158 |
if ( pmproStripe.setupIntent ) {
|
159 |
form.append( '<input type="hidden" name="setup_intent_id" value="' + pmproStripe.setupIntent.id + '" />' );
|
160 |
-
form.append( '<input type="hidden" name="subscription_id" value="' + pmproStripe.subscription.id + '" />' );
|
161 |
}
|
162 |
|
163 |
-
// Insert the Customer ID into the form so it gets submitted to the server.
|
164 |
-
form.append( '<input type="hidden" name="customer_id" value="' + customerId + '" />' );
|
165 |
-
|
166 |
// Insert the PaymentMethod ID into the form so it gets submitted to the server.
|
167 |
form.append( '<input type="hidden" name="payment_method_id" value="' + paymentMethodId + '" />' );
|
168 |
|
5 |
|
6 |
var stripe, elements, cardNumber, cardExpiry, cardCvc;
|
7 |
|
8 |
+
/**
|
9 |
+
* Identify with Stripe.
|
10 |
+
*/
|
11 |
+
if ( pmproStripe.user_id ) {
|
12 |
+
stripe = Stripe( pmproStripe.publishableKey, { stripeAccount: pmproStripe.user_id, locale: 'auto' } );
|
13 |
+
} else {
|
14 |
+
stripe = Stripe( pmproStripe.publishableKey, { locale: 'auto' } );
|
15 |
+
}
|
16 |
elements = stripe.elements();
|
17 |
|
18 |
+
/**
|
19 |
+
* Set up default credit card fields.
|
20 |
+
*/
|
21 |
// Create Elements.
|
22 |
cardNumber = elements.create('cardNumber');
|
23 |
cardExpiry = elements.create('cardExpiry');
|
34 |
cardCvc.mount('#CVV');
|
35 |
}
|
36 |
|
37 |
+
/**
|
38 |
+
* Handle request for card authentication. Only used after initial
|
39 |
+
* checkout form has been submitted with a valid payment method.
|
40 |
+
*/
|
41 |
+
function pmpro_set_checkout_for_stripe_card_authentication() {
|
42 |
+
$('input[type=submit]', this).attr('disabled', 'disabled');
|
43 |
+
$('input[type=image]', this).attr('disabled', 'disabled');
|
44 |
+
$('#pmpro_processing_message').css('visibility', 'visible');
|
45 |
+
}
|
46 |
+
// Check if payment intent (charge) requires authentication.
|
47 |
if ( 'undefined' !== typeof( pmproStripe.paymentIntent ) ) {
|
48 |
if ( 'requires_action' === pmproStripe.paymentIntent.status ) {
|
49 |
+
pmpro_set_checkout_for_stripe_card_authentication();
|
|
|
|
|
|
|
50 |
stripe.handleCardAction( pmproStripe.paymentIntent.client_secret )
|
51 |
+
.then( pmpro_stripeResponseHandler );
|
52 |
}
|
53 |
}
|
54 |
+
// Check if payment intent (subscription) requires authentication.
|
|
|
55 |
if ( 'undefined' !== typeof( pmproStripe.setupIntent ) ) {
|
56 |
if ( 'requires_action' === pmproStripe.setupIntent.status ) {
|
57 |
+
pmpro_set_checkout_for_stripe_card_authentication();
|
|
|
|
|
|
|
58 |
stripe.handleCardSetup( pmproStripe.setupIntent.client_secret )
|
59 |
+
.then( pmpro_stripeResponseHandler );
|
60 |
}
|
61 |
}
|
62 |
|
63 |
+
/**
|
64 |
+
* Set up submit behavior for checkout form.
|
65 |
+
*/
|
66 |
// Set require billing var if not set yet.
|
67 |
if ( typeof pmpro_require_billing === 'undefined' ) {
|
68 |
pmpro_require_billing = pmproStripe.pmpro_require_billing;
|
69 |
}
|
|
|
70 |
$( '.pmpro_form' ).submit( function( event ) {
|
71 |
var name, address;
|
72 |
|
75 |
|
76 |
// Double check in case a discount code made the level free.
|
77 |
if ( typeof pmpro_require_billing === 'undefined' || pmpro_require_billing ) {
|
78 |
+
// Get the data needed to create a payment method for this checkout.
|
79 |
if ( pmproStripe.verifyAddress ) {
|
80 |
address = {
|
81 |
line1: $( '#baddress1' ).val(),
|
91 |
if ( $( '#bfirstname' ).length && $( '#blastname' ).length ) {
|
92 |
name = $.trim( $( '#bfirstname' ).val() + ' ' + $( '#blastname' ).val() );
|
93 |
}
|
94 |
+
|
95 |
+
// Create the payment method.
|
96 |
stripe.createPaymentMethod( 'card', cardNumber, {
|
97 |
billing_details: {
|
98 |
address: address,
|
99 |
name: name,
|
100 |
}
|
101 |
+
}).then( pmpro_stripeResponseHandler );
|
102 |
|
103 |
// Prevent the form from submitting with the default action.
|
104 |
return false;
|
108 |
}
|
109 |
});
|
110 |
|
111 |
+
/**
|
112 |
+
* Set up payment request button.
|
113 |
+
*/
|
114 |
+
// Check if Payment Request Button is enabled.
|
115 |
+
if ( $('#payment-request-button').length ) {
|
116 |
+
var paymentRequest = null;
|
117 |
+
|
118 |
+
// Get the level price so that information can be shown in payment request popup
|
119 |
+
jQuery.noConflict().ajax({
|
120 |
+
url: pmproStripe.restUrl + 'pmpro/v1/checkout_levels',
|
121 |
+
dataType: 'json',
|
122 |
+
data: jQuery( "#pmpro_form" ).serialize(),
|
123 |
+
success: function(data) {
|
124 |
+
if ( data.hasOwnProperty('initial_payment') ) {
|
125 |
+
// Build payment request button.
|
126 |
+
paymentRequest = stripe.paymentRequest({
|
127 |
+
country: pmproStripe.accountCountry,
|
128 |
+
currency: pmproStripe.currency,
|
129 |
+
total: {
|
130 |
+
label: pmproStripe.siteName,
|
131 |
+
amount: Math.round( data.initial_payment * 100 ),
|
132 |
+
},
|
133 |
+
requestPayerName: true,
|
134 |
+
requestPayerEmail: true,
|
135 |
+
});
|
136 |
+
var prButton = elements.create('paymentRequestButton', {
|
137 |
+
paymentRequest: paymentRequest,
|
138 |
+
});
|
139 |
+
// Mount payment request button.
|
140 |
+
paymentRequest.canMakePayment().then(function(result) {
|
141 |
+
if (result) {
|
142 |
+
prButton.mount('#payment-request-button');
|
143 |
+
} else {
|
144 |
+
$('#payment-request-button').hide();
|
145 |
+
}
|
146 |
+
});
|
147 |
+
// Handle payment request button confirmation.
|
148 |
+
paymentRequest.on('paymentmethod', function( event ) {
|
149 |
+
// Do not let customer submit the form again.
|
150 |
+
$('#pmpro_btn-submit').attr('disabled', 'disabled');
|
151 |
+
$('#pmpro_processing_message').css('visibility', 'visible');
|
152 |
+
$('#payment-request-button').hide();
|
153 |
+
/*
|
154 |
+
Close the payment request interface immeditately. This is not the intended
|
155 |
+
implementation from Stripe, but we are submitting the payment method
|
156 |
+
through our default checkout process instead of letting Stripe
|
157 |
+
process it through the payment request button. Closing immediately also
|
158 |
+
prevents timeouts during the payment request workflow that have caused
|
159 |
+
issues on slower sites in the past.
|
160 |
+
*/
|
161 |
+
event.complete('success');
|
162 |
+
pmpro_stripeResponseHandler( event );
|
163 |
+
});
|
164 |
+
}
|
165 |
+
}
|
166 |
+
});
|
167 |
+
// Hide payment request button on form submit to prevent double charges.
|
168 |
+
jQuery('form').submit(function(){
|
169 |
+
jQuery('#payment-request-button').hide();
|
170 |
+
});
|
171 |
+
// Update price shown in payment request button if price changes.
|
172 |
+
function stripeUpdatePaymentRequestButton() {
|
173 |
+
jQuery.noConflict().ajax({
|
174 |
+
url: pmproStripe.restUrl + 'pmpro/v1/checkout_levels',
|
175 |
+
dataType: 'json',
|
176 |
+
data: jQuery( "#pmpro_form" ).serialize(),
|
177 |
+
success: function(data) {
|
178 |
+
if ( data.hasOwnProperty('initial_payment') ) {
|
179 |
+
paymentRequest.update({
|
180 |
+
total: {
|
181 |
+
label: pmproStripe.siteName,
|
182 |
+
amount: Math.round( data.initial_payment * 100 ),
|
183 |
+
},
|
184 |
+
});
|
185 |
+
}
|
186 |
+
}
|
187 |
+
});
|
188 |
+
}
|
189 |
+
if ( pmproStripe.updatePaymentRequestButton ) {
|
190 |
+
$(".pmpro_alter_price").change(function(){
|
191 |
+
stripeUpdatePaymentRequestButton();
|
192 |
+
});
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Handle the response from Stripe.
|
198 |
+
*/
|
199 |
+
function pmpro_stripeResponseHandler( response ) {
|
200 |
|
201 |
+
var form, data, card, paymentMethodId;
|
202 |
|
203 |
form = $('#pmpro_form, .pmpro_form');
|
204 |
|
205 |
if (response.error) {
|
206 |
+
// There was an issue with the payment method supplied or card authentication failed.
|
207 |
// Re-enable the submit button.
|
208 |
$('.pmpro_btn-submit-checkout,.pmpro_btn-submit').removeAttr('disabled');
|
209 |
|
214 |
$( '#pmpro_message' ).text( response.error.message ).addClass( 'pmpro_error' ).removeClass( 'pmpro_alert' ).removeClass( 'pmpro_success' ).show();
|
215 |
|
216 |
} else if ( response.paymentMethod ) {
|
217 |
+
// A payment method was created successfully. Submit the checkout form and finish the checkout in PHP.
|
218 |
paymentMethodId = response.paymentMethod.id;
|
219 |
card = response.paymentMethod.card;
|
220 |
|
237 |
form.get(0).submit();
|
238 |
|
239 |
} else if ( response.paymentIntent || response.setupIntent ) {
|
240 |
+
// Card authentication was successful. Finish the checkout in PHP.
|
241 |
// success message
|
242 |
$( '#pmpro_message' ).text( pmproStripe.msgAuthenticationValidated ).addClass( 'pmpro_success' ).removeClass( 'pmpro_alert' ).removeClass( 'pmpro_error' ).show();
|
243 |
+
|
|
|
|
|
|
|
|
|
244 |
paymentMethodId = pmproStripe.paymentIntent
|
245 |
? pmproStripe.paymentIntent.payment_method.id
|
246 |
: pmproStripe.setupIntent.payment_method.id;
|
249 |
? pmproStripe.paymentIntent.payment_method.card
|
250 |
: pmproStripe.setupIntent.payment_method.card;
|
251 |
|
252 |
+
if ( pmproStripe.paymentIntent ) {
|
253 |
form.append( '<input type="hidden" name="payment_intent_id" value="' + pmproStripe.paymentIntent.id + '" />' );
|
254 |
}
|
255 |
if ( pmproStripe.setupIntent ) {
|
256 |
form.append( '<input type="hidden" name="setup_intent_id" value="' + pmproStripe.setupIntent.id + '" />' );
|
|
|
257 |
}
|
258 |
|
|
|
|
|
|
|
259 |
// Insert the PaymentMethod ID into the form so it gets submitted to the server.
|
260 |
form.append( '<input type="hidden" name="payment_method_id" value="' + paymentMethodId + '" />' );
|
261 |
|
languages/email/de_DE/admin_change.html
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
-
<p>Ein Administrator von !!sitename!! hat Ihr Paket
|
2 |
|
3 |
<p>!!membership_change!!.</p>
|
4 |
|
5 |
-
<p>Wenn Sie diese
|
6 |
|
7 |
-
<p>Hier
|
1 |
+
<p>Ein Administrator von !!sitename!! hat Ihr Paket geändert.</p>
|
2 |
|
3 |
<p>!!membership_change!!.</p>
|
4 |
|
5 |
+
<p>Wenn Sie diese Änderung nicht veranlasst haben und mehr Informationen benötigen, kotaktieren Sie uns bitte unter !!siteemail!!</p>
|
6 |
|
7 |
+
<p>Hier können Sie sich in Ihren Account einloggen: !!login_link!!</p>
|
languages/email/de_DE/admin_change_admin.html
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<p>Ein Administrator von !!sitename!! hat das Paket
|
2 |
|
3 |
<p>!!membership_change!!.</p>
|
4 |
|
1 |
+
<p>Ein Administrator von !!sitename!! hat das Paket geändert.</p>
|
2 |
|
3 |
<p>!!membership_change!!.</p>
|
4 |
|
languages/email/de_DE/billing.html
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<p>Ihre Zahlungsinformationen bei !!sitename!! wurden
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>
|
@@ -8,9 +8,9 @@
|
|
8 |
|
9 |
<p>
|
10 |
!!cardtype!!: !!accountnumber!!<br />
|
11 |
-
|
12 |
</p>
|
13 |
|
14 |
-
<p>Wenn Sie diese
|
15 |
|
16 |
-
<p>Hier
|
1 |
+
<p>Ihre Zahlungsinformationen bei !!sitename!! wurden geändert.</p>
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>
|
8 |
|
9 |
<p>
|
10 |
!!cardtype!!: !!accountnumber!!<br />
|
11 |
+
Gültig bis: !!expirationmonth!!/!!expirationyear!!
|
12 |
</p>
|
13 |
|
14 |
+
<p>Wenn Sie diese Änderung nicht veranlasst haben, kontaktieren Sie uns bitte unter !!siteemail!!</p>
|
15 |
|
16 |
+
<p>Hier können Sie sich in Ihren Account einloggen: !!login_link!!</p>
|
languages/email/de_DE/billing_admin.html
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<p>Die Zahlungsinformationen
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>
|
@@ -11,7 +11,7 @@
|
|
11 |
|
12 |
<p>
|
13 |
!!cardtype!!: !!accountnumber!!<br />
|
14 |
-
|
15 |
</p>
|
16 |
|
17 |
<p>Wordpress Login: !!login_link!!</p>
|
1 |
+
<p>Die Zahlungsinformationen für !!display_name!! bei !!sitename!! wurden geändert.</p>
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>
|
11 |
|
12 |
<p>
|
13 |
!!cardtype!!: !!accountnumber!!<br />
|
14 |
+
Gültig bis: !!expirationmonth!!/!!expirationyear!!
|
15 |
</p>
|
16 |
|
17 |
<p>Wordpress Login: !!login_link!!</p>
|
languages/email/de_DE/billing_failure.html
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<p>Die aktuelle Abo-Zahlung
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>Die aktuell bei uns hinterlegten Zahlungsinformationen lauten:</p>
|
@@ -7,5 +7,5 @@
|
|
7 |
|
8 |
<p>
|
9 |
!!cardtype!!: !!accountnumber!!<br />
|
10 |
-
|
11 |
</p>
|
1 |
+
<p>Die aktuelle Abo-Zahlung für ihr Paket auf !!sitename!! ist fehlgeschlagen. <strong>Klicken Sie bitte auf den folgenden Link, um sich einzuloggen und Ihre Zahlungsinformationen zu aktualisieren, da Ihr Account sonst gesperrt wird: !!login_link!!</strong></p>
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>Die aktuell bei uns hinterlegten Zahlungsinformationen lauten:</p>
|
7 |
|
8 |
<p>
|
9 |
!!cardtype!!: !!accountnumber!!<br />
|
10 |
+
Gültig bis: !!expirationmonth!!/!!expirationyear!!
|
11 |
</p>
|
languages/email/de_DE/billing_failure_admin.html
CHANGED
@@ -7,5 +7,5 @@
|
|
7 |
|
8 |
<p>
|
9 |
!!cardtype!!: !!accountnumber!!<br />
|
10 |
-
|
11 |
</p>
|
7 |
|
8 |
<p>
|
9 |
!!cardtype!!: !!accountnumber!!<br />
|
10 |
+
Gültig bis: !!expirationmonth!!/!!expirationyear!!
|
11 |
</p>
|
languages/email/de_DE/cancel.html
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
<p>Ihr Account bei !!sitename!! wurde
|
2 |
|
3 |
-
<p>Wenn Sie diese
|
1 |
+
<p>Ihr Account bei !!sitename!! wurde gelöscht.</p>
|
2 |
|
3 |
+
<p>Wenn Sie diese Löschung nicht veranlasst haben und Sie mehr Informationen benötigen, kontaktieren Sie uns bitte unter !!siteemail!!</p>
|
languages/email/de_DE/cancel_admin.html
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
-
<p>Der Zugang
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>Paket: !!membership_level_name!!</p>
|
5 |
<p>Datum der Anmeldung: !!startdate!!</p>
|
6 |
-
<p>Datum der
|
7 |
|
8 |
<p>Wordpress Login: !!login_link!!</p>
|
1 |
+
<p>Der Zugang für !!user_login!! bei !!sitename!! wurde gelöscht.</p>
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>Paket: !!membership_level_name!!</p>
|
5 |
<p>Datum der Anmeldung: !!startdate!!</p>
|
6 |
+
<p>Datum der Löschung: !!enddate!!</p>
|
7 |
|
8 |
<p>Wordpress Login: !!login_link!!</p>
|
languages/email/de_DE/checkout_check.html
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
-
<p>Danke
|
2 |
|
3 |
!!instructions!!
|
4 |
|
5 |
-
<p>Untenstehend finden Sie die Details zu Ihrem Account und eine Rechnung
|
6 |
|
7 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
8 |
<p>Paket: !!membership_level_name!!</p>
|
@@ -14,4 +14,4 @@
|
|
14 |
Gesamt: !!invoice_total!!
|
15 |
</p>
|
16 |
|
17 |
-
<p>Hier
|
1 |
+
<p>Danke für Ihre Anmeldung bei !!sitename!!. Ihr Zugang ist nun aktiv.</p>
|
2 |
|
3 |
!!instructions!!
|
4 |
|
5 |
+
<p>Untenstehend finden Sie die Details zu Ihrem Account und eine Rechnung für Ihre Zahlung.</p>
|
6 |
|
7 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
8 |
<p>Paket: !!membership_level_name!!</p>
|
14 |
Gesamt: !!invoice_total!!
|
15 |
</p>
|
16 |
|
17 |
+
<p>Hier können Sie sich in Ihren Account einloggen: !!login_link!!</p>
|
languages/email/de_DE/checkout_check_admin.html
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
<p>Es gibt eine neue Registrierung bei !!sitename!!.</p>
|
2 |
|
3 |
-
<p><strong>Als Zahlungsart wurde die Zahlung per Scheck
|
4 |
|
5 |
-
<p>Untenstehend die Details
|
6 |
|
7 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
8 |
<p>Paket: !!membership_level_name!!</p>
|
1 |
<p>Es gibt eine neue Registrierung bei !!sitename!!.</p>
|
2 |
|
3 |
+
<p><strong>Als Zahlungsart wurde die Zahlung per Scheck ausgewählt.</strong></p>
|
4 |
|
5 |
+
<p>Untenstehend die Details über den neuen Account und die Rechnung für die aktuelle Zahlung.</p>
|
6 |
|
7 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
8 |
<p>Paket: !!membership_level_name!!</p>
|
languages/email/de_DE/checkout_express.html
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
-
<p>Vielen Dank
|
2 |
-
<p>Untenstehend finden Sie die Details zu Ihrem Account und eine Rechnung
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
@@ -11,4 +11,4 @@
|
|
11 |
Gesamt: !!invoice_total!!
|
12 |
</p>
|
13 |
|
14 |
-
<p>Hier
|
1 |
+
<p>Vielen Dank für Ihre Anmeldung bei !!sitename!!. Ihr Zugang ist nun aktiv.</p>
|
2 |
+
<p>Untenstehend finden Sie die Details zu Ihrem Account und eine Rechnung für Ihre Zahlung.</p>
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
11 |
Gesamt: !!invoice_total!!
|
12 |
</p>
|
13 |
|
14 |
+
<p>Hier können Sie sich in Ihren Account einloggen: !!login_link!!</p>
|
languages/email/de_DE/checkout_express_admin.html
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<p>Es gibt eine neue Registrierung bei !!sitename!!.</p>
|
2 |
-
<p>Untenstehend die Details
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
@@ -7,7 +7,7 @@
|
|
7 |
!!membership_expiration!! !!discount_code!!
|
8 |
|
9 |
<p>
|
10 |
-
|
11 |
Gesamt: !!invoice_total!!
|
12 |
</p>
|
13 |
|
1 |
<p>Es gibt eine neue Registrierung bei !!sitename!!.</p>
|
2 |
+
<p>Untenstehend die Details über den neuen Account und die Rechnung für die aktuelle Zahlung.</p>
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
7 |
!!membership_expiration!! !!discount_code!!
|
8 |
|
9 |
<p>
|
10 |
+
Rechnung #!!invoice_id!! am !!invoice_date!!<br />
|
11 |
Gesamt: !!invoice_total!!
|
12 |
</p>
|
13 |
|
languages/email/de_DE/checkout_free.html
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
-
<p>Vielen Dank
|
2 |
<p>Untenstehend die Details zu Ihrem Account.</p>
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
6 |
!!membership_expiration!! !!discount_code!!
|
7 |
|
8 |
-
<p>Hier
|
1 |
+
<p>Vielen Dank für Ihre Anmeldung bei !!sitename!!. Ihr Zugang ist nun aktiv.</p>
|
2 |
<p>Untenstehend die Details zu Ihrem Account.</p>
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
6 |
!!membership_expiration!! !!discount_code!!
|
7 |
|
8 |
+
<p>Hier können Sie sich in Ihren Account einloggen: !!login_link!!</p>
|
languages/email/de_DE/checkout_free_admin.html
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<p>Es gibt eine neue Registrierung bei !!sitename!!.</p>
|
2 |
-
<p>Untenstehend die Details
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
1 |
<p>Es gibt eine neue Registrierung bei !!sitename!!.</p>
|
2 |
+
<p>Untenstehend die Details über den neuen Account.</p>
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
languages/email/de_DE/checkout_freetrial.html
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<p>Vielen Dank
|
2 |
<p>Untenstehend finden Sie die Details zu Ihrem Account.</p>
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
@@ -13,7 +13,7 @@
|
|
13 |
|
14 |
<p>
|
15 |
!!cardtype!!: !!accountnumber!!<br />
|
16 |
-
|
17 |
</p>
|
18 |
|
19 |
-
<p>Hier
|
1 |
+
<p>Vielen Dank für Ihre Anmeldung bei !!sitename!!. Ihr Zugang ist nun aktiv.</p>
|
2 |
<p>Untenstehend finden Sie die Details zu Ihrem Account.</p>
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
13 |
|
14 |
<p>
|
15 |
!!cardtype!!: !!accountnumber!!<br />
|
16 |
+
Gültig bis: !!expirationmonth!!/!!expirationyear!!
|
17 |
</p>
|
18 |
|
19 |
+
<p>Hier können Sie sich in Ihren Account einloggen: !!login_link!!</p>
|
languages/email/de_DE/checkout_freetrial_admin.html
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<p>Es gibt eine neue Registrierung bei !!sitename!!.</p>
|
2 |
-
<p>Untenstehend die Details
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
@@ -13,7 +13,7 @@
|
|
13 |
|
14 |
<p>
|
15 |
!!cardtype!!: !!accountnumber!!<br />
|
16 |
-
|
17 |
</p>
|
18 |
|
19 |
<p>Wordpress Login: !!login_link!!</p>
|
1 |
<p>Es gibt eine neue Registrierung bei !!sitename!!.</p>
|
2 |
+
<p>Untenstehend die Details über den neuen Account und die Rechnung für die aktuelle Zahlung.</p>
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
13 |
|
14 |
<p>
|
15 |
!!cardtype!!: !!accountnumber!!<br />
|
16 |
+
Gültig bis: !!expirationmonth!!/!!expirationyear!!
|
17 |
</p>
|
18 |
|
19 |
<p>Wordpress Login: !!login_link!!</p>
|
languages/email/de_DE/checkout_paid.html
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
-
<p>Vielen Dank
|
2 |
-
<p>Untenstehend finden Sie die Details zu Ihrem Account und eine Rechnung
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
@@ -17,7 +17,7 @@
|
|
17 |
|
18 |
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
-
|
21 |
</p>
|
22 |
|
23 |
-
<p>Hier
|
1 |
+
<p>Vielen Dank für Ihre Anmeldung bei !!sitename!!. Ihr Zugang ist nun aktiv.</p>
|
2 |
+
<p>Untenstehend finden Sie die Details zu Ihrem Account und eine Rechnung für Ihre Zahlung.</p>
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
17 |
|
18 |
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
+
Gültig bis: !!expirationmonth!!/!!expirationyear!!
|
21 |
</p>
|
22 |
|
23 |
+
<p>Hier können Sie sich in Ihren Account einloggen: !!login_link!!</p>
|
languages/email/de_DE/checkout_paid_admin.html
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<p>Es gibt eine neue Registrierung bei !!sitename!!.</p>
|
2 |
-
<p>Untenstehend die Details
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
@@ -17,7 +17,7 @@
|
|
17 |
|
18 |
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
-
|
21 |
</p>
|
22 |
|
23 |
<p>Wordpress Login: !!login_link!!</p>
|
1 |
<p>Es gibt eine neue Registrierung bei !!sitename!!.</p>
|
2 |
+
<p>Untenstehend die Details über den neuen Account und die Rechnung für die aktuelle Zahlung.</p>
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
17 |
|
18 |
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
+
Gültig bis: !!expirationmonth!!/!!expirationyear!!
|
21 |
</p>
|
22 |
|
23 |
<p>Wordpress Login: !!login_link!!</p>
|
languages/email/de_DE/checkout_trial.html
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
-
<p>Vielen Dank
|
2 |
-
<p>Untenstehend finden Sie die Details zu Ihrem Account und eine Rechnung
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
@@ -17,7 +17,7 @@
|
|
17 |
|
18 |
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
-
|
21 |
</p>
|
22 |
|
23 |
-
<p>Hier
|
1 |
+
<p>Vielen Dank für Ihre Anmeldung bei !!sitename!!. Ihr Zugang ist nun aktiv.</p>
|
2 |
+
<p>Untenstehend finden Sie die Details zu Ihrem Account und eine Rechnung für Ihre Zahlung.</p>
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
17 |
|
18 |
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
+
Gültig bis: !!expirationmonth!!/!!expirationyear!!
|
21 |
</p>
|
22 |
|
23 |
+
<p>Hier können Sie sich in Ihren Account einloggen: !!login_link!!</p>
|
languages/email/de_DE/checkout_trial_admin.html
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<p>Es gibt eine neue Registrierung bei !!sitename!!.</p>
|
2 |
-
<p>Untenstehend die Details
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
@@ -17,7 +17,7 @@
|
|
17 |
|
18 |
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
-
|
21 |
</p>
|
22 |
|
23 |
<p>Wordpress Login: !!login_link!!</p>
|
1 |
<p>Es gibt eine neue Registrierung bei !!sitename!!.</p>
|
2 |
+
<p>Untenstehend die Details über den neuen Account und die Rechnung für die aktuelle Zahlung.</p>
|
3 |
|
4 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
5 |
<p>Paket: !!membership_level_name!!</p>
|
17 |
|
18 |
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
+
Gültig bis: !!expirationmonth!!/!!expirationyear!!
|
21 |
</p>
|
22 |
|
23 |
<p>Wordpress Login: !!login_link!!</p>
|
languages/email/de_DE/credit_card_expiring.html
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<p>Die
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>Ihre aktuellen Zahlungsinformationen:</p>
|
@@ -9,5 +9,5 @@
|
|
9 |
|
10 |
<p>
|
11 |
!!cardtype!!: !!accountnumber!!<br />
|
12 |
-
|
13 |
</p>
|
1 |
+
<p>Die Gültigkeit der Kreditkarte, die Sie für Ihren Zugang bei !!sitename!! angegeben haben, wird in Kürze ablaufen. <strong>Klicken Sie bitte auf den folgenden Link, um Ihre Zahlungsinformationen zu aktualisieren, damit Ihr Account nicht deaktiviert wird: !!login_link!!</strong></p>
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>Ihre aktuellen Zahlungsinformationen:</p>
|
9 |
|
10 |
<p>
|
11 |
!!cardtype!!: !!accountnumber!!<br />
|
12 |
+
Gültig bis: !!expirationmonth!!/!!expirationyear!!
|
13 |
</p>
|
languages/email/de_DE/footer.html
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
<p>
|
2 |
-
|
3 |
Ihr !!sitename!! Team
|
4 |
</p>
|
1 |
<p>
|
2 |
+
Mit freundlichen Grüßen,<br />
|
3 |
Ihr !!sitename!! Team
|
4 |
</p>
|
languages/email/de_DE/invoice.html
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
-
<p>Vielen Dank
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>
|
5 |
-
Rechnung #!!invoice_id!!
|
6 |
Gesamt: !!invoice_total!!
|
7 |
</p>
|
8 |
<p>
|
@@ -12,8 +12,8 @@
|
|
12 |
|
13 |
<p>
|
14 |
!!cardtype!!: !!accountnumber!!<br />
|
15 |
-
|
16 |
</p>
|
17 |
|
18 |
-
<p>Hier
|
19 |
<p>Um diese Rechnung online abzurufen, klicken Sie bitte hier: !!invoice_link!!</p>
|
1 |
+
<p>Vielen Dank für Ihre Anmeldung bei !!sitename!!. Untenstehend finden Sie die Rechnung zur Ihrer aktuellen Zahlung.</p>
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>
|
5 |
+
Rechnung #!!invoice_id!! vom !!invoice_date!!<br />
|
6 |
Gesamt: !!invoice_total!!
|
7 |
</p>
|
8 |
<p>
|
12 |
|
13 |
<p>
|
14 |
!!cardtype!!: !!accountnumber!!<br />
|
15 |
+
Gültig bis: !!expirationmonth!!/!!expirationyear!!
|
16 |
</p>
|
17 |
|
18 |
+
<p>Hier können Sie sich in Ihren Account einloggen: !!login_link!!</p>
|
19 |
<p>Um diese Rechnung online abzurufen, klicken Sie bitte hier: !!invoice_link!!</p>
|
languages/email/de_DE/membership_expired.html
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<p>Ihr Zugang auf !!sitename!! ist abgelaufen.</p>
|
2 |
|
3 |
-
<p>Vielen Dank
|
4 |
|
5 |
<p>Unsere aktuellen Konditionen finden Sie hier: !!levels_link!!</p>
|
6 |
|
7 |
-
<p>Hier
|
1 |
<p>Ihr Zugang auf !!sitename!! ist abgelaufen.</p>
|
2 |
|
3 |
+
<p>Vielen Dank für Ihre Unterstützung.</p>
|
4 |
|
5 |
<p>Unsere aktuellen Konditionen finden Sie hier: !!levels_link!!</p>
|
6 |
|
7 |
+
<p>Hier können Sie sich in Ihren Account einloggen: !!login_link!!</p>
|
languages/email/de_DE/membership_expiring.html
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
-
<p>Vielen Dank
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>Paket: !!membership_level_name!!</p>
|
5 |
|
6 |
-
<p>Hier
|
1 |
+
<p>Vielen Dank für Ihre Anmeldung bei !!sitename!!. Dies ist eine Erinnerung, dass Ihr Zugang am !!enddate!! abläuft.</p>
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>Paket: !!membership_level_name!!</p>
|
5 |
|
6 |
+
<p>Hier können Sie sich in Ihren Account einloggen: !!login_link!!</p>
|
languages/email/de_DE/trial_ending.html
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
-
<p>Vielen Dank
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>Paket: !!membership_level_name!!</p>
|
5 |
|
6 |
-
<p>Die Kosten
|
7 |
|
8 |
-
<p>Hier
|
1 |
+
<p>Vielen Dank für Ihre Anmeldung bei !!sitename!!. Ihre Testperiode endet am !!trial_end!!.</p>
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
<p>Paket: !!membership_level_name!!</p>
|
5 |
|
6 |
+
<p>Die Kosten für den Zugang ändern sich dann von !!trial_amount!! auf !!billing_amount!! jede(n) !!cycle_number!! !!cycle_period!!(s).</p>
|
7 |
|
8 |
+
<p>Hier können Sie sich in Ihren Account einloggen: !!login_link!!</p>
|
languages/gettext.sh
CHANGED
@@ -16,6 +16,12 @@ xgettext -j -o languages/paid-memberships-pro.pot \
|
|
16 |
--keyword=_ex \
|
17 |
--keyword=_n \
|
18 |
--keyword=_x \
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
--sort-by-file \
|
20 |
--package-version=1.0 \
|
21 |
--msgid-bugs-address="jason@strangerstudios.com" \
|
16 |
--keyword=_ex \
|
17 |
--keyword=_n \
|
18 |
--keyword=_x \
|
19 |
+
--keyword=esc_html__ \
|
20 |
+
--keyword=esc_html_e \
|
21 |
+
--keyword=esc_html_x \
|
22 |
+
--keyword=esc_attr__ \
|
23 |
+
--keyword=esc_attr_e \
|
24 |
+
--keyword=esc_attr_x \
|
25 |
--sort-by-file \
|
26 |
--package-version=1.0 \
|
27 |
--msgid-bugs-address="jason@strangerstudios.com" \
|
languages/paid-memberships-pro-ca.mo
CHANGED
Binary file
|
languages/paid-memberships-pro-ca.po
CHANGED
@@ -1,175 +1,309 @@
|
|
1 |
-
#
|
2 |
-
#
|
3 |
-
# http://www.paidmembershipspro.com/documentation/languages/
|
4 |
-
#
|
5 |
msgid ""
|
6 |
msgstr ""
|
7 |
-
"Project-Id-Version:
|
8 |
-
"
|
9 |
-
"
|
10 |
-
"Language-Team:
|
11 |
"MIME-Version: 1.0\n"
|
12 |
"Content-Type: text/plain; charset=UTF-8\n"
|
13 |
"Content-Transfer-Encoding: 8bit\n"
|
14 |
-
"
|
15 |
-
"
|
16 |
-
"
|
17 |
-
"
|
18 |
-
|
19 |
-
#: adminpages/addons.php:5
|
20 |
-
#: adminpages/
|
21 |
-
#: adminpages/
|
22 |
-
#: adminpages/
|
23 |
-
#: adminpages/
|
24 |
-
#: adminpages/
|
25 |
-
#: adminpages/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
#: adminpages/pagesettings.php:5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
msgid "You do not have permissions to perform this action."
|
28 |
msgstr "Vostè no té permisos per a realitzar aquesta acció."
|
29 |
|
30 |
-
#: adminpages/addons.php:64
|
31 |
-
#:
|
32 |
-
#:
|
33 |
-
#:
|
34 |
-
#:
|
35 |
-
#:
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
#: includes/adminpages.php:146
|
|
|
|
|
|
|
|
|
37 |
msgid "Add Ons"
|
38 |
msgstr "Complement"
|
39 |
|
40 |
-
#: adminpages/addons.php:71
|
|
|
|
|
41 |
#, php-format
|
42 |
msgid "Last checked on %s at %s."
|
43 |
msgstr "Darrera comprovació: %s a %s."
|
44 |
|
45 |
-
#: adminpages/addons.php:72
|
|
|
|
|
46 |
msgid "Check Again"
|
47 |
msgstr "Comproveu una vegada més"
|
48 |
|
49 |
-
#: adminpages/addons.php:76
|
50 |
-
#: adminpages/orders.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
msgid "All"
|
52 |
msgstr "Tot"
|
53 |
|
54 |
-
#: adminpages/addons.php:77
|
|
|
|
|
55 |
msgid "Active"
|
56 |
msgstr "Actiu"
|
57 |
|
58 |
-
#: adminpages/addons.php:78
|
|
|
|
|
59 |
msgid "Inactive"
|
60 |
msgstr "Inactiu"
|
61 |
|
62 |
-
#: adminpages/addons.php:79
|
|
|
|
|
63 |
msgid "Update Available"
|
64 |
msgstr "Actualització disponible"
|
65 |
|
66 |
-
#: adminpages/addons.php:80
|
|
|
|
|
67 |
msgid "Not Installed"
|
68 |
msgstr "No instal·lat"
|
69 |
|
70 |
-
#: adminpages/addons.php:93
|
|
|
71 |
msgid "Add On Name"
|
72 |
msgstr "Add On Nom"
|
73 |
|
74 |
-
#: adminpages/addons.php:94
|
|
|
75 |
msgid "Type"
|
76 |
msgstr "Tipus"
|
77 |
|
78 |
-
#: adminpages/addons.php:95
|
79 |
-
#: adminpages/
|
|
|
|
|
80 |
#: adminpages/membershiplevels.php:298
|
|
|
81 |
msgid "Description"
|
82 |
msgstr "Descripció"
|
83 |
|
84 |
-
#: adminpages/addons.php:118
|
|
|
|
|
85 |
msgid "No Add Ons found."
|
86 |
msgstr "No s’ha trobat Add Ons"
|
87 |
|
88 |
-
#: adminpages/addons.php:179
|
89 |
-
#: adminpages/addons.php:
|
90 |
-
#: adminpages/addons.php:
|
|
|
|
|
|
|
|
|
|
|
91 |
msgid "Install Now"
|
92 |
msgstr "Instal · la ara"
|
93 |
|
94 |
-
#: adminpages/addons.php:185
|
95 |
-
#: adminpages/addons.php:
|
96 |
-
#: adminpages/addons.php:
|
97 |
-
#: adminpages/addons.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
msgid "Download"
|
99 |
msgstr "Descarrega"
|
100 |
|
101 |
-
#: adminpages/addons.php:190
|
102 |
-
#: adminpages/addons.php:
|
|
|
|
|
|
|
|
|
103 |
msgid "Update License"
|
104 |
msgstr "Actualitza Llicència"
|
105 |
|
106 |
-
#: adminpages/addons.php:208
|
|
|
107 |
msgid "Deactivate"
|
108 |
msgstr "Desactiva"
|
109 |
|
110 |
-
#: adminpages/addons.php:208
|
|
|
111 |
#, php-format
|
112 |
msgid "Deactivate %s"
|
113 |
msgstr "Desactiva %s"
|
114 |
|
115 |
-
#: adminpages/addons.php:212
|
|
|
116 |
msgid "Activate"
|
117 |
msgstr "Activa"
|
118 |
|
119 |
-
#: adminpages/addons.php:212
|
|
|
120 |
#, php-format
|
121 |
msgid "Activate %s"
|
122 |
msgstr "Activa %s"
|
123 |
|
124 |
-
#: adminpages/addons.php:213
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
msgid "Delete"
|
126 |
msgstr "Esborra"
|
127 |
|
128 |
-
#: adminpages/addons.php:213
|
|
|
129 |
#, php-format
|
130 |
msgid "Delete %s"
|
131 |
msgstr "Esborra %s"
|
132 |
|
133 |
-
#: adminpages/addons.php:223
|
|
|
|
|
134 |
msgid "PMPro Free"
|
135 |
msgstr "PMPro Free"
|
136 |
|
137 |
-
#: adminpages/addons.php:225
|
|
|
|
|
138 |
msgid "PMPro Core"
|
139 |
msgstr "PMPro Core"
|
140 |
|
141 |
-
#: adminpages/addons.php:227
|
|
|
|
|
142 |
msgid "PMPro Plus"
|
143 |
msgstr "PMPro Plus"
|
144 |
|
145 |
-
#: adminpages/addons.php:229
|
|
|
|
|
146 |
msgid "WordPress.org"
|
147 |
msgstr "WordPress.org"
|
148 |
|
149 |
-
#: adminpages/addons.php:231
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2022 Stranger Studios
|
2 |
+
# This file is distributed under the same license as the Paid Memberships Pro plugin.
|
|
|
|
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: Paid Memberships Pro 2.7\n"
|
6 |
+
"Report-Msgid-Bugs-To: info@paidmembershipspro.com\n"
|
7 |
+
"Last-Translator: Paid Memberships Pro <info@paidmembershipspro.com>\n"
|
8 |
+
"Language-Team: Paid Memberships Pro <info@paidmembershipspro.com>\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: 2022-01-13T17:22:32+00:00\n"
|
13 |
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
14 |
+
"X-Generator: WP-CLI 2.5.0\n"
|
15 |
+
"X-Domain: paid-memberships-pro\n"
|
16 |
+
|
17 |
+
#: adminpages/addons.php:5
|
18 |
+
#: adminpages/advancedsettings.php:5
|
19 |
+
#: adminpages/discountcodes.php:5
|
20 |
+
#: adminpages/emailsettings.php:5
|
21 |
+
#: adminpages/membershiplevels.php:5
|
22 |
+
#: adminpages/memberslist-csv.php:5
|
23 |
+
#: adminpages/memberslist.php:5
|
24 |
+
#: adminpages/orders-csv.php:5
|
25 |
+
#: adminpages/orders-print.php:12
|
26 |
+
#: adminpages/orders.php:5
|
27 |
+
#: adminpages/pagesettings.php:4
|
28 |
+
#: adminpages/paymentsettings.php:5
|
29 |
+
#: adminpages/updates.php:5
|
30 |
+
#: includes/license.php:36
|
31 |
+
#: adminpages/addons.php:21
|
32 |
#: adminpages/pagesettings.php:5
|
33 |
+
#: adminpages/emailtemplates.php:5
|
34 |
+
#: adminpages/license.php:4
|
35 |
+
#: adminpages/orders-csv.php:4
|
36 |
+
#: adminpages/orders.php:4
|
37 |
+
#: includes/services.php:91
|
38 |
+
#: includes/services.php:104
|
39 |
+
#: includes/email.php:175
|
40 |
+
#: includes/email.php:211
|
41 |
+
#: includes/email.php:230
|
42 |
+
#: includes/email.php:255
|
43 |
+
#: includes/email.php:273
|
44 |
+
#: includes/email.php:178
|
45 |
+
#: includes/email.php:214
|
46 |
+
#: includes/email.php:237
|
47 |
+
#: includes/email.php:262
|
48 |
+
#: includes/email.php:280
|
49 |
msgid "You do not have permissions to perform this action."
|
50 |
msgstr "Vostè no té permisos per a realitzar aquesta acció."
|
51 |
|
52 |
+
#: adminpages/addons.php:64
|
53 |
+
#: adminpages/admin_header.php:170
|
54 |
+
#: includes/adminpages.php:53
|
55 |
+
#: includes/adminpages.php:151
|
56 |
+
#: adminpages/addons.php:80
|
57 |
+
#: adminpages/admin_header.php:133
|
58 |
+
#: adminpages/admin_header.php:154
|
59 |
+
#: includes/adminpages.php:14
|
60 |
+
#: includes/adminpages.php:52
|
61 |
+
#: includes/adminpages.php:69
|
62 |
+
#: includes/adminpages.php:135
|
63 |
+
#: includes/adminpages.php:142
|
64 |
#: includes/adminpages.php:146
|
65 |
+
#: adminpages/addons.php:81
|
66 |
+
#: adminpages/admin_header.php:242
|
67 |
+
#: includes/adminpages.php:56
|
68 |
+
#: includes/adminpages.php:206
|
69 |
msgid "Add Ons"
|
70 |
msgstr "Complement"
|
71 |
|
72 |
+
#: adminpages/addons.php:71
|
73 |
+
#: adminpages/addons.php:87
|
74 |
+
#: adminpages/addons.php:89
|
75 |
#, php-format
|
76 |
msgid "Last checked on %s at %s."
|
77 |
msgstr "Darrera comprovació: %s a %s."
|
78 |
|
79 |
+
#: adminpages/addons.php:72
|
80 |
+
#: adminpages/addons.php:88
|
81 |
+
#: adminpages/addons.php:90
|
82 |
msgid "Check Again"
|
83 |
msgstr "Comproveu una vegada més"
|
84 |
|
85 |
+
#: adminpages/addons.php:76
|
86 |
+
#: adminpages/orders.php:712
|
87 |
+
#: adminpages/addons.php:92
|
88 |
+
#: adminpages/orders.php:605
|
89 |
+
#: adminpages/orders.php:741
|
90 |
+
#: adminpages/addons.php:94
|
91 |
+
#: adminpages/orders.php:1016
|
92 |
+
#: adminpages/orders.php:1022
|
93 |
+
#: adminpages/orders.php:1014
|
94 |
+
#: includes/metaboxes.php:19
|
95 |
msgid "All"
|
96 |
msgstr "Tot"
|
97 |
|
98 |
+
#: adminpages/addons.php:77
|
99 |
+
#: adminpages/addons.php:93
|
100 |
+
#: adminpages/addons.php:95
|
101 |
msgid "Active"
|
102 |
msgstr "Actiu"
|
103 |
|
104 |
+
#: adminpages/addons.php:78
|
105 |
+
#: adminpages/addons.php:94
|
106 |
+
#: adminpages/addons.php:96
|
107 |
msgid "Inactive"
|
108 |
msgstr "Inactiu"
|
109 |
|
110 |
+
#: adminpages/addons.php:79
|
111 |
+
#: adminpages/addons.php:95
|
112 |
+
#: adminpages/addons.php:97
|
113 |
msgid "Update Available"
|
114 |
msgstr "Actualització disponible"
|
115 |
|
116 |
+
#: adminpages/addons.php:80
|
117 |
+
#: adminpages/addons.php:96
|
118 |
+
#: adminpages/addons.php:98
|
119 |
msgid "Not Installed"
|
120 |
msgstr "No instal·lat"
|
121 |
|
122 |
+
#: adminpages/addons.php:93
|
123 |
+
#: adminpages/addons.php:109
|
124 |
msgid "Add On Name"
|
125 |
msgstr "Add On Nom"
|
126 |
|
127 |
+
#: adminpages/addons.php:94
|
128 |
+
#: adminpages/addons.php:110
|
129 |
msgid "Type"
|
130 |
msgstr "Tipus"
|
131 |
|
132 |
+
#: adminpages/addons.php:95
|
133 |
+
#: adminpages/membershiplevels.php:300
|
134 |
+
#: adminpages/addons.php:111
|
135 |
+
#: adminpages/membershiplevels.php:296
|
136 |
#: adminpages/membershiplevels.php:298
|
137 |
+
#: adminpages/membershiplevels.php:359
|
138 |
msgid "Description"
|
139 |
msgstr "Descripció"
|
140 |
|
141 |
+
#: adminpages/addons.php:118
|
142 |
+
#: adminpages/addons.php:134
|
143 |
+
#: adminpages/addons.php:135
|
144 |
msgid "No Add Ons found."
|
145 |
msgstr "No s’ha trobat Add Ons"
|
146 |
|
147 |
+
#: adminpages/addons.php:179
|
148 |
+
#: adminpages/addons.php:184
|
149 |
+
#: adminpages/addons.php:196
|
150 |
+
#: adminpages/addons.php:195
|
151 |
+
#: adminpages/addons.php:200
|
152 |
+
#: adminpages/addons.php:212
|
153 |
+
#: adminpages/addons.php:201
|
154 |
+
#: adminpages/addons.php:213
|
155 |
msgid "Install Now"
|
156 |
msgstr "Instal · la ara"
|
157 |
|
158 |
+
#: adminpages/addons.php:185
|
159 |
+
#: adminpages/addons.php:191
|
160 |
+
#: adminpages/addons.php:197
|
161 |
+
#: adminpages/addons.php:203
|
162 |
+
#: adminpages/addons.php:201
|
163 |
+
#: adminpages/addons.php:207
|
164 |
+
#: adminpages/addons.php:213
|
165 |
+
#: adminpages/addons.php:219
|
166 |
+
#: adminpages/addons.php:202
|
167 |
+
#: adminpages/addons.php:208
|
168 |
+
#: adminpages/addons.php:214
|
169 |
+
#: adminpages/addons.php:220
|
170 |
msgid "Download"
|
171 |
msgstr "Descarrega"
|
172 |
|
173 |
+
#: adminpages/addons.php:190
|
174 |
+
#: adminpages/addons.php:202
|
175 |
+
#: adminpages/addons.php:206
|
176 |
+
#: adminpages/addons.php:218
|
177 |
+
#: adminpages/addons.php:207
|
178 |
+
#: adminpages/addons.php:219
|
179 |
msgid "Update License"
|
180 |
msgstr "Actualitza Llicència"
|
181 |
|
182 |
+
#: adminpages/addons.php:208
|
183 |
+
#: adminpages/addons.php:224
|
184 |
msgid "Deactivate"
|
185 |
msgstr "Desactiva"
|
186 |
|
187 |
+
#: adminpages/addons.php:208
|
188 |
+
#: adminpages/addons.php:224
|
189 |
#, php-format
|
190 |
msgid "Deactivate %s"
|
191 |
msgstr "Desactiva %s"
|
192 |
|
193 |
+
#: adminpages/addons.php:212
|
194 |
+
#: adminpages/addons.php:228
|
195 |
msgid "Activate"
|
196 |
msgstr "Activa"
|
197 |
|
198 |
+
#: adminpages/addons.php:212
|
199 |
+
#: adminpages/addons.php:228
|
200 |
#, php-format
|
201 |
msgid "Activate %s"
|
202 |
msgstr "Activa %s"
|
203 |
|
204 |
+
#: adminpages/addons.php:213
|
205 |
+
#: adminpages/addons.php:229
|
206 |
+
#: adminpages/discountcodes.php:816
|
207 |
+
#: adminpages/membershiplevels.php:835
|
208 |
+
#: adminpages/orders.php:1374
|
209 |
+
#: adminpages/discountcodes.php:862
|
210 |
+
#: adminpages/discountcodes.php:864
|
211 |
+
#: adminpages/membershiplevels.php:887
|
212 |
+
#: adminpages/membershiplevels.php:889
|
213 |
+
#: adminpages/orders.php:1425
|
214 |
+
#: adminpages/orders.php:1427
|
215 |
+
#: adminpages/discountcodes.php:866
|
216 |
+
#: adminpages/orders.php:1417
|
217 |
+
#: adminpages/orders.php:1419
|
218 |
msgid "Delete"
|
219 |
msgstr "Esborra"
|
220 |
|
221 |
+
#: adminpages/addons.php:213
|
222 |
+
#: adminpages/addons.php:229
|
223 |
#, php-format
|
224 |
msgid "Delete %s"
|
225 |
msgstr "Esborra %s"
|
226 |
|
227 |
+
#: adminpages/addons.php:223
|
228 |
+
#: adminpages/addons.php:239
|
229 |
+
#: adminpages/addons.php:240
|
230 |
msgid "PMPro Free"
|
231 |
msgstr "PMPro Free"
|
232 |
|
233 |
+
#: adminpages/addons.php:225
|
234 |
+
#: adminpages/addons.php:241
|
235 |
+
#: adminpages/addons.php:242
|
236 |
msgid "PMPro Core"
|
237 |
msgstr "PMPro Core"
|
238 |
|
239 |
+
#: adminpages/addons.php:227
|
240 |
+
#: adminpages/addons.php:243
|
241 |
+
#: adminpages/addons.php:244
|
242 |
msgid "PMPro Plus"
|
243 |
msgstr "PMPro Plus"
|
244 |
|
245 |
+
#: adminpages/addons.php:229
|
246 |
+
#: adminpages/addons.php:245
|
247 |
+
#: adminpages/addons.php:246
|
248 |
msgid "WordPress.org"
|
249 |
msgstr "WordPress.org"
|
250 |
|
251 |
+
#: adminpages/addons.php:231
|
252 |
+
#: adminpages/addons.php:247
|
253 |
+
#: adminpages/addons.php:248
|
254 |
+
#: adminpages/orders.php:581
|
255 |
+
#: adminpages/orders.php:1467
|
256 |
+
#: adminpages/orders.php:1477
|
257 |
+
#: inclu
|