Version Description
- 2020-08-25
- SECURITY: Fixed a cross-site scripting vulnerability in the code that updates the Required Membership settings on a post. This vulnerability could have been used in conjunction with other security vulnerabilities to trick an admin into editing the membership settings for a page, potentially exposing members only content to non-members. It is unlikely that there was any active exploitation of this vulnerability. This issue may also have shown up as a bug on some sites using page builders, where the membership settings for a post would be cleared out when editing a post. (Thanks to the wp.org plugin review team for catching this issue.)
- SECURITY: Better escaping of variables shown in the Require Membership meta box and related SQL queries.
- BUG FIX/ENHANCEMENT: Renamed the Vietnamese language files to match what is expected.
Download this release
Release Info
Developer | strangerstudios |
Plugin | Paid Memberships Pro |
Version | 2.4.3 |
Comparing to | |
See all releases |
Code changes from version 2.4.1 to 2.4.3
- CHANGELOG.txt +20 -0
- adminpages/admin_header.php +17 -0
- adminpages/advancedsettings.php +11 -6
- adminpages/dashboard.php +1 -1
- adminpages/discountcodes.php +37 -7
- adminpages/functions.php +103 -0
- adminpages/orders-csv.php +1 -1
- adminpages/orders.php +4 -4
- adminpages/templates/orders-email.php +1 -1
- adminpages/templates/orders-print.php +1 -1
- classes/class.memberorder.php +15 -6
- classes/class.pmproemail.php +3 -3
- classes/gateways/class.pmprogateway_paypal.php +2 -2
- classes/gateways/class.pmprogateway_paypalexpress.php +3 -2
- classes/gateways/class.pmprogateway_paypalstandard.php +1 -1
- includes/capabilities.php +10 -7
- includes/content.php +2 -40
- includes/functions.php +66 -2
- includes/metaboxes.php +83 -82
- includes/privacy.php +1 -1
- includes/profile.php +10 -1
- includes/rest-api.php +92 -22
- includes/updates.php +1 -3
- includes/updates/upgrade_1_8_9_3.php +1 -1
- languages/{paid-memberships-pro-vi_VN.mo → paid-memberships-pro-vi.mo} +0 -0
- languages/{paid-memberships-pro-vi_VN.po → paid-memberships-pro-vi.po} +0 -0
- pages/cancel.php +7 -4
- pages/confirmation.php +1 -1
- pages/invoice.php +2 -2
- paid-memberships-pro.php +2 -2
- readme.txt +21 -1
- shortcodes/membership.php +10 -3
- shortcodes/pmpro_account.php +1 -1
CHANGELOG.txt
CHANGED
@@ -1,4 +1,24 @@
|
|
1 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
= 2.4.1 - 2020-08-10 =
|
3 |
* BUG FIX: Fixed issues with password resets on WP Engine hosting due to security features added by their mu-plugin.
|
4 |
* BUG FIX: Fixed issue where end dates were showing up incorrectly in the confirmation email sometimes.
|
1 |
== Changelog ==
|
2 |
+
= 2.4.3 - 2020-08-25
|
3 |
+
* SECURITY: Fixed a cross-site scripting vulnerability in the code that updates the Required Membership settings on a post. This vulnerability could have been used in conjunction with other security vulnerabilities to trick an admin into editing the membership settings for a page, potentially exposing members only content to non-members. It is unlikely that there was any active exploitation of this vulnerability. This issue may also have shown up as a bug on some sites using page builders, where the membership settings for a post would be cleared out when editing a post. (Thanks to the wp.org plugin review team for catching this issue.)
|
4 |
+
* SECURITY: Better escaping of variables shown in the Require Membership meta box and related SQL queries.
|
5 |
+
* BUG FIX/ENHANCEMENT: Renamed the Vietnamese language files to match what is expected.
|
6 |
+
|
7 |
+
= 2.4.2 - 2020-08-24
|
8 |
+
* SECURITY: Updated the PMPro REST API endpoints accessed via the GET method to also require appropriate capabilities to access. The membership confirmation text will be hidden from non-members and non-admins. The endpoints to check a user's level or access to a post require the pmpro_edit_memberships capability now. You should make sure your API users have the appropriate capabilities to use the API. You can use the pmpro_rest_api_route_capabilities filter and/or pmpro_rest_api_permissions filter to change this behavior.
|
9 |
+
* BUG FIX: Fixed issues with the PMPro REST API endpoints, including the discount code and checkout level endpoints.
|
10 |
+
* BUG FIX: Fixed issue with backslashes in the display name when editing form the PMPro frontend profile page.
|
11 |
+
* BUG FIX: Fixed issue where timestamps were showing up incorrectly for recent orders shown on the dashboard page.
|
12 |
+
BUG FIX: Fixed issue where PMPro would always try to add capabilities to the administrator role, even if you removed that role for some reason.
|
13 |
+
* ENHANCEMENT: Added a pmpro_get_no_access_message() function, which can be used to show the no access messages.
|
14 |
+
* ENHANCEMENT: Added a "show_noaccess" property to the membership shortcode. When set, it will show the noaccess message to users who don't have the levels specified.
|
15 |
+
* ENHANCEMENT: Added a pmpro_user_profile_update_errors hook, which can be used to show errors on the PMPro frontend profile page.
|
16 |
+
* ENHANCEMENT: The pmpro_set_capabilities_for_role() function now returns true or false if the caps were added in case others want to use this function and tell if it worked.
|
17 |
+
* ENHANCEMENT: You can now include links in the description of the fields you add to the PMPro advanced settings page via the pmpro_custom_advanced_settings filter.
|
18 |
+
* ENHANCEMENT: Updated the PayPal gateways to use the latest versions of the PayPal buttons.
|
19 |
+
* ENHANCEMENT: Fixed styling of the PMPro update script notice.
|
20 |
+
* ENHANCEMENT: Added the pmpro_account_membership_expiration_text filter to the expiration dates shown on the cancel page when using MMPU.
|
21 |
+
|
22 |
= 2.4.1 - 2020-08-10 =
|
23 |
* BUG FIX: Fixed issues with password resets on WP Engine hosting due to security features added by their mu-plugin.
|
24 |
* BUG FIX: Fixed issue where end dates were showing up incorrectly in the confirmation email sometimes.
|
adminpages/admin_header.php
CHANGED
@@ -124,6 +124,23 @@
|
|
124 |
$msgt .= " <a href=\"" . admin_url('admin.php?page=pmpro-membershiplevels') . "\">" . __("Please edit your levels", 'paid-memberships-pro' ) . "</a>.";
|
125 |
}
|
126 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
//check gateway dependencies
|
128 |
$gateway = pmpro_getOption('gateway');
|
129 |
if($gateway == "stripe" && version_compare( PHP_VERSION, '5.3.29', '>=' ) ) {
|
124 |
$msgt .= " <a href=\"" . admin_url('admin.php?page=pmpro-membershiplevels') . "\">" . __("Please edit your levels", 'paid-memberships-pro' ) . "</a>.";
|
125 |
}
|
126 |
|
127 |
+
if ( ! pmpro_check_discount_code_for_gateway_compatibility() ) {
|
128 |
+
$msg = -1;
|
129 |
+
$msgt = __( 'The billing details for some of your discount codes are not supported by your gateway.', 'paid-memberships-pro' );
|
130 |
+
if ( $view == 'pmpro-discountcodes' && ! empty($_REQUEST['edit']) && $_REQUEST['edit'] > 0 ) {
|
131 |
+
if ( ! pmpro_check_discount_code_for_gateway_compatibility( $_REQUEST['edit'] ) ) {
|
132 |
+
$msg = -1;
|
133 |
+
$msgt = __( 'The billing details for this discount code are not supported by your gateway.', 'paid-memberships-pro' );
|
134 |
+
}
|
135 |
+
} elseif ( $view == 'pmpro-discountcodes' ) {
|
136 |
+
$msg = -1;
|
137 |
+
$msgt .= " " . __("The discount codes with issues are highlighted below.", 'paid-memberships-pro' );
|
138 |
+
} else {
|
139 |
+
$msgt .= " <a href=\"" . admin_url('admin.php?page=pmpro-discountcodes') . "\">" . __("Please edit your discount codes", 'paid-memberships-pro' ) . "</a>.";
|
140 |
+
|
141 |
+
}
|
142 |
+
}
|
143 |
+
|
144 |
//check gateway dependencies
|
145 |
$gateway = pmpro_getOption('gateway');
|
146 |
if($gateway == "stripe" && version_compare( PHP_VERSION, '5.3.29', '>=' ) ) {
|
adminpages/advancedsettings.php
CHANGED
@@ -450,12 +450,17 @@ if ( function_exists( 'pmpro_displayAds' ) && pmpro_displayAds() ) {
|
|
450 |
default:
|
451 |
break;
|
452 |
}
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
|
|
|
|
|
|
|
|
|
|
459 |
</td>
|
460 |
</tr>
|
461 |
<?php
|
450 |
default:
|
451 |
break;
|
452 |
}
|
453 |
+
if ( ! empty( $field['description'] ) ) {
|
454 |
+
$allowed_pmpro_custom_advanced_settings_html = array (
|
455 |
+
'a' => array (
|
456 |
+
'href' => array(),
|
457 |
+
'target' => array(),
|
458 |
+
'title' => array(),
|
459 |
+
),
|
460 |
+
);
|
461 |
+
?>
|
462 |
+
<p class="description"><?php echo wp_kses( $field['description'], $allowed_pmpro_custom_advanced_settings_html ); ?></p>
|
463 |
+
<?php } ?>
|
464 |
</td>
|
465 |
</tr>
|
466 |
<?php
|
adminpages/dashboard.php
CHANGED
@@ -343,7 +343,7 @@ function pmpro_dashboard_report_recent_orders_callback() {
|
|
343 |
echo '<br />(' . $order->status . ')';
|
344 |
} ?>
|
345 |
</td>
|
346 |
-
<td><?php echo date_i18n( get_option( 'date_format' ), $order->
|
347 |
</tr>
|
348 |
<?php
|
349 |
}
|
343 |
echo '<br />(' . $order->status . ')';
|
344 |
} ?>
|
345 |
</td>
|
346 |
+
<td><?php echo date_i18n( get_option( 'date_format' ), $order->getTimestamp() ); ?></td>
|
347 |
</tr>
|
348 |
<?php
|
349 |
}
|
adminpages/discountcodes.php
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
}
|
7 |
|
8 |
//vars
|
9 |
-
global $wpdb, $pmpro_currency_symbol;
|
10 |
|
11 |
$now = current_time( 'timestamp' );
|
12 |
|
@@ -562,7 +562,7 @@
|
|
562 |
else
|
563 |
$level_checked = false;
|
564 |
?>
|
565 |
-
<div class="pmpro_discount_level">
|
566 |
<input type="hidden" name="all_levels[]" value="<?php echo $level->id?>" />
|
567 |
<input type="checkbox" id="levels_<?php echo $level->id;?>" name="levels[]" value="<?php echo $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();" />
|
568 |
<label for="levels_<?php echo $level->id;?>"><?php echo $level->name?></label>
|
@@ -615,6 +615,9 @@
|
|
615 |
?>
|
616 |
</select>
|
617 |
<p class="description"><?php _e('The amount to be billed one cycle after the initial payment.', 'paid-memberships-pro' );?></p>
|
|
|
|
|
|
|
618 |
</td>
|
619 |
</tr>
|
620 |
|
@@ -622,13 +625,33 @@
|
|
622 |
<th scope="row" valign="top"><label for="billing_limit"><?php _e('Billing Cycle Limit', 'paid-memberships-pro' );?>:</label></th>
|
623 |
<td>
|
624 |
<input name="billing_limit[]" type="text" size="20" value="<?php echo $level->billing_limit?>" />
|
625 |
-
<p class="description"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
626 |
</td>
|
627 |
</tr>
|
628 |
|
629 |
<tr class="recurring_info" <?php if (!pmpro_isLevelRecurring($level)) echo "style='display:none;'";?>>
|
630 |
<th scope="row" valign="top"><label><?php _e('Custom Trial', 'paid-memberships-pro' );?>:</label></th>
|
631 |
-
<td
|
|
|
|
|
|
|
|
|
|
|
632 |
</tr>
|
633 |
|
634 |
<tr class="trial_info recurring_info" <?php if (!pmpro_isLevelTrial($level)) echo "style='display:none;'";?>>
|
@@ -646,6 +669,13 @@
|
|
646 |
<?php _e('for the first', 'paid-memberships-pro' );?>
|
647 |
<input name="trial_limit[]" type="text" size="10" value="<?php echo str_replace("\"", """, stripslashes($level->trial_limit))?>" />
|
648 |
<?php _e('subscription payments', 'paid-memberships-pro' );?>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
649 |
</td>
|
650 |
</tr>
|
651 |
|
@@ -667,6 +697,7 @@
|
|
667 |
echo ">$name</option>";
|
668 |
}
|
669 |
?>
|
|
|
670 |
</select>
|
671 |
<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>
|
672 |
</td>
|
@@ -755,18 +786,17 @@
|
|
755 |
</thead>
|
756 |
<tbody>
|
757 |
<?php if ( !empty( $s ) && empty( $codes ) ) { ?>
|
758 |
-
<tr
|
759 |
<td colspan="6">
|
760 |
<?php echo esc_attr_e( 'Code not found.', 'paid-memberships-pro' ); ?>
|
761 |
</td>
|
762 |
</tr>
|
763 |
<?php } ?>
|
764 |
<?php
|
765 |
-
$count = 0;
|
766 |
foreach($codes as $code) {
|
767 |
$uses = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->pmpro_discount_codes_uses WHERE code_id = %d", $code->id ) );
|
768 |
?>
|
769 |
-
<tr<?php if(
|
770 |
<td><?php echo $code->id?></td>
|
771 |
<td class="has-row-actions">
|
772 |
<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>
|
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 |
|
562 |
else
|
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;?>" name="levels[]" value="<?php echo $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();" />
|
568 |
<label for="levels_<?php echo $level->id;?>"><?php echo $level->name?></label>
|
615 |
?>
|
616 |
</select>
|
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 |
|
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' ) ) { ?>
|
631 |
+
<br /><strong <?php if(!empty($pmpro_stripe_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Stripe integration currently does not support billing limits. You can still set an expiration date below.', 'paid-memberships-pro' );?></strong>
|
632 |
+
<?php if ( ! function_exists( 'pmprosd_pmpro_membership_level_after_other_settings' ) ) {
|
633 |
+
$allowed_sbl_html = array (
|
634 |
+
'a' => array (
|
635 |
+
'href' => array(),
|
636 |
+
'target' => array(),
|
637 |
+
'title' => array(),
|
638 |
+
),
|
639 |
+
);
|
640 |
+
echo '<br />' . sprintf( wp_kses( __( 'Optional: Allow billing limits with Stripe using the <a href="%s" title="Paid Memberships Pro - Stripe Billing Limits Add On" target="_blank">Stripe Billing Limits Add On</a>.', 'paid-memberships-pro' ), $allowed_sbl_html ), 'https://www.paidmembershipspro.com/add-ons/pmpro-stripe-billing-limits/?utm_source=plugin&utm_medium=pmpro-membershiplevels&utm_campaign=add-ons&utm_content=stripe-billing-limits' ) . '</em></td></tr>';
|
641 |
+
} ?>
|
642 |
+
<?php } ?>
|
643 |
+
</p>
|
644 |
</td>
|
645 |
</tr>
|
646 |
|
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;?>" name="custom_trial[]" type="checkbox" value="<?php echo $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 $level->id;?>"><?php _e('Check to add a custom trial period.', 'paid-memberships-pro' );?></label>
|
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 } ?>
|
654 |
+
</td>
|
655 |
</tr>
|
656 |
|
657 |
<tr class="trial_info recurring_info" <?php if (!pmpro_isLevelTrial($level)) echo "style='display:none;'";?>>
|
669 |
<?php _e('for the first', 'paid-memberships-pro' );?>
|
670 |
<input name="trial_limit[]" type="text" size="10" value="<?php echo str_replace("\"", """, stripslashes($level->trial_limit))?>" />
|
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>
|
674 |
+
<?php } elseif($gateway == "braintree") { ?>
|
675 |
+
<p class="description"><strong <?php if(!empty($pmpro_braintree_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Braintree integration currently does not support trial amounts greater than $0.', 'paid-memberships-pro' );?></strong></p>
|
676 |
+
<?php } elseif($gateway == "payflowpro") { ?>
|
677 |
+
<p class="description"><strong <?php if(!empty($pmpro_payflow_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Payflow integration currently does not support trial amounts greater than $0.', 'paid-memberships-pro' );?></strong></p>
|
678 |
+
<?php } ?>
|
679 |
</td>
|
680 |
</tr>
|
681 |
|
697 |
echo ">$name</option>";
|
698 |
}
|
699 |
?>
|
700 |
+
|
701 |
</select>
|
702 |
<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>
|
703 |
</td>
|
786 |
</thead>
|
787 |
<tbody>
|
788 |
<?php if ( !empty( $s ) && empty( $codes ) ) { ?>
|
789 |
+
<tr>
|
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) {
|
797 |
$uses = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->pmpro_discount_codes_uses WHERE code_id = %d", $code->id ) );
|
798 |
?>
|
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>
|
adminpages/functions.php
CHANGED
@@ -158,6 +158,109 @@ function pmpro_checkLevelForBraintreeCompatibility($level = NULL)
|
|
158 |
return true;
|
159 |
}
|
160 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
/*
|
162 |
Checks if PMPro settings are complete or if there are any errors.
|
163 |
|
158 |
return true;
|
159 |
}
|
160 |
|
161 |
+
/**
|
162 |
+
* Checks if a discount code's settings are compatible with the active gateway.
|
163 |
+
*
|
164 |
+
*/
|
165 |
+
function pmpro_check_discount_code_for_gateway_compatibility( $discount_code = NULL ) {
|
166 |
+
// Return if no gateway is set.
|
167 |
+
$gateway = pmpro_getOption( 'gateway' );
|
168 |
+
if ( empty( $gateway ) ) {
|
169 |
+
return true;
|
170 |
+
}
|
171 |
+
|
172 |
+
global $wpdb;
|
173 |
+
|
174 |
+
// Check ALL the discount codes if none specified.
|
175 |
+
if ( empty( $discount_code ) ) {
|
176 |
+
$discount_codes = $wpdb->get_results( "SELECT * FROM $wpdb->pmpro_discount_codes" );
|
177 |
+
if ( ! empty( $discount_codes ) ) {
|
178 |
+
foreach ( $discount_codes as $discount_code ) {
|
179 |
+
if ( ! pmpro_check_discount_code_for_gateway_compatibility( $discount_code ) ) {
|
180 |
+
return false;
|
181 |
+
}
|
182 |
+
}
|
183 |
+
}
|
184 |
+
} else {
|
185 |
+
if ( ! is_numeric( $discount_code ) ) {
|
186 |
+
// Convert the code array into a single id.
|
187 |
+
$discount_code = $discount_code->id;
|
188 |
+
}
|
189 |
+
// Check ALL the discount code levels for this code.
|
190 |
+
$discount_codes_levels = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->pmpro_discount_codes_levels WHERE code_id = %d", $discount_code ) );
|
191 |
+
if ( ! empty( $discount_codes_levels ) ) {
|
192 |
+
foreach ( $discount_codes_levels as $discount_code_level ) {
|
193 |
+
if ( ! pmpro_check_discount_code_level_for_gateway_compatibility( $discount_code_level ) ) {
|
194 |
+
return false;
|
195 |
+
}
|
196 |
+
}
|
197 |
+
}
|
198 |
+
}
|
199 |
+
return true;
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Checks if a discount code's settings are compatible with the active gateway.
|
204 |
+
*
|
205 |
+
*/
|
206 |
+
function pmpro_check_discount_code_level_for_gateway_compatibility( $discount_code_level = NULL ) {
|
207 |
+
// Return if no gateway is set.
|
208 |
+
$gateway = pmpro_getOption( 'gateway' );
|
209 |
+
if ( empty( $gateway ) ) {
|
210 |
+
return true;
|
211 |
+
}
|
212 |
+
|
213 |
+
global $wpdb;
|
214 |
+
|
215 |
+
// Check ALL the discount code levels if none specified.
|
216 |
+
if ( empty( $discount_code_level ) ) {
|
217 |
+
$sqlQuery = "SELECT * FROM $wpdb->pmpro_discount_codes_levels ORDER BY id ASC";
|
218 |
+
$discount_codes_levels = $wpdb->get_results($sqlQuery, OBJECT);
|
219 |
+
if ( ! empty( $discount_codes_levels ) ) {
|
220 |
+
foreach ( $discount_codes_levels as $discount_code_level ) {
|
221 |
+
if ( ! pmpro_check_discount_code_level_for_gateway_compatibility( $discount_code_level ) ) {
|
222 |
+
return false;
|
223 |
+
}
|
224 |
+
}
|
225 |
+
}
|
226 |
+
} else {
|
227 |
+
// Need to look it up?
|
228 |
+
if ( is_numeric( $discount_code_level ) ) {
|
229 |
+
$discount_code_level = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->pmpro_discount_codes_levels WHERE id = %d LIMIT 1" , $discount_code_level ) );
|
230 |
+
}
|
231 |
+
|
232 |
+
// Check this discount code level for gateway compatibility
|
233 |
+
if ( $gateway == 'stripe' ) {
|
234 |
+
if ( ( $discount_code_level->billing_limit > 0 ) && ! function_exists( 'pmprosbl_plugin_row_meta' ) ) {
|
235 |
+
global $pmpro_stripe_error;
|
236 |
+
$pmpro_stripe_error = true;
|
237 |
+
return false;
|
238 |
+
}
|
239 |
+
} elseif ( $gateway == 'payflowpro' ) {
|
240 |
+
if ( $discount_code_level->trial_amount > 0 ) {
|
241 |
+
global $pmpro_payflow_error;
|
242 |
+
$pmpro_payflow_error = true;
|
243 |
+
return false;
|
244 |
+
}
|
245 |
+
} elseif ( $gateway == 'braintree' ) {
|
246 |
+
if ( $discount_code_level->trial_amount > 0 ||
|
247 |
+
( $discount_code_level->cycle_number > 0 && ( $discount_code_level->cycle_period == "Day" || $discount_code_level->cycle_period == "Week" ) ) ) {
|
248 |
+
global $pmpro_braintree_error;
|
249 |
+
$pmpro_braintree_error = true;
|
250 |
+
return false;
|
251 |
+
}
|
252 |
+
} if ( $gateway == 'twocheckout' ) {
|
253 |
+
if ( $discount_code_level->trial_amount > $discount_code_level->billing_amount ) {
|
254 |
+
global $pmpro_twocheckout_error;
|
255 |
+
$pmpro_twocheckout_error = true;
|
256 |
+
return false;
|
257 |
+
}
|
258 |
+
}
|
259 |
+
}
|
260 |
+
|
261 |
+
return true;
|
262 |
+
}
|
263 |
+
|
264 |
/*
|
265 |
Checks if PMPro settings are complete or if there are any errors.
|
266 |
|
adminpages/orders-csv.php
CHANGED
@@ -498,7 +498,7 @@ for ( $ic = 1; $ic <= $iterations; $ic ++ ) {
|
|
498 |
}
|
499 |
|
500 |
//timestamp
|
501 |
-
$ts = date_i18n( $dateformat, $order->
|
502 |
array_push( $csvoutput, pmpro_enclose( $ts ) );
|
503 |
|
504 |
//any extra columns
|
498 |
}
|
499 |
|
500 |
//timestamp
|
501 |
+
$ts = date_i18n( $dateformat, $order->getTimestamp() );
|
502 |
array_push( $csvoutput, pmpro_enclose( $ts ) );
|
503 |
|
504 |
//any extra columns
|
adminpages/orders.php
CHANGED
@@ -815,11 +815,11 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
815 |
<td>
|
816 |
<?php
|
817 |
if ( in_array( 'timestamp', $read_only_fields ) && $order_id > 0 ) {
|
818 |
-
echo esc_html( date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $order->
|
819 |
} else {
|
820 |
// set up date vars
|
821 |
if ( ! empty( $order->timestamp ) ) {
|
822 |
-
$timestamp = $order->
|
823 |
} else {
|
824 |
$timestamp = current_time( 'timestamp' );
|
825 |
}
|
@@ -1452,8 +1452,8 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
|
|
1452 |
</td>
|
1453 |
<td><?php echo esc_html( $order->status ); ?></td>
|
1454 |
<td>
|
1455 |
-
<?php echo esc_html( date_i18n( get_option( 'date_format' ), $order->
|
1456 |
-
<?php echo esc_html( date_i18n( get_option( 'time_format' ), $order->
|
1457 |
</td>
|
1458 |
<td>
|
1459 |
<?php if ( $order->getDiscountCode() ) { ?>
|
815 |
<td>
|
816 |
<?php
|
817 |
if ( in_array( 'timestamp', $read_only_fields ) && $order_id > 0 ) {
|
818 |
+
echo esc_html( date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $order->getTimestamp() ) );
|
819 |
} else {
|
820 |
// set up date vars
|
821 |
if ( ! empty( $order->timestamp ) ) {
|
822 |
+
$timestamp = $order->getTimestamp();
|
823 |
} else {
|
824 |
$timestamp = current_time( 'timestamp' );
|
825 |
}
|
1452 |
</td>
|
1453 |
<td><?php echo esc_html( $order->status ); ?></td>
|
1454 |
<td>
|
1455 |
+
<?php echo esc_html( date_i18n( get_option( 'date_format' ), $order->getTimestamp() ) ); ?><br/>
|
1456 |
+
<?php echo esc_html( date_i18n( get_option( 'time_format' ), $order->getTimestamp() ) ); ?>
|
1457 |
</td>
|
1458 |
<td>
|
1459 |
<?php if ( $order->getDiscountCode() ) { ?>
|
adminpages/templates/orders-email.php
CHANGED
@@ -15,7 +15,7 @@
|
|
15 |
</tr>
|
16 |
<tr>
|
17 |
<td>
|
18 |
-
<?php echo __( 'Date:', 'paid-memberships-pro' ) . ' ' . date_i18n( 'Y-m-d', $order->
|
19 |
</td>
|
20 |
</tr>
|
21 |
<?php if(!empty($order->billing->name)): ?>
|
15 |
</tr>
|
16 |
<tr>
|
17 |
<td>
|
18 |
+
<?php echo __( 'Date:', 'paid-memberships-pro' ) . ' ' . date_i18n( 'Y-m-d', $order->getTimestamp() ) ?>
|
19 |
</td>
|
20 |
</tr>
|
21 |
<?php if(!empty($order->billing->name)): ?>
|
adminpages/templates/orders-print.php
CHANGED
@@ -51,7 +51,7 @@
|
|
51 |
</tr>
|
52 |
<tr>
|
53 |
<td>
|
54 |
-
<?php echo __( 'Date:', 'paid-memberships-pro' ) . ' ' . date_i18n( get_option( 'date_format' ), $order->
|
55 |
</td>
|
56 |
</tr>
|
57 |
</table>
|
51 |
</tr>
|
52 |
<tr>
|
53 |
<td>
|
54 |
+
<?php echo __( 'Date:', 'paid-memberships-pro' ) . ' ' . date_i18n( get_option( 'date_format' ), $order->getTimestamp() ); ?>
|
55 |
</td>
|
56 |
</tr>
|
57 |
</table>
|
classes/class.memberorder.php
CHANGED
@@ -134,16 +134,13 @@
|
|
134 |
$this->gateway_environment = $dbobj->gateway_environment;
|
135 |
$this->payment_transaction_id = $dbobj->payment_transaction_id;
|
136 |
$this->subscription_transaction_id = $dbobj->subscription_transaction_id;
|
137 |
-
$this->timestamp = $dbobj->timestamp;
|
138 |
$this->affiliate_id = $dbobj->affiliate_id;
|
139 |
$this->affiliate_subid = $dbobj->affiliate_subid;
|
140 |
|
141 |
$this->notes = $dbobj->notes;
|
142 |
$this->checkout_id = $dbobj->checkout_id;
|
143 |
|
144 |
-
// Fix the timestamp for local time
|
145 |
-
$this->timestamp = strtotime( get_date_from_gmt( $this->timestamp, 'Y-m-d H:i:s' ) );
|
146 |
-
|
147 |
//reset the gateway
|
148 |
if(empty($this->nogateway))
|
149 |
$this->setGateway();
|
@@ -525,6 +522,16 @@
|
|
525 |
return $this->tax;
|
526 |
}
|
527 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
528 |
/**
|
529 |
* Change the timestamp of an order by passing in year, month, day, time.
|
530 |
*
|
@@ -545,10 +552,12 @@
|
|
545 |
global $wpdb;
|
546 |
$this->sqlQuery = "UPDATE $wpdb->pmpro_membership_orders SET timestamp = '" . $date . "' WHERE id = '" . $this->id . "' LIMIT 1";
|
547 |
|
548 |
-
if($wpdb->query($this->sqlQuery) !== "false")
|
|
|
549 |
return $this->getMemberOrderByID($this->id);
|
550 |
-
else
|
551 |
return false;
|
|
|
552 |
}
|
553 |
|
554 |
/**
|
134 |
$this->gateway_environment = $dbobj->gateway_environment;
|
135 |
$this->payment_transaction_id = $dbobj->payment_transaction_id;
|
136 |
$this->subscription_transaction_id = $dbobj->subscription_transaction_id;
|
137 |
+
$this->timestamp = strtotime( $dbobj->timestamp );
|
138 |
$this->affiliate_id = $dbobj->affiliate_id;
|
139 |
$this->affiliate_subid = $dbobj->affiliate_subid;
|
140 |
|
141 |
$this->notes = $dbobj->notes;
|
142 |
$this->checkout_id = $dbobj->checkout_id;
|
143 |
|
|
|
|
|
|
|
144 |
//reset the gateway
|
145 |
if(empty($this->nogateway))
|
146 |
$this->setGateway();
|
522 |
return $this->tax;
|
523 |
}
|
524 |
|
525 |
+
/**
|
526 |
+
* Get the timestamp for this order.
|
527 |
+
*
|
528 |
+
* @param bool $gmt whether to return GMT time or local timestamp.
|
529 |
+
* @return int timestamp.
|
530 |
+
*/
|
531 |
+
function getTimestamp( $gmt = false ) {
|
532 |
+
return $gmt ? $this->timestamp : strtotime( get_date_from_gmt( date( 'Y-m-d H:i:s', $this->timestamp ) ) );
|
533 |
+
}
|
534 |
+
|
535 |
/**
|
536 |
* Change the timestamp of an order by passing in year, month, day, time.
|
537 |
*
|
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;
|
560 |
+
}
|
561 |
}
|
562 |
|
563 |
/**
|
classes/class.pmproemail.php
CHANGED
@@ -288,7 +288,7 @@
|
|
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->
|
292 |
$this->data["billing_name"] = $invoice->billing->name;
|
293 |
$this->data["billing_street"] = $invoice->billing->street;
|
294 |
$this->data["billing_city"] = $invoice->billing->city;
|
@@ -388,7 +388,7 @@
|
|
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->
|
392 |
$this->data["billing_name"] = $invoice->billing->name;
|
393 |
$this->data["billing_street"] = $invoice->billing->street;
|
394 |
$this->data["billing_city"] = $invoice->billing->city;
|
@@ -711,7 +711,7 @@
|
|
711 |
"user_email" => $user->user_email,
|
712 |
"invoice_id" => $invoice->code,
|
713 |
"invoice_total" => pmpro_formatPrice($invoice->total),
|
714 |
-
"invoice_date" => date_i18n(get_option('date_format'), $invoice->
|
715 |
"billing_name" => $invoice->billing->name,
|
716 |
"billing_street" => $invoice->billing->street,
|
717 |
"billing_city" => $invoice->billing->city,
|
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() );
|
292 |
$this->data["billing_name"] = $invoice->billing->name;
|
293 |
$this->data["billing_street"] = $invoice->billing->street;
|
294 |
$this->data["billing_city"] = $invoice->billing->city;
|
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());
|
392 |
$this->data["billing_name"] = $invoice->billing->name;
|
393 |
$this->data["billing_street"] = $invoice->billing->street;
|
394 |
$this->data["billing_city"] = $invoice->billing->city;
|
711 |
"user_email" => $user->user_email,
|
712 |
"invoice_id" => $invoice->code,
|
713 |
"invoice_total" => pmpro_formatPrice($invoice->total),
|
714 |
+
"invoice_date" => date_i18n(get_option('date_format'), $invoice->getTimestamp()),
|
715 |
"billing_name" => $invoice->billing->name,
|
716 |
"billing_street" => $invoice->billing->street,
|
717 |
"billing_city" => $invoice->billing->city,
|
classes/gateways/class.pmprogateway_paypal.php
CHANGED
@@ -278,7 +278,7 @@
|
|
278 |
<?php if($gateway == "paypal" || $gateway == "paypalexpress" || $gateway == "paypalstandard") { ?>
|
279 |
<span id="pmpro_paypalexpress_checkout" <?php if(($gateway != "paypalexpress" && $gateway != "paypalstandard") || !$pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
280 |
<input type="hidden" name="submit-checkout" value="1" />
|
281 |
-
<input type="image" id="pmpro_btn-submit-paypal" 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.
|
282 |
</span>
|
283 |
<?php } ?>
|
284 |
|
@@ -762,7 +762,7 @@
|
|
762 |
/** Initial payment **/
|
763 |
$nvpStr = "";
|
764 |
// STARTDATE is Required, even if useless here. Start from 24h before the order timestamp, to avoid timezone related issues.
|
765 |
-
$nvpStr .= "&STARTDATE=" . urlencode( gmdate( DATE_W3C, $order->
|
766 |
// filter results by a specific transaction id.
|
767 |
$nvpStr .= "&TRANSACTIONID=" . urlencode($order->subscription_transaction_id);
|
768 |
|
278 |
<?php if($gateway == "paypal" || $gateway == "paypalexpress" || $gateway == "paypalstandard") { ?>
|
279 |
<span id="pmpro_paypalexpress_checkout" <?php if(($gateway != "paypalexpress" && $gateway != "paypalstandard") || !$pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
280 |
<input type="hidden" name="submit-checkout" value="1" />
|
281 |
+
<input type="image" id="pmpro_btn-submit-paypal" 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");?>" />
|
282 |
</span>
|
283 |
<?php } ?>
|
284 |
|
762 |
/** Initial payment **/
|
763 |
$nvpStr = "";
|
764 |
// STARTDATE is Required, even if useless here. Start from 24h before the order timestamp, to avoid timezone related issues.
|
765 |
+
$nvpStr .= "&STARTDATE=" . urlencode( gmdate( DATE_W3C, $order->getTimestamp() - DAY_IN_SECONDS ) . 'Z' );
|
766 |
// filter results by a specific transaction id.
|
767 |
$nvpStr .= "&TRANSACTIONID=" . urlencode($order->subscription_transaction_id);
|
768 |
|
classes/gateways/class.pmprogateway_paypalexpress.php
CHANGED
@@ -473,7 +473,7 @@
|
|
473 |
?>
|
474 |
<span id="pmpro_paypalexpress_checkout" <?php if(($gateway != "paypalexpress" && $gateway != "paypalstandard") || !$pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
475 |
<input type="hidden" name="submit-checkout" value="1" />
|
476 |
-
<input type="image" id="pmpro_btn-submit-paypalexpress" 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.
|
477 |
</span>
|
478 |
|
479 |
<span id="pmpro_submit_span" <?php if(($gateway == "paypalexpress" || $gateway == "paypalstandard") && $pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
@@ -614,6 +614,7 @@
|
|
614 |
$order->status = "review";
|
615 |
|
616 |
//update order
|
|
|
617 |
$order->saveOrder();
|
618 |
|
619 |
return true;
|
@@ -844,7 +845,7 @@
|
|
844 |
/** Initial payment **/
|
845 |
$nvpStr = "";
|
846 |
// STARTDATE is Required, even if useless here. Start from 24h before the order timestamp, to avoid timezone related issues.
|
847 |
-
$nvpStr .= "&STARTDATE=" . urlencode( gmdate( DATE_W3C, $order->
|
848 |
// filter results by a specific transaction id.
|
849 |
$nvpStr .= "&TRANSACTIONID=" . urlencode($order->subscription_transaction_id);
|
850 |
|
473 |
?>
|
474 |
<span id="pmpro_paypalexpress_checkout" <?php if(($gateway != "paypalexpress" && $gateway != "paypalstandard") || !$pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
475 |
<input type="hidden" name="submit-checkout" value="1" />
|
476 |
+
<input type="image" id="pmpro_btn-submit-paypalexpress" 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");?>" />
|
477 |
</span>
|
478 |
|
479 |
<span id="pmpro_submit_span" <?php if(($gateway == "paypalexpress" || $gateway == "paypalstandard") && $pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
614 |
$order->status = "review";
|
615 |
|
616 |
//update order
|
617 |
+
|
618 |
$order->saveOrder();
|
619 |
|
620 |
return true;
|
845 |
/** Initial payment **/
|
846 |
$nvpStr = "";
|
847 |
// STARTDATE is Required, even if useless here. Start from 24h before the order timestamp, to avoid timezone related issues.
|
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 |
|
classes/gateways/class.pmprogateway_paypalstandard.php
CHANGED
@@ -238,7 +238,7 @@
|
|
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.
|
242 |
</span>
|
243 |
|
244 |
<span id="pmpro_submit_span" <?php if(($gateway == "paypalexpress" || $gateway == "paypalstandard") && $pmpro_requirebilling) { ?>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" 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 } ?>>
|
includes/capabilities.php
CHANGED
@@ -24,20 +24,23 @@ add_action('admin_init', 'pmpro_check_admin_capabilities', 5, 2);
|
|
24 |
// use the capability definition for $role_name and add/remove capabilities as requested
|
25 |
function pmpro_set_capabilities_for_role( $role_name, $action = 'enable' )
|
26 |
{
|
27 |
-
$cap_array = pmpro_get_capability_defs($role_name);
|
28 |
-
|
29 |
-
//add caps to specified role
|
30 |
$role = get_role( $role_name );
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
// Iterate through the relevant caps for the role & add or remove them
|
33 |
-
foreach( $cap_array as $cap_name )
|
34 |
-
{
|
35 |
if ( $action == 'enable' )
|
36 |
-
$role->add_cap($cap_name);
|
37 |
|
38 |
if ( $action == 'disable' )
|
39 |
-
$role->remove_cap($cap_name);
|
40 |
}
|
|
|
41 |
}
|
42 |
|
43 |
// used to define what capabilities goes with what role.
|
24 |
// use the capability definition for $role_name and add/remove capabilities as requested
|
25 |
function pmpro_set_capabilities_for_role( $role_name, $action = 'enable' )
|
26 |
{
|
|
|
|
|
|
|
27 |
$role = get_role( $role_name );
|
28 |
+
if ( empty( $role ) ) {
|
29 |
+
// Role does not exist.
|
30 |
+
return false;
|
31 |
+
}
|
32 |
+
|
33 |
+
$cap_array = pmpro_get_capability_defs( $role_name );
|
34 |
|
35 |
// Iterate through the relevant caps for the role & add or remove them
|
36 |
+
foreach( $cap_array as $cap_name ) {
|
|
|
37 |
if ( $action == 'enable' )
|
38 |
+
$role->add_cap( $cap_name );
|
39 |
|
40 |
if ( $action == 'disable' )
|
41 |
+
$role->remove_cap( $cap_name );
|
42 |
}
|
43 |
+
return true;
|
44 |
}
|
45 |
|
46 |
// used to define what capabilities goes with what role.
|
includes/content.php
CHANGED
@@ -347,45 +347,7 @@ function pmpro_membership_content_filter( $content, $skipcheck = false ) {
|
|
347 |
$content = "";
|
348 |
}
|
349 |
|
350 |
-
|
351 |
-
$post_membership_levels_ids = array();
|
352 |
-
}
|
353 |
-
|
354 |
-
if( empty( $post_membership_levels_names ) ) {
|
355 |
-
$post_membership_levels_names = array();
|
356 |
-
}
|
357 |
-
|
358 |
-
//hide levels which don't allow signups by default
|
359 |
-
if( ! apply_filters("pmpro_membership_content_filter_disallowed_levels", false, $post_membership_levels_ids, $post_membership_levels_names ) ) {
|
360 |
-
foreach($post_membership_levels_ids as $key=>$id) {
|
361 |
-
//does this level allow registrations?
|
362 |
-
$level_obj = pmpro_getLevel( $id );
|
363 |
-
if( empty( $level_obj ) || empty( $level_obj->allow_signups ) ) {
|
364 |
-
unset( $post_membership_levels_ids[$key] );
|
365 |
-
unset( $post_membership_levels_names[$key] );
|
366 |
-
}
|
367 |
-
}
|
368 |
-
}
|
369 |
-
|
370 |
-
$pmpro_content_message_pre = '<div class="' . pmpro_get_element_class( 'pmpro_content_message' ) . '">';
|
371 |
-
$pmpro_content_message_post = '</div>';
|
372 |
-
|
373 |
-
$sr_search = array("!!levels!!", "!!referrer!!", "!!login_url!!", "!!login_page_url!!", "!!levels_url!!", "!!levels_page_url!!");
|
374 |
-
$sr_replace = array(pmpro_implodeToEnglish($post_membership_levels_names), urlencode(site_url($_SERVER['REQUEST_URI'])), esc_url( pmpro_login_url() ), esc_url( pmpro_login_url() ), esc_url( pmpro_url( 'levels' ) ), esc_url( pmpro_url( 'levels' ) ));
|
375 |
-
|
376 |
-
//get the correct message to show at the bottom
|
377 |
-
if( is_feed() ) {
|
378 |
-
$newcontent = apply_filters("pmpro_rss_text_filter", stripslashes(pmpro_getOption("rsstext")));
|
379 |
-
$content .= $pmpro_content_message_pre . str_replace($sr_search, $sr_replace, $newcontent) . $pmpro_content_message_post;
|
380 |
-
} elseif( $current_user->ID ) {
|
381 |
-
//not a member
|
382 |
-
$newcontent = apply_filters("pmpro_non_member_text_filter", stripslashes(pmpro_getOption("nonmembertext")));
|
383 |
-
$content .= $pmpro_content_message_pre . str_replace($sr_search, $sr_replace, $newcontent) . $pmpro_content_message_post;
|
384 |
-
} else {
|
385 |
-
//not logged in!
|
386 |
-
$newcontent = apply_filters("pmpro_not_logged_in_text_filter", stripslashes(pmpro_getOption("notloggedintext")));
|
387 |
-
$content .= $pmpro_content_message_pre . str_replace($sr_search, $sr_replace, $newcontent) . $pmpro_content_message_post;
|
388 |
-
}
|
389 |
}
|
390 |
|
391 |
return $content;
|
@@ -395,7 +357,7 @@ add_filter('the_content_rss', 'pmpro_membership_content_filter', 5);
|
|
395 |
add_filter('comment_text_rss', 'pmpro_membership_content_filter', 5);
|
396 |
|
397 |
/*
|
398 |
-
If the_excerpt is called, we want to disable the_content filters so the PMPro messages aren't added to the content before AND after the
|
399 |
*/
|
400 |
function pmpro_membership_excerpt_filter($content, $skipcheck = false) {
|
401 |
remove_filter('the_content', 'pmpro_membership_content_filter', 5);
|
347 |
$content = "";
|
348 |
}
|
349 |
|
350 |
+
$content = pmpro_get_no_access_message( $content, $post_membership_levels_ids, $post_membership_levels_names );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
351 |
}
|
352 |
|
353 |
return $content;
|
357 |
add_filter('comment_text_rss', 'pmpro_membership_content_filter', 5);
|
358 |
|
359 |
/*
|
360 |
+
If the_excerpt is called, we want to disable the_content filters so the PMPro messages aren't added to the content before AND after the excerpt.
|
361 |
*/
|
362 |
function pmpro_membership_excerpt_filter($content, $skipcheck = false) {
|
363 |
remove_filter('the_content', 'pmpro_membership_content_filter', 5);
|
includes/functions.php
CHANGED
@@ -668,7 +668,7 @@ function pmpro_next_payment( $user_id = null, $order_status = 'success', $format
|
|
668 |
|
669 |
if ( ! empty( $order ) && ! empty( $order->id ) && ! empty( $level ) && ! empty( $level->id ) && ! empty( $level->cycle_number ) ) {
|
670 |
// next payment date
|
671 |
-
$nextdate = strtotime( '+' . $level->cycle_number . ' ' . $level->cycle_period, $order->
|
672 |
|
673 |
$r = $nextdate;
|
674 |
} else {
|
@@ -1787,7 +1787,66 @@ function pmpro_actions_nav_separator() {
|
|
1787 |
$separator = apply_filters( 'pmpro_actions_nav_separator', ' | ' );
|
1788 |
|
1789 |
return $separator;
|
1790 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1791 |
|
1792 |
/*
|
1793 |
pmpro_getMembershipLevelForUser() returns the first active membership level for a user
|
@@ -2192,6 +2251,11 @@ function pmpro_getLevelAtCheckout( $level_id = null, $discount_code = null ) {
|
|
2192 |
$pmpro_level = $wpdb->get_row( "SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql( $level_id ) . "' AND allow_signups = 1 LIMIT 1" );
|
2193 |
}
|
2194 |
|
|
|
|
|
|
|
|
|
|
|
2195 |
// filter the level (for upgrades, etc)
|
2196 |
$pmpro_level = apply_filters( 'pmpro_checkout_level', $pmpro_level );
|
2197 |
|
668 |
|
669 |
if ( ! empty( $order ) && ! empty( $order->id ) && ! empty( $level ) && ! empty( $level->id ) && ! empty( $level->cycle_number ) ) {
|
670 |
// next payment date
|
671 |
+
$nextdate = strtotime( '+' . $level->cycle_number . ' ' . $level->cycle_period, $order->getTimestamp() );
|
672 |
|
673 |
$r = $nextdate;
|
674 |
} else {
|
1787 |
$separator = apply_filters( 'pmpro_actions_nav_separator', ' | ' );
|
1788 |
|
1789 |
return $separator;
|
1790 |
+
}
|
1791 |
+
|
1792 |
+
/**
|
1793 |
+
* pmpro_get_no_access_message to return the appropriate content message for the protected content.
|
1794 |
+
*
|
1795 |
+
* @param array $level_ids The array of level IDs this post is protected for.
|
1796 |
+
* @param array $level_names The array of names for the levels this post is protected for.
|
1797 |
+
*
|
1798 |
+
* @return string $content The appropriate content message for the given user/visitor and required levels.
|
1799 |
+
*
|
1800 |
+
*/
|
1801 |
+
function pmpro_get_no_access_message( $content, $level_ids, $level_names = NULL ) {
|
1802 |
+
global $current_user;
|
1803 |
+
|
1804 |
+
if ( empty( $level_ids ) ) {
|
1805 |
+
$level_ids = array();
|
1806 |
+
}
|
1807 |
+
|
1808 |
+
if ( empty( $level_names ) ) {
|
1809 |
+
$level_names = array();
|
1810 |
+
foreach ( $level_ids as $key => $id ) {
|
1811 |
+
$level_obj = pmpro_getLevel( $id );
|
1812 |
+
$level_names[] = $level_obj->name;
|
1813 |
+
}
|
1814 |
+
}
|
1815 |
+
|
1816 |
+
// Hide levels which don't allow signups by default.
|
1817 |
+
if( ! apply_filters( 'pmpro_membership_content_filter_disallowed_levels', false, $level_ids, $level_names ) ) {
|
1818 |
+
foreach ( $level_ids as $key => $id ) {
|
1819 |
+
// Does this level allow registrations?
|
1820 |
+
$level_obj = pmpro_getLevel( $id );
|
1821 |
+
if ( empty( $level_obj ) || empty( $level_obj->allow_signups ) ) {
|
1822 |
+
unset( $level_ids[$key] );
|
1823 |
+
unset( $level_names[$key] );
|
1824 |
+
}
|
1825 |
+
}
|
1826 |
+
}
|
1827 |
+
|
1828 |
+
$pmpro_content_message_pre = '<div class="' . pmpro_get_element_class( 'pmpro_content_message' ) . '">';
|
1829 |
+
$pmpro_content_message_post = '</div>';
|
1830 |
+
|
1831 |
+
$sr_search = array( '!!levels!!', '!!referrer!!', '!!login_url!!', '!!login_page_url!!', '!!levels_url!!', '!!levels_page_url!!' );
|
1832 |
+
$sr_replace = array( pmpro_implodeToEnglish( $level_names ), urlencode( site_url( $_SERVER['REQUEST_URI'] ) ), esc_url( pmpro_login_url() ), esc_url( pmpro_login_url() ), esc_url( pmpro_url( 'levels' ) ), esc_url( pmpro_url( 'levels' ) ) );
|
1833 |
+
|
1834 |
+
// Get the correct message to show at the bottom.
|
1835 |
+
if ( is_feed() ) {
|
1836 |
+
$newcontent = apply_filters( 'pmpro_rss_text_filter', stripslashes( pmpro_getOption( 'rsstext' ) ) );
|
1837 |
+
$content .= $pmpro_content_message_pre . str_replace( $sr_search, $sr_replace, $newcontent ) . $pmpro_content_message_post;
|
1838 |
+
} elseif ( $current_user->ID ) {
|
1839 |
+
//not a member
|
1840 |
+
$newcontent = apply_filters( 'pmpro_non_member_text_filter', stripslashes( pmpro_getOption( 'nonmembertext' ) ) );
|
1841 |
+
$content .= $pmpro_content_message_pre . str_replace( $sr_search, $sr_replace, $newcontent ) . $pmpro_content_message_post;
|
1842 |
+
} else {
|
1843 |
+
//not logged in!
|
1844 |
+
$newcontent = apply_filters( 'pmpro_not_logged_in_text_filter', stripslashes( pmpro_getOption( 'notloggedintext' ) ) );
|
1845 |
+
$content .= $pmpro_content_message_pre . str_replace( $sr_search, $sr_replace, $newcontent ) . $pmpro_content_message_post;
|
1846 |
+
}
|
1847 |
+
|
1848 |
+
return $content;
|
1849 |
+
}
|
1850 |
|
1851 |
/*
|
1852 |
pmpro_getMembershipLevelForUser() returns the first active membership level for a user
|
2251 |
$pmpro_level = $wpdb->get_row( "SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql( $level_id ) . "' AND allow_signups = 1 LIMIT 1" );
|
2252 |
}
|
2253 |
|
2254 |
+
// hide the confirmation message
|
2255 |
+
if ( ! empty( $pmpro_level->confirmation ) ) {
|
2256 |
+
$pmpro_level->confirmation = '';
|
2257 |
+
}
|
2258 |
+
|
2259 |
// filter the level (for upgrades, etc)
|
2260 |
$pmpro_level = apply_filters( 'pmpro_checkout_level', $pmpro_level );
|
2261 |
|
includes/metaboxes.php
CHANGED
@@ -1,139 +1,140 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
|
4 |
-
*/
|
5 |
-
function pmpro_page_meta()
|
6 |
-
{
|
7 |
global $post, $wpdb;
|
8 |
-
$membership_levels = pmpro_getAllLevels(true, true);
|
9 |
-
$page_levels = $wpdb->get_col("SELECT membership_id FROM {$wpdb->pmpro_memberships_pages} WHERE page_id = '
|
10 |
?>
|
11 |
<ul id="membershipschecklist" class="list:category categorychecklist form-no-clear">
|
12 |
-
<input type="hidden" name="pmpro_noncename" id="pmpro_noncename" value="<?php echo wp_create_nonce( plugin_basename(__FILE__) )?>" />
|
13 |
<?php
|
14 |
$in_member_cat = false;
|
15 |
-
foreach($membership_levels as $level)
|
16 |
-
|
17 |
-
|
18 |
-
<li id="membership-level-<?php echo $level->id?>">
|
19 |
<label class="selectit">
|
20 |
-
<input id="in-membership-level-<?php echo $level->id?>" type="checkbox" <?php if(in_array($level->id, $page_levels)) { ?>checked="checked"<?php } ?> name="page_levels[]" value="<?php echo $level->id
|
21 |
<?php
|
22 |
-
echo $level->name;
|
23 |
//Check which categories are protected for this level
|
24 |
-
$protectedcategories = $wpdb->get_col("SELECT category_id FROM $wpdb->pmpro_memberships_categories WHERE membership_id = $level->id");
|
25 |
//See if this post is in any of the level's protected categories
|
26 |
-
if(in_category($protectedcategories, $post->id))
|
27 |
-
{
|
28 |
$in_member_cat = true;
|
29 |
echo ' *';
|
30 |
}
|
31 |
?>
|
32 |
</label>
|
33 |
</li>
|
34 |
-
|
35 |
}
|
36 |
?>
|
37 |
</ul>
|
38 |
<?php
|
39 |
-
if('post' == get_post_type($post) && $in_member_cat) { ?>
|
40 |
<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>
|
41 |
<?php
|
42 |
}
|
43 |
|
44 |
-
do_action('pmpro_after_require_membership_metabox', $post);
|
45 |
?>
|
46 |
<?php
|
47 |
}
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
|
|
|
52 |
global $wpdb;
|
53 |
|
54 |
-
if(empty($post_id))
|
55 |
return false;
|
|
|
56 |
|
57 |
-
|
|
|
58 |
return $post_id;
|
59 |
}
|
60 |
|
61 |
-
//
|
62 |
-
|
63 |
-
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
|
64 |
return $post_id;
|
|
|
65 |
|
66 |
-
//
|
67 |
-
if(
|
68 |
-
|
69 |
-
if ( !current_user_can( 'edit_page', $post_id ) )
|
70 |
-
return $post_id;
|
71 |
}
|
72 |
-
|
73 |
-
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
75 |
return $post_id;
|
|
|
76 |
}
|
77 |
|
78 |
-
// OK, we're authenticated
|
79 |
-
if(
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
$mydata = NULL;
|
85 |
|
86 |
-
|
87 |
-
|
88 |
|
89 |
-
|
90 |
-
|
91 |
-
{
|
92 |
-
|
93 |
-
$wpdb->query("INSERT INTO {$wpdb->pmpro_memberships_pages} (membership_id, page_id) VALUES('" . intval($level) . "', '" . intval($post_id) . "')");
|
94 |
}
|
95 |
-
|
96 |
-
return $mydata;
|
97 |
}
|
98 |
-
|
99 |
-
|
100 |
}
|
101 |
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
add_meta_box('pmpro_page_meta', __('Require Membership', 'paid-memberships-pro' ), 'pmpro_page_meta', '
|
|
|
107 |
}
|
108 |
-
if (is_admin())
|
109 |
-
|
110 |
-
add_action('
|
111 |
-
add_action('save_post', 'pmpro_page_save');
|
112 |
}
|
113 |
|
114 |
-
|
115 |
-
|
116 |
-
|
|
|
117 |
global $membership_levels, $post, $wpdb;
|
118 |
|
119 |
$protectedlevels = array();
|
120 |
-
foreach($membership_levels as $level)
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
}
|
126 |
-
|
127 |
-
{
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
<?php
|
138 |
}
|
139 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Require Membership Meta Box
|
4 |
+
*/
|
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 |
<ul id="membershipschecklist" class="list:category categorychecklist form-no-clear">
|
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;
|
14 |
+
foreach( $membership_levels as $level ) {
|
15 |
+
?>
|
16 |
+
<li id="membership-level-<?php echo esc_attr( $level->id ); ?>">
|
|
|
17 |
<label class="selectit">
|
18 |
+
<input id="in-membership-level-<?php echo esc_attr( $level->id ); ?>" type="checkbox" <?php if(in_array($level->id, $page_levels)) { ?>checked="checked"<?php } ?> name="page_levels[]" value="<?php echo esc_attr( $level->id ) ;?>" />
|
19 |
<?php
|
20 |
+
echo esc_html( $level->name );
|
21 |
//Check which categories are protected for this level
|
22 |
+
$protectedcategories = $wpdb->get_col( "SELECT category_id FROM $wpdb->pmpro_memberships_categories WHERE membership_id = '" . intval( $level->id ) . "'");
|
23 |
//See if this post is in any of the level's protected categories
|
24 |
+
if( in_category( $protectedcategories, $post->id ) ) {
|
|
|
25 |
$in_member_cat = true;
|
26 |
echo ' *';
|
27 |
}
|
28 |
?>
|
29 |
</label>
|
30 |
</li>
|
31 |
+
<?php
|
32 |
}
|
33 |
?>
|
34 |
</ul>
|
35 |
<?php
|
36 |
+
if( 'post' == get_post_type( $post ) && $in_member_cat ) { ?>
|
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
|
44 |
}
|
45 |
|
46 |
+
/**
|
47 |
+
* Saves meta options when a page is saved.
|
48 |
+
*/
|
49 |
+
function pmpro_page_save( $post_id ) {
|
50 |
global $wpdb;
|
51 |
|
52 |
+
if( empty( $post_id ) ) {
|
53 |
return false;
|
54 |
+
}
|
55 |
|
56 |
+
// Post is saving somehow with our meta box not shown.
|
57 |
+
if ( ! isset( $_POST['pmpro_noncename'] ) ) {
|
58 |
return $post_id;
|
59 |
}
|
60 |
|
61 |
+
// Verify the nonce.
|
62 |
+
if ( ! wp_verify_nonce( $_POST['pmpro_noncename'], plugin_basename( __FILE__ ) ) ) {
|
|
|
63 |
return $post_id;
|
64 |
+
}
|
65 |
|
66 |
+
// Don't try to update meta fields on AUTOSAVE.
|
67 |
+
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
68 |
+
return $post_id;
|
|
|
|
|
69 |
}
|
70 |
+
|
71 |
+
// Check permissions.
|
72 |
+
if( ! empty( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {
|
73 |
+
if ( ! current_user_can( 'edit_page', $post_id ) ) {
|
74 |
+
return $post_id;
|
75 |
+
}
|
76 |
+
} else {
|
77 |
+
if ( ! current_user_can( 'edit_post', $post_id ) ) {
|
78 |
return $post_id;
|
79 |
+
}
|
80 |
}
|
81 |
|
82 |
+
// OK, we're authenticated. We need to find and save the data.
|
83 |
+
if( ! empty( $_POST['page_levels'] ) ) {
|
84 |
+
$mydata = $_POST['page_levels'];
|
85 |
+
} else {
|
86 |
+
$mydata = NULL;
|
87 |
+
}
|
|
|
88 |
|
89 |
+
// Remove all memberships for this page.
|
90 |
+
$wpdb->query( "DELETE FROM {$wpdb->pmpro_memberships_pages} WHERE page_id = '" . intval( $post_id ) . "'" );
|
91 |
|
92 |
+
// Add new memberships for this page.
|
93 |
+
if( is_array( $mydata ) ) {
|
94 |
+
foreach( $mydata as $level ) {
|
95 |
+
$wpdb->query( "INSERT INTO {$wpdb->pmpro_memberships_pages} (membership_id, page_id) VALUES('" . intval( $level ) . "', '" . intval( $post_id ) . "')" );
|
|
|
96 |
}
|
|
|
|
|
97 |
}
|
98 |
+
|
99 |
+
return $mydata;
|
100 |
}
|
101 |
|
102 |
+
/**
|
103 |
+
* Wrapper to add meta boxes
|
104 |
+
*/
|
105 |
+
function pmpro_page_meta_wrapper() {
|
106 |
+
add_meta_box( 'pmpro_page_meta', __( 'Require Membership', 'paid-memberships-pro' ), 'pmpro_page_meta', 'page', 'side', 'high' );
|
107 |
+
add_meta_box( 'pmpro_page_meta', __( 'Require Membership', 'paid-memberships-pro' ), 'pmpro_page_meta', 'post', 'side', 'high' );
|
108 |
}
|
109 |
+
if ( is_admin() ) {
|
110 |
+
add_action( 'admin_menu', 'pmpro_page_meta_wrapper' );
|
111 |
+
add_action( 'save_post', 'pmpro_page_save' );
|
|
|
112 |
}
|
113 |
|
114 |
+
/**
|
115 |
+
* Show membership level restrictions on category edit.
|
116 |
+
*/
|
117 |
+
function pmpro_taxonomy_meta( $term ) {
|
118 |
global $membership_levels, $post, $wpdb;
|
119 |
|
120 |
$protectedlevels = array();
|
121 |
+
foreach( $membership_levels as $level ) {
|
122 |
+
$protectedlevel = $wpdb->get_col( "SELECT category_id FROM $wpdb->pmpro_memberships_categories WHERE membership_id = '" . intval( $level->id ) . "' AND category_id = '" . intval( $term->term_id ) . "'" );
|
123 |
+
if( ! empty( $protectedlevel ) ) {
|
124 |
+
$protectedlevels[] .= '<a target="_blank" href="admin.php?page=pmpro-membershiplevels&edit=' . intval( $level->id ) . '">' . esc_html( $level->name ) . '</a>';
|
125 |
+
}
|
126 |
}
|
127 |
+
|
128 |
+
if( ! empty( $protectedlevels ) ) {
|
129 |
+
?>
|
130 |
+
<tr class="form-field">
|
131 |
+
<th scope="row" valign="top"><?php _e( 'Membership Levels', 'paid-memberships-pro' ); ?></label></th>
|
132 |
+
<td>
|
133 |
+
<p><strong>
|
134 |
+
<?php echo implode(', ',$protectedlevels); ?></strong></p>
|
135 |
+
<p class="description"><?php _e( 'Only members of these levels will be able to view posts in this category.', 'paid-memberships-pro' ); ?></p>
|
136 |
+
</td>
|
137 |
+
</tr>
|
138 |
<?php
|
139 |
}
|
140 |
}
|
includes/privacy.php
CHANGED
@@ -235,7 +235,7 @@ function pmpro_personal_data_exporter( $email_address, $page = 1 ) {
|
|
235 |
),
|
236 |
array(
|
237 |
'name' => __( 'Order Date', 'paid-memberships-pro' ),
|
238 |
-
'value' => date( get_option( 'date_format' ), $order->
|
239 |
),
|
240 |
array(
|
241 |
'name' => __( 'Level', 'paid-memberships-pro' ),
|
235 |
),
|
236 |
array(
|
237 |
'name' => __( 'Order Date', 'paid-memberships-pro' ),
|
238 |
+
'value' => date( get_option( 'date_format' ), $order->getTimestamp() ),
|
239 |
),
|
240 |
array(
|
241 |
'name' => __( 'Level', 'paid-memberships-pro' ),
|
includes/profile.php
CHANGED
@@ -457,6 +457,15 @@ function pmpro_member_profile_edit_form() {
|
|
457 |
}
|
458 |
}
|
459 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
460 |
// Show error messages.
|
461 |
if ( ! empty( $errors ) ) { ?>
|
462 |
<div class="<?php echo pmpro_get_element_class( 'pmpro_message pmpro_error', 'pmpro_error' ); ?>">
|
@@ -513,7 +522,7 @@ function pmpro_member_profile_edit_form() {
|
|
513 |
<input type="text" readonly="readonly" name="user_email" id="user_email" value="<?php echo esc_attr( $user->user_email ); ?>" class="<?php echo pmpro_get_element_class( 'input', 'user_email' ); ?>" />
|
514 |
<p class="<?php echo pmpro_get_element_class( 'lite' ); ?>"><?php esc_html_e( 'Site administrators must use the WordPress dashboard to update their email address.', 'paid-memberships-pro' ); ?></p>
|
515 |
<?php } else { ?>
|
516 |
-
<input type="text" name="<?php echo esc_attr( $field_key ); ?>" id="<?php echo esc_attr( $field_key ); ?>" value="<?php echo esc_attr( $user->{$field_key} ); ?>" class="<?php echo pmpro_get_element_class( 'input', $field_key ); ?>" />
|
517 |
<?php } ?>
|
518 |
</div>
|
519 |
<?php } ?>
|
457 |
}
|
458 |
}
|
459 |
|
460 |
+
/**
|
461 |
+
* Fires before member profile update errors are returned.
|
462 |
+
*
|
463 |
+
* @param $errors WP_Error object (passed by reference).
|
464 |
+
* @param $update Whether this is a user update.
|
465 |
+
* @param $user User object (passed by reference).
|
466 |
+
*/
|
467 |
+
do_action_ref_array( 'pmpro_user_profile_update_errors', array( &$errors, $update, &$user ) );
|
468 |
+
|
469 |
// Show error messages.
|
470 |
if ( ! empty( $errors ) ) { ?>
|
471 |
<div class="<?php echo pmpro_get_element_class( 'pmpro_message pmpro_error', 'pmpro_error' ); ?>">
|
522 |
<input type="text" readonly="readonly" name="user_email" id="user_email" value="<?php echo esc_attr( $user->user_email ); ?>" class="<?php echo pmpro_get_element_class( 'input', 'user_email' ); ?>" />
|
523 |
<p class="<?php echo pmpro_get_element_class( 'lite' ); ?>"><?php esc_html_e( 'Site administrators must use the WordPress dashboard to update their email address.', 'paid-memberships-pro' ); ?></p>
|
524 |
<?php } else { ?>
|
525 |
+
<input type="text" name="<?php echo esc_attr( $field_key ); ?>" id="<?php echo esc_attr( $field_key ); ?>" value="<?php echo esc_attr( stripslashes( $user->{$field_key} ) ); ?>" class="<?php echo pmpro_get_element_class( 'input', $field_key ); ?>" />
|
526 |
<?php } ?>
|
527 |
</div>
|
528 |
<?php } ?>
|
includes/rest-api.php
CHANGED
@@ -138,12 +138,12 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
138 |
array(
|
139 |
'methods' => WP_REST_Server::READABLE,
|
140 |
'callback' => array( $this, 'pmpro_rest_api_get_discount_code' ),
|
141 |
-
'
|
142 |
),
|
143 |
array(
|
144 |
'methods' => 'POST,PUT,PATCH',
|
145 |
'callback' => array( $this, 'pmpro_rest_api_set_discount_code' ),
|
146 |
-
'
|
147 |
),
|
148 |
));
|
149 |
|
@@ -157,6 +157,7 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
157 |
array(
|
158 |
'methods' => WP_REST_Server::READABLE,
|
159 |
'callback' => array( $this, 'pmpro_rest_api_get_checkout_level' ),
|
|
|
160 |
),
|
161 |
));
|
162 |
|
@@ -169,6 +170,7 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
169 |
array(
|
170 |
'methods' => WP_REST_Server::READABLE,
|
171 |
'callback' => array( $this, 'pmpro_rest_api_get_checkout_levels' ),
|
|
|
172 |
),
|
173 |
));
|
174 |
}
|
@@ -183,12 +185,22 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
183 |
|
184 |
$user_id = isset( $params['user_id'] ) ? $params['user_id'] : null;
|
185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
if ( empty( $user_id ) && !empty( $params['email'] ) ) {
|
187 |
$user = get_user_by_email( $params['email'] );
|
188 |
$user_id = $user->ID;
|
189 |
}
|
190 |
|
191 |
-
|
|
|
|
|
|
|
|
|
192 |
|
193 |
return new WP_REST_Response( $level, 200 );
|
194 |
}
|
@@ -203,12 +215,22 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
203 |
|
204 |
$user_id = isset( $params['user_id'] ) ? $params['user_id'] : null;
|
205 |
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
if ( empty( $user_id ) && !empty( $params['email'] ) ) {
|
207 |
$user = get_user_by_email( $params['email'] );
|
208 |
$user_id = $user->ID;
|
209 |
}
|
210 |
|
211 |
-
|
|
|
|
|
|
|
|
|
212 |
|
213 |
return new WP_REST_Response( $levels, 200 );
|
214 |
}
|
@@ -234,7 +256,14 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
234 |
}
|
235 |
}
|
236 |
|
237 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
238 |
return new WP_REST_Response( $has_access, 200 );
|
239 |
}
|
240 |
|
@@ -261,8 +290,14 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
261 |
if ( ! function_exists( 'pmpro_changeMembershipLevel' ) ) {
|
262 |
return new WP_REST_Response( 'Paid Memberships Pro function not found.', 404 );
|
263 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
264 |
|
265 |
-
return new WP_REST_Response(
|
266 |
}
|
267 |
|
268 |
/**
|
@@ -292,8 +327,14 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
292 |
if ( ! function_exists( 'pmpro_cancelMembershipLevel' ) ) {
|
293 |
return new WP_REST_Response( 'Paid Memberships Pro function not found.', 404 );
|
294 |
}
|
295 |
-
|
296 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
297 |
}
|
298 |
|
299 |
/**
|
@@ -314,7 +355,16 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
314 |
return new WP_REST_Response( 'ID not passed through', 400 );
|
315 |
}
|
316 |
|
317 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
318 |
}
|
319 |
|
320 |
/**
|
@@ -496,7 +546,7 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
496 |
function pmpro_rest_api_get_checkout_level( $request ) {
|
497 |
$params = $request->get_params();
|
498 |
|
499 |
-
$level_id = isset( $params['
|
500 |
if ( empty( $level_id ) ) {
|
501 |
return new WP_REST_Response( 'No level found.', 400 );
|
502 |
}
|
@@ -517,8 +567,8 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
517 |
if ( ! empty( $pmpro_checkout_level_ids ) ) {
|
518 |
// MMPU Compatibility...
|
519 |
$level_ids = $pmpro_checkout_level_ids;
|
520 |
-
} elseif ( isset( $_REQUEST['
|
521 |
-
$level_ids = explode( '+', $_REQUEST['
|
522 |
}
|
523 |
|
524 |
if ( empty( $level_ids ) ) {
|
@@ -549,21 +599,41 @@ if ( class_exists( 'WP_REST_Controller' ) ) {
|
|
549 |
|
550 |
$method = $request->get_method();
|
551 |
$route = $request->get_route();
|
552 |
-
|
553 |
-
// default permissions to 'read' (subscriber)
|
554 |
-
$permissions = current_user_can('read');
|
555 |
-
if ( $method != 'GET' ) {
|
556 |
-
$permissions = current_user_can('pmpro_edit_memberships'); //Assume they can edit membership levels.
|
557 |
-
}
|
558 |
|
559 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
560 |
if ( ! in_array( $method, pmpro_get_rest_api_methods( $route ) ) ) {
|
561 |
-
$
|
562 |
}
|
563 |
|
564 |
-
$
|
565 |
|
566 |
-
return $
|
567 |
}
|
568 |
|
569 |
/**
|
138 |
array(
|
139 |
'methods' => WP_REST_Server::READABLE,
|
140 |
'callback' => array( $this, 'pmpro_rest_api_get_discount_code' ),
|
141 |
+
'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
|
142 |
),
|
143 |
array(
|
144 |
'methods' => 'POST,PUT,PATCH',
|
145 |
'callback' => array( $this, 'pmpro_rest_api_set_discount_code' ),
|
146 |
+
'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
|
147 |
),
|
148 |
));
|
149 |
|
157 |
array(
|
158 |
'methods' => WP_REST_Server::READABLE,
|
159 |
'callback' => array( $this, 'pmpro_rest_api_get_checkout_level' ),
|
160 |
+
'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
|
161 |
),
|
162 |
));
|
163 |
|
170 |
array(
|
171 |
'methods' => WP_REST_Server::READABLE,
|
172 |
'callback' => array( $this, 'pmpro_rest_api_get_checkout_levels' ),
|
173 |
+
'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
|
174 |
),
|
175 |
));
|
176 |
}
|
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 |
|
199 |
+
if ( ! empty( $user_id ) ) {
|
200 |
+
$level = pmpro_getMembershipLevelForUser( $user_id );
|
201 |
+
} else {
|
202 |
+
$level = false;
|
203 |
+
}
|
204 |
|
205 |
return new WP_REST_Response( $level, 200 );
|
206 |
}
|
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 |
|
229 |
+
if ( ! empty( $user_id ) ) {
|
230 |
+
$levels = pmpro_getMembershipLevelsForUser( $user_id );
|
231 |
+
} else {
|
232 |
+
$levels = false;
|
233 |
+
}
|
234 |
|
235 |
return new WP_REST_Response( $levels, 200 );
|
236 |
}
|
256 |
}
|
257 |
}
|
258 |
|
259 |
+
if ( ! empty( $user_id ) ) {
|
260 |
+
$has_access = pmpro_has_membership_access( $post_id, $user_id );
|
261 |
+
} else {
|
262 |
+
// No good user, so say no.
|
263 |
+
// Technically this will make public posts look restricted.
|
264 |
+
$has_access = false;
|
265 |
+
}
|
266 |
+
|
267 |
return new WP_REST_Response( $has_access, 200 );
|
268 |
}
|
269 |
|
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 |
|
303 |
/**
|
327 |
if ( ! function_exists( 'pmpro_cancelMembershipLevel' ) ) {
|
328 |
return new WP_REST_Response( 'Paid Memberships Pro function not found.', 404 );
|
329 |
}
|
330 |
+
|
331 |
+
if ( ! empty( $user_id ) ) {
|
332 |
+
$response = pmpro_cancelMembershipLevel( $level_id, $user_id, 'inactive' );
|
333 |
+
} else {
|
334 |
+
$response = false;
|
335 |
+
}
|
336 |
+
|
337 |
+
return new WP_REST_Response( $response, 200 );
|
338 |
}
|
339 |
|
340 |
/**
|
355 |
return new WP_REST_Response( 'ID not passed through', 400 );
|
356 |
}
|
357 |
|
358 |
+
$level = new PMPro_Membership_Level( $id );
|
359 |
+
|
360 |
+
// Hide confirmation message if not an admin or member.
|
361 |
+
if ( ! empty( $level->confirmation )
|
362 |
+
&& ! pmpro_hasMembershipLevel( $id )
|
363 |
+
&& ! current_user_can( 'pmpro_edit_memberships' ) ) {
|
364 |
+
$level->confirmation = '';
|
365 |
+
}
|
366 |
+
|
367 |
+
return new WP_REST_Response( $level, 200 );
|
368 |
}
|
369 |
|
370 |
/**
|
546 |
function pmpro_rest_api_get_checkout_level( $request ) {
|
547 |
$params = $request->get_params();
|
548 |
|
549 |
+
$level_id = isset( $params['level_id'] ) ? $params['level_id'] : null;
|
550 |
if ( empty( $level_id ) ) {
|
551 |
return new WP_REST_Response( 'No level found.', 400 );
|
552 |
}
|
567 |
if ( ! empty( $pmpro_checkout_level_ids ) ) {
|
568 |
// MMPU Compatibility...
|
569 |
$level_ids = $pmpro_checkout_level_ids;
|
570 |
+
} elseif ( isset( $_REQUEST['level_id'] ) ) {
|
571 |
+
$level_ids = explode( '+', $_REQUEST['level_id'] );
|
572 |
}
|
573 |
|
574 |
if ( empty( $level_ids ) ) {
|
599 |
|
600 |
$method = $request->get_method();
|
601 |
$route = $request->get_route();
|
|
|
|
|
|
|
|
|
|
|
|
|
602 |
|
603 |
+
// Default to requiring pmpro_edit_memberships capability.
|
604 |
+
$permission = current_user_can( 'pmpro_edit_memberships' );
|
605 |
+
|
606 |
+
// Check other caps for some routes.
|
607 |
+
$route_caps = array(
|
608 |
+
'/pmpro/v1/has_membership_access' => 'pmpro_edit_memberships',
|
609 |
+
'/pmpro/v1/get_membership_level_for_user' => 'pmpro_edit_memberships',
|
610 |
+
'/pmpro/v1/get_membership_levels_for_user' => 'pmpro_edit_memberships',
|
611 |
+
'/pmpro/v1/change_membership_level' => 'pmpro_edit_memberships',
|
612 |
+
'/pmpro/v1/cancel_membership_level' => 'pmpro_edit_memberships',
|
613 |
+
'/pmpro/v1/membership_level' => true,
|
614 |
+
'/pmpro/v1/discount_code' => 'pmpro_discountcodes',
|
615 |
+
'/pmpro/v1/checkout_level' => true,
|
616 |
+
'/pmpro/v1/checkout_levels' => true,
|
617 |
+
);
|
618 |
+
$route_caps = apply_filters( 'pmpro_rest_api_route_capabilities', $route_caps, $request );
|
619 |
+
|
620 |
+
if ( isset( $route_caps[$route] ) ) {
|
621 |
+
if ( $route_caps[$route] === true ) {
|
622 |
+
// public
|
623 |
+
$permission = true;
|
624 |
+
} else {
|
625 |
+
$permission = current_user_can( $route_caps[$route] );
|
626 |
+
}
|
627 |
+
}
|
628 |
+
|
629 |
+
// Is the request method allowed? We disable DELETE by default.
|
630 |
if ( ! in_array( $method, pmpro_get_rest_api_methods( $route ) ) ) {
|
631 |
+
$permission = false;
|
632 |
}
|
633 |
|
634 |
+
$permission = apply_filters( 'pmpro_rest_api_permissions', $permission, $request );
|
635 |
|
636 |
+
return $permission;
|
637 |
}
|
638 |
|
639 |
/**
|
includes/updates.php
CHANGED
@@ -104,13 +104,11 @@ if(pmpro_isUpdateRequired() && (empty($_REQUEST['page']) || $_REQUEST['page'] !=
|
|
104 |
*/
|
105 |
function pmpro_updates_notice() {
|
106 |
?>
|
107 |
-
<div class="update-nag">
|
108 |
-
<p>
|
109 |
<?php
|
110 |
echo __( 'Paid Memberships Pro Data Update Required', 'paid-memberships-pro' ) . '. ';
|
111 |
echo sprintf(__( '(1) <a target="_blank" href="%s">Backup your WordPress database</a></strong> and then (2) <a href="%s">click here to start the update</a>.', 'paid-memberships-pro' ), 'https://codex.wordpress.org/WordPress_Backups#Database_Backup_Instructions', admin_url('admin.php?page=pmpro-updates'));
|
112 |
?>
|
113 |
-
</p>
|
114 |
</div>
|
115 |
<?php
|
116 |
}
|
104 |
*/
|
105 |
function pmpro_updates_notice() {
|
106 |
?>
|
107 |
+
<div class="update-nag notice notice-warning inline">
|
|
|
108 |
<?php
|
109 |
echo __( 'Paid Memberships Pro Data Update Required', 'paid-memberships-pro' ) . '. ';
|
110 |
echo sprintf(__( '(1) <a target="_blank" href="%s">Backup your WordPress database</a></strong> and then (2) <a href="%s">click here to start the update</a>.', 'paid-memberships-pro' ), 'https://codex.wordpress.org/WordPress_Backups#Database_Backup_Instructions', admin_url('admin.php?page=pmpro-updates'));
|
111 |
?>
|
|
|
112 |
</div>
|
113 |
<?php
|
114 |
}
|
includes/updates/upgrade_1_8_9_3.php
CHANGED
@@ -168,7 +168,7 @@ function pmpro_upgrade_1_8_9_3_ajax() {
|
|
168 |
//calculate and fix the end date
|
169 |
if(empty($user->membership_level->enddate)) {
|
170 |
if ( ! empty( $pmpro_level->expiration_number ) ) {
|
171 |
-
$enddate = date_i18n( "Y-m-d", strtotime( "+ " . $pmpro_level->expiration_number . " " . $pmpro_level->expiration_period, $last_order->
|
172 |
} else {
|
173 |
$enddate = "NULL";
|
174 |
}
|
168 |
//calculate and fix the end date
|
169 |
if(empty($user->membership_level->enddate)) {
|
170 |
if ( ! empty( $pmpro_level->expiration_number ) ) {
|
171 |
+
$enddate = date_i18n( "Y-m-d", strtotime( "+ " . $pmpro_level->expiration_number . " " . $pmpro_level->expiration_period, $last_order->getTimestamp() ) );
|
172 |
} else {
|
173 |
$enddate = "NULL";
|
174 |
}
|
languages/{paid-memberships-pro-vi_VN.mo → paid-memberships-pro-vi.mo}
RENAMED
File without changes
|
languages/{paid-memberships-pro-vi_VN.po → paid-memberships-pro-vi.po}
RENAMED
File without changes
|
pages/cancel.php
CHANGED
@@ -73,10 +73,13 @@
|
|
73 |
</td>
|
74 |
<td class="<?php echo pmpro_get_element_class( 'pmpro_cancel-membership-expiration' ); ?>">
|
75 |
<?php
|
76 |
-
if($level->enddate)
|
77 |
-
|
78 |
-
|
79 |
-
|
|
|
|
|
|
|
80 |
?>
|
81 |
</td>
|
82 |
<td class="<?php echo pmpro_get_element_class( 'pmpro_cancel-membership-cancel' ); ?>">
|
73 |
</td>
|
74 |
<td class="<?php echo pmpro_get_element_class( 'pmpro_cancel-membership-expiration' ); ?>">
|
75 |
<?php
|
76 |
+
if($level->enddate) {
|
77 |
+
$expiration_text = date_i18n( get_option( 'date_format' ), $level->enddate );
|
78 |
+
} else {
|
79 |
+
$expiration_text = "---";
|
80 |
+
}
|
81 |
+
|
82 |
+
echo apply_filters( 'pmpro_account_membership_expiration_text', $expiration_text, $level );
|
83 |
?>
|
84 |
</td>
|
85 |
<td class="<?php echo pmpro_get_element_class( 'pmpro_cancel-membership-cancel' ); ?>">
|
pages/confirmation.php
CHANGED
@@ -44,7 +44,7 @@
|
|
44 |
echo wp_kses_post( $confirmation_message );
|
45 |
?>
|
46 |
<h3>
|
47 |
-
<?php printf(__('Invoice #%s on %s', 'paid-memberships-pro' ), $pmpro_invoice->code, date_i18n(get_option('date_format'), $pmpro_invoice->
|
48 |
</h3>
|
49 |
<a class="<?php echo pmpro_get_element_class( 'pmpro_a-print' ); ?>" href="javascript:window.print()"><?php _e('Print', 'paid-memberships-pro' );?></a>
|
50 |
<ul>
|
44 |
echo wp_kses_post( $confirmation_message );
|
45 |
?>
|
46 |
<h3>
|
47 |
+
<?php printf(__('Invoice #%s on %s', 'paid-memberships-pro' ), $pmpro_invoice->code, date_i18n(get_option('date_format'), $pmpro_invoice->getTimestamp()));?>
|
48 |
</h3>
|
49 |
<a class="<?php echo pmpro_get_element_class( 'pmpro_a-print' ); ?>" href="javascript:window.print()"><?php _e('Print', 'paid-memberships-pro' );?></a>
|
50 |
<ul>
|
pages/invoice.php
CHANGED
@@ -18,7 +18,7 @@
|
|
18 |
$pmpro_invoice->getUser();
|
19 |
$pmpro_invoice->getMembershipLevel();
|
20 |
?>
|
21 |
-
<h3><?php printf(__('Invoice #%s on %s', 'paid-memberships-pro' ), $pmpro_invoice->code, date_i18n(get_option('date_format'), $pmpro_invoice->
|
22 |
<a class="<?php echo pmpro_get_element_class( 'pmpro_a-print' ); ?>" href="javascript:window.print()"><?php _e('Print', 'paid-memberships-pro' ); ?></a>
|
23 |
<ul>
|
24 |
<?php do_action("pmpro_invoice_bullets_top", $pmpro_invoice); ?>
|
@@ -119,7 +119,7 @@
|
|
119 |
{
|
120 |
?>
|
121 |
<tr>
|
122 |
-
<td><a href="<?php echo pmpro_url("invoice", "?invoice=" . $invoice->code)?>"><?php echo date_i18n(get_option("date_format"), $invoice->
|
123 |
<td><a href="<?php echo pmpro_url("invoice", "?invoice=" . $invoice->code)?>"><?php echo $invoice->code; ?></a></td>
|
124 |
<td><?php echo $invoice->membership_level_name;?></td>
|
125 |
<td><?php echo pmpro_formatPrice($invoice->total);?></td>
|
18 |
$pmpro_invoice->getUser();
|
19 |
$pmpro_invoice->getMembershipLevel();
|
20 |
?>
|
21 |
+
<h3><?php printf(__('Invoice #%s on %s', 'paid-memberships-pro' ), $pmpro_invoice->code, date_i18n(get_option('date_format'), $pmpro_invoice->getTimestamp()));?></h3>
|
22 |
<a class="<?php echo pmpro_get_element_class( 'pmpro_a-print' ); ?>" href="javascript:window.print()"><?php _e('Print', 'paid-memberships-pro' ); ?></a>
|
23 |
<ul>
|
24 |
<?php do_action("pmpro_invoice_bullets_top", $pmpro_invoice); ?>
|
119 |
{
|
120 |
?>
|
121 |
<tr>
|
122 |
+
<td><a href="<?php echo pmpro_url("invoice", "?invoice=" . $invoice->code)?>"><?php echo date_i18n(get_option("date_format"), $invoice->getTimestamp())?></a></td>
|
123 |
<td><a href="<?php echo pmpro_url("invoice", "?invoice=" . $invoice->code)?>"><?php echo $invoice->code; ?></a></td>
|
124 |
<td><?php echo $invoice->membership_level_name;?></td>
|
125 |
<td><?php echo pmpro_formatPrice($invoice->total);?></td>
|
paid-memberships-pro.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Paid Memberships Pro
|
4 |
* Plugin URI: https://www.paidmembershipspro.com
|
5 |
* Description: The most complete member management and membership subscriptions plugin for WordPress.
|
6 |
-
* Version: 2.4.
|
7 |
* Author: Stranger Studios
|
8 |
* Author URI: https://www.strangerstudios.com
|
9 |
* Text Domain: paid-memberships-pro
|
@@ -16,7 +16,7 @@
|
|
16 |
*/
|
17 |
|
18 |
// version constant
|
19 |
-
define( 'PMPRO_VERSION', '2.4.
|
20 |
define( 'PMPRO_USER_AGENT', 'Paid Memberships Pro v' . PMPRO_VERSION . '; ' . site_url() );
|
21 |
define( 'PMPRO_MIN_PHP_VERSION', '5.6' );
|
22 |
|
3 |
* Plugin Name: Paid Memberships Pro
|
4 |
* Plugin URI: https://www.paidmembershipspro.com
|
5 |
* Description: The most complete member management and membership subscriptions plugin for WordPress.
|
6 |
+
* Version: 2.4.3
|
7 |
* Author: Stranger Studios
|
8 |
* Author URI: https://www.strangerstudios.com
|
9 |
* Text Domain: paid-memberships-pro
|
16 |
*/
|
17 |
|
18 |
// version constant
|
19 |
+
define( 'PMPRO_VERSION', '2.4.3' );
|
20 |
define( 'PMPRO_USER_AGENT', 'Paid Memberships Pro v' . PMPRO_VERSION . '; ' . site_url() );
|
21 |
define( 'PMPRO_MIN_PHP_VERSION', '5.6' );
|
22 |
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: strangerstudios, kimannwall, andrewza, dlparker1005, paidmembershi
|
|
3 |
Tags: memberships, members, subscriptions, ecommerce, user registration, member, membership, e-commerce, paypal, stripe, braintree, authorize.net, payflow, restrict access, restrict content, directory
|
4 |
Requires at least: 4
|
5 |
Tested up to: 5.5
|
6 |
-
Stable tag: 2.4.
|
7 |
|
8 |
Get Paid with Paid Memberships Pro: The most complete member management and membership subscriptions plugin for your WordPress site.
|
9 |
|
@@ -153,6 +153,26 @@ Not sure? You can find out by doing a bit a research.
|
|
153 |
8. Membership Account page, display all sections or show specific sections using shortcode attributes.
|
154 |
|
155 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
= 2.4.1 - 2020-08-10 =
|
157 |
* BUG FIX: Fixed issues with password resets on WP Engine hosting due to security features added by their mu-plugin.
|
158 |
* BUG FIX: Fixed issue where end dates were showing up incorrectly in the confirmation email sometimes.
|
3 |
Tags: memberships, members, subscriptions, ecommerce, user registration, member, membership, e-commerce, paypal, stripe, braintree, authorize.net, payflow, restrict access, restrict content, directory
|
4 |
Requires at least: 4
|
5 |
Tested up to: 5.5
|
6 |
+
Stable tag: 2.4.3
|
7 |
|
8 |
Get Paid with Paid Memberships Pro: The most complete member management and membership subscriptions plugin for your WordPress site.
|
9 |
|
153 |
8. Membership Account page, display all sections or show specific sections using shortcode attributes.
|
154 |
|
155 |
== Changelog ==
|
156 |
+
= 2.4.3 - 2020-08-25
|
157 |
+
* SECURITY: Fixed a cross-site scripting vulnerability in the code that updates the Required Membership settings on a post. This vulnerability could have been used in conjunction with other security vulnerabilities to trick an admin into editing the membership settings for a page, potentially exposing members only content to non-members. It is unlikely that there was any active exploitation of this vulnerability. This issue may also have shown up as a bug on some sites using page builders, where the membership settings for a post would be cleared out when editing a post. (Thanks to the wp.org plugin review team for catching this issue.)
|
158 |
+
* SECURITY: Better escaping of variables shown in the Require Membership meta box and related SQL queries.
|
159 |
+
* BUG FIX/ENHANCEMENT: Renamed the Vietnamese language files to match what is expected.
|
160 |
+
|
161 |
+
= 2.4.2 - 2020-08-24
|
162 |
+
* SECURITY: Updated the PMPro REST API endpoints accessed via the GET method to also require appropriate capabilities to access. The membership confirmation text will be hidden from non-members and non-admins. The endpoints to check a user's level or access to a post require the pmpro_edit_memberships capability now. You should make sure your API users have the appropriate capabilities to use the API. You can use the pmpro_rest_api_route_capabilities filter and/or pmpro_rest_api_permissions filter to change this behavior.
|
163 |
+
* BUG FIX: Fixed issues with the PMPro REST API endpoints, including the discount code and checkout level endpoints.
|
164 |
+
* BUG FIX: Fixed issue with backslashes in the display name when editing form the PMPro frontend profile page.
|
165 |
+
* BUG FIX: Fixed issue where timestamps were showing up incorrectly for recent orders shown on the dashboard page.
|
166 |
+
BUG FIX: Fixed issue where PMPro would always try to add capabilities to the administrator role, even if you removed that role for some reason.
|
167 |
+
* ENHANCEMENT: Added a pmpro_get_no_access_message() function, which can be used to show the no access messages.
|
168 |
+
* ENHANCEMENT: Added a "show_noaccess" property to the membership shortcode. When set, it will show the noaccess message to users who don't have the levels specified.
|
169 |
+
* ENHANCEMENT: Added a pmpro_user_profile_update_errors hook, which can be used to show errors on the PMPro frontend profile page.
|
170 |
+
* ENHANCEMENT: The pmpro_set_capabilities_for_role() function now returns true or false if the caps were added in case others want to use this function and tell if it worked.
|
171 |
+
* ENHANCEMENT: You can now include links in the description of the fields you add to the PMPro advanced settings page via the pmpro_custom_advanced_settings filter.
|
172 |
+
* ENHANCEMENT: Updated the PayPal gateways to use the latest versions of the PayPal buttons.
|
173 |
+
* ENHANCEMENT: Fixed styling of the PMPro update script notice.
|
174 |
+
* ENHANCEMENT: Added the pmpro_account_membership_expiration_text filter to the expiration dates shown on the cancel page when using MMPU.
|
175 |
+
|
176 |
= 2.4.1 - 2020-08-10 =
|
177 |
* BUG FIX: Fixed issues with password resets on WP Engine hosting due to security features added by their mu-plugin.
|
178 |
* BUG FIX: Fixed issue where end dates were showing up incorrectly in the confirmation email sometimes.
|
shortcodes/membership.php
CHANGED
@@ -12,7 +12,8 @@ function pmpro_shortcode_membership($atts, $content=null, $code="")
|
|
12 |
extract(shortcode_atts(array(
|
13 |
'level' => NULL,
|
14 |
'levels' => NULL,
|
15 |
-
'delay' => NULL
|
|
|
16 |
), $atts));
|
17 |
|
18 |
//if levels is used instead of level
|
@@ -85,7 +86,13 @@ function pmpro_shortcode_membership($atts, $content=null, $code="")
|
|
85 |
//to show or not to show
|
86 |
if($hasaccess)
|
87 |
return do_shortcode($content); //show content
|
88 |
-
else
|
89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
}
|
91 |
add_shortcode("membership", "pmpro_shortcode_membership");
|
12 |
extract(shortcode_atts(array(
|
13 |
'level' => NULL,
|
14 |
'levels' => NULL,
|
15 |
+
'delay' => NULL,
|
16 |
+
'show_noaccess' => NULL
|
17 |
), $atts));
|
18 |
|
19 |
//if levels is used instead of level
|
86 |
//to show or not to show
|
87 |
if($hasaccess)
|
88 |
return do_shortcode($content); //show content
|
89 |
+
else {
|
90 |
+
if ( empty( $show_noaccess ) ) {
|
91 |
+
return '';
|
92 |
+
} else {
|
93 |
+
$content = '';
|
94 |
+
return pmpro_get_no_access_message( $content, $levels );
|
95 |
+
}
|
96 |
+
}
|
97 |
}
|
98 |
add_shortcode("membership", "pmpro_shortcode_membership");
|
shortcodes/pmpro_account.php
CHANGED
@@ -237,7 +237,7 @@ function pmpro_shortcode_account($atts, $content=null, $code="")
|
|
237 |
}
|
238 |
?>
|
239 |
<tr id="pmpro_account-invoice-<?php echo $invoice->code; ?>">
|
240 |
-
<td><a href="<?php echo pmpro_url("invoice", "?invoice=" . $invoice->code)?>"><?php echo date_i18n(get_option("date_format"), $invoice->
|
241 |
<td><?php if(!empty($invoice->membership_level)) echo $invoice->membership_level->name; else echo __("N/A", 'paid-memberships-pro' );?></td>
|
242 |
<td><?php echo pmpro_formatPrice($invoice->total)?></td>
|
243 |
<td><?php echo $display_status; ?></td>
|
237 |
}
|
238 |
?>
|
239 |
<tr id="pmpro_account-invoice-<?php echo $invoice->code; ?>">
|
240 |
+
<td><a href="<?php echo pmpro_url("invoice", "?invoice=" . $invoice->code)?>"><?php echo date_i18n(get_option("date_format"), $invoice->getTimestamp())?></td>
|
241 |
<td><?php if(!empty($invoice->membership_level)) echo $invoice->membership_level->name; else echo __("N/A", 'paid-memberships-pro' );?></td>
|
242 |
<td><?php echo pmpro_formatPrice($invoice->total)?></td>
|
243 |
<td><?php echo $display_status; ?></td>
|