Paid Memberships Pro - Version 2.2

Version Description

  • 2019-11-22 =
  • FEATURE: The Members List is now shown in an official "WP List Table". Most columns are sortable. The screen options in the upper right can be used to add/remove columns. (Thanks, Thomas Sjolshagen, Paul Barthmaier, and David Parker)
  • FEATURE: Showing useful notifications in the PMPro dashboard area. Notifications are shown no more than once ever 12 hours, and no more than 3 times every week. The PMPro Advanced Settings page has an option to only show security-related notifications.
  • SECURITY: Better sanitizing of values in the 2Checkout INS handler.
  • BUG FIX: Fixed issue since WP 5.3 where expiration dates and other dates could be off by a month after saving.
  • BUG FIX: Fixed issue where Stripe orders processed through the webhook would use the current date instead of the date of the order. This was an issue if you had to rerun a webhook later.
  • BUG FIX: Fixed issue level confirmation text was sometimes not shown in emails when it was supposed to.
  • BUG FIX: Russian Rubles are now configured to have 2 decimals again. In practice, decimals aren't often used for rubles and we are looking into ways to store the decimals (because gateways like Stripe need them) while showing values without decimals.
  • BUG FIX: Fixed bug where the "logged in as" message would sometimes show twice on the update billing page.
  • BUG FIX/ENHANCEMENT: Updated dashboard to adopt WordPress 5.3 formatting updates.
  • BUG FIX/ENHANCEMENT: Updated frontend pages to improve cross-browser and cross-theme compatibility.
  • BUG FIX/ENHANCEMENT: New free orders will always have the "success" status after checkout.
  • BUG FIX/ENHANCEMENT: Better handling of tax values in the PayPal IPN handler.
  • ENHANCEMENT: Added "Edit User" and "Edit Order" links to the admin email when a gateway subscription fails to cancel.
Download this release

Release Info

Developer strangerstudios
Plugin Icon 128x128 Paid Memberships Pro
Version 2.2
Comparing to
See all releases

Code changes from version 2.1.4 to 2.2

Files changed (48) hide show
  1. CHANGELOG.txt +15 -0
  2. adminpages/addons.php +3 -4
  3. adminpages/admin_header.php +9 -1
  4. adminpages/advancedsettings.php +31 -11
  5. adminpages/dashboard.php +7 -2
  6. adminpages/discountcodes.php +9 -10
  7. adminpages/emailsettings.php +8 -8
  8. adminpages/membershiplevels.php +26 -21
  9. adminpages/memberslist.php +30 -295
  10. adminpages/orders.php +58 -64
  11. adminpages/pagesettings.php +3 -1
  12. adminpages/paymentsettings.php +6 -5
  13. adminpages/reports/login.php +2 -2
  14. classes/class-pmpro-members-list-table.php +687 -0
  15. classes/class.memberorder.php +4 -0
  16. classes/gateways/class.pmprogateway_authorizenet.php +5 -4
  17. classes/gateways/class.pmprogateway_braintree.php +8 -10
  18. classes/gateways/class.pmprogateway_check.php +1 -1
  19. classes/gateways/class.pmprogateway_cybersource.php +3 -3
  20. classes/gateways/class.pmprogateway_payflowpro.php +6 -6
  21. classes/gateways/class.pmprogateway_paypal.php +7 -6
  22. classes/gateways/class.pmprogateway_paypalexpress.php +7 -6
  23. classes/gateways/class.pmprogateway_stripe.php +8 -10
  24. classes/gateways/class.pmprogateway_twocheckout.php +9 -8
  25. css/admin.css +76 -4
  26. css/frontend.css +90 -58
  27. includes/adminpages.php +23 -1
  28. includes/currencies.php +1 -1
  29. includes/functions.php +61 -0
  30. includes/license.php +13 -16
  31. includes/notifications.php +537 -51
  32. includes/profile.php +1 -1
  33. js/pmpro-admin.js +23 -0
  34. languages/paid-memberships-pro.mo +0 -0
  35. languages/paid-memberships-pro.po +1219 -1138
  36. languages/paid-memberships-pro.pot +1219 -1138
  37. pages/billing.php +4 -4
  38. pages/cancel.php +3 -3
  39. pages/confirmation.php +2 -2
  40. pages/invoice.php +8 -9
  41. pages/levels.php +1 -1
  42. paid-memberships-pro.php +3 -2
  43. preheaders/checkout.php +2 -2
  44. readme.txt +17 -2
  45. services/ipnhandler.php +7 -0
  46. services/stripe-webhook.php +1 -0
  47. services/twocheckout-ins.php +8 -7
  48. shortcodes/pmpro_account.php +2 -2
CHANGELOG.txt CHANGED
@@ -1,5 +1,20 @@
1
== Changelog ==
2
3
= 2.1.4 - 2019-10-31
4
* BUG FIX: Better exception handling in the Stripe gateway class for PHP 7+.
5
* BUG FIX: Fixing some JS issues at checkout, e.g. related to the "validateCreditCard method is not available" error.
1
== Changelog ==
2
3
+ = 2.2 - 2019-11-22 =
4
+ * FEATURE: The Members List is now shown in an official "WP List Table". Most columns are sortable. The screen options in the upper right can be used to add/remove columns. (Thanks, Thomas Sjolshagen, Paul Barthmaier, and David Parker)
5
+ * FEATURE: Showing useful notifications in the PMPro dashboard area. Notifications are shown no more than once ever 12 hours, and no more than 3 times every week. The PMPro Advanced Settings page has an option to only show security-related notifications.
6
+ * SECURITY: Better sanitizing of values in the 2Checkout INS handler.
7
+ * BUG FIX: Fixed issue since WP 5.3 where expiration dates and other dates could be off by a month after saving.
8
+ * BUG FIX: Fixed issue where Stripe orders processed through the webhook would use the current date instead of the date of the order. This was an issue if you had to rerun a webhook later.
9
+ * BUG FIX: Fixed issue level confirmation text was sometimes not shown in emails when it was supposed to.
10
+ * BUG FIX: Russian Rubles are now configured to have 2 decimals again. In practice, decimals aren't often used for rubles and we are looking into ways to store the decimals (because gateways like Stripe need them) while showing values without decimals.
11
+ * BUG FIX: Fixed bug where the "logged in as" message would sometimes show twice on the update billing page.
12
+ * BUG FIX/ENHANCEMENT: Updated dashboard to adopt WordPress 5.3 formatting updates.
13
+ * BUG FIX/ENHANCEMENT: Updated frontend pages to improve cross-browser and cross-theme compatibility.
14
+ * BUG FIX/ENHANCEMENT: New free orders will always have the "success" status after checkout.
15
+ * BUG FIX/ENHANCEMENT: Better handling of tax values in the PayPal IPN handler.
16
+ * ENHANCEMENT: Added "Edit User" and "Edit Order" links to the admin email when a gateway subscription fails to cancel.
17
+
18
= 2.1.4 - 2019-10-31
19
* BUG FIX: Better exception handling in the Stripe gateway class for PHP 7+.
20
* BUG FIX: Fixing some JS issues at checkout, e.g. related to the "validateCreditCard method is not available" error.
adminpages/addons.php CHANGED
@@ -78,8 +78,9 @@
78
}
79
80
?>
81
- <h2><?php _e('Add Ons', 'paid-memberships-pro' ); ?></h2>
82
-
83
<?php
84
pmpro_showMessage();
85
?>
@@ -97,8 +98,6 @@
97
<li class="uninstalled"><a href="admin.php?page=pmpro-addons&plugin_status=uninstalled" <?php if($status == "uninstalled") { ?>class="current"<?php } ?>><?php _e('Not Installed', 'paid-memberships-pro' ); ?> <span class="count">(<?php echo count($not_installed_addons);?>)</span></a></li>
98
</ul>
99
100
- <br /><br />
101
-
102
<table class="wp-list-table widefat plugins">
103
<thead>
104
<tr>
78
}
79
80
?>
81
+ <h1 class="wp-heading-inline"><?php esc_html_e( 'Add Ons', 'paid-memberships-pro' ); ?></h1>
82
+ <hr class="wp-header-end">
83
+
84
<?php
85
pmpro_showMessage();
86
?>
98
<li class="uninstalled"><a href="admin.php?page=pmpro-addons&plugin_status=uninstalled" <?php if($status == "uninstalled") { ?>class="current"<?php } ?>><?php _e('Not Installed', 'paid-memberships-pro' ); ?> <span class="count">(<?php echo count($not_installed_addons);?>)</span></a></li>
99
</ul>
100
101
<table class="wp-list-table widefat plugins">
102
<thead>
103
<tr>
adminpages/admin_header.php CHANGED
@@ -166,9 +166,17 @@
166
</div>
167
<div id="pmpro_notifications">
168
</div>
169
<script>
170
jQuery(document).ready(function() {
171
- jQuery.get('<?php echo get_admin_url(NULL, "/admin-ajax.php?action=pmpro_notifications"); ?>', function(data) {
172
if(data && data != 'NULL')
173
jQuery('#pmpro_notifications').html(data);
174
});
166
</div>
167
<div id="pmpro_notifications">
168
</div>
169
+ <?php
170
+ // To debug a specific notification.
171
+ if ( !empty( $_REQUEST['pmpro_notification'] ) ) {
172
+ $specific_notification = '&pmpro_notification=' . intval( $_REQUEST['pmpro_notification'] );
173
+ } else {
174
+ $specific_notification = '';
175
+ }
176
+ ?>
177
<script>
178
jQuery(document).ready(function() {
179
+ jQuery.get('<?php echo get_admin_url(NULL, "/admin-ajax.php?action=pmpro_notifications" . $specific_notification ); ?>', function(data) {
180
if(data && data != 'NULL')
181
jQuery('#pmpro_notifications').html(data);
182
});
adminpages/advancedsettings.php CHANGED
@@ -33,6 +33,7 @@
33
pmpro_setOption("hideads");
34
pmpro_setOption("hideadslevels");
35
pmpro_setOption("redirecttosubscription");
36
37
//captcha
38
pmpro_setOption("recaptcha");
@@ -68,6 +69,7 @@
68
$filterqueries = pmpro_getOption('filterqueries');
69
$showexcerpts = pmpro_getOption("showexcerpts");
70
$hideadslevels = pmpro_getOption("hideadslevels");
71
72
if(is_multisite())
73
$redirecttosubscription = pmpro_getOption("redirecttosubscription");
@@ -106,7 +108,8 @@
106
<form action="" method="post" enctype="multipart/form-data">
107
<?php wp_nonce_field('savesettings', 'pmpro_advancedsettings_nonce');?>
108
109
- <h2><?php _e('Advanced Settings', 'paid-memberships-pro' );?></h2>
110
111
<table class="form-table">
112
<tbody>
@@ -115,7 +118,7 @@
115
<label for="nonmembertext"><?php _e('Message for Logged-in Non-members', 'paid-memberships-pro' );?>:</label>
116
</th>
117
<td>
118
- <textarea name="nonmembertext" rows="3" cols="80"><?php echo stripslashes($nonmembertext)?></textarea>
119
<p class="description"><?php _e('This message replaces the post content for non-members. Available variables', 'paid-memberships-pro' );?>: !!levels!!, !!referrer!!</p>
120
</td>
121
</tr>
@@ -124,7 +127,7 @@
124
<label for="notloggedintext"><?php _e('Message for Logged-out Users', 'paid-memberships-pro' );?>:</label>
125
</th>
126
<td>
127
- <textarea name="notloggedintext" rows="3" cols="80"><?php echo stripslashes($notloggedintext)?></textarea>
128
<p class="description"><?php _e('This message replaces the post content for logged-out visitors.', 'paid-memberships-pro' );?></p>
129
</td>
130
</tr>
@@ -133,14 +136,14 @@
133
<label for="rsstext"><?php _e('Message for RSS Feed', 'paid-memberships-pro' );?>:</label>
134
</th>
135
<td>
136
- <textarea name="rsstext" rows="3" cols="80"><?php echo stripslashes($rsstext)?></textarea>
137
<p class="description"><?php _e('This message replaces the post content in RSS feeds.', 'paid-memberships-pro' );?></p>
138
</td>
139
</tr>
140
</tbody>
141
</table>
142
<hr />
143
- <h3><?php _e('Content Settings', 'paid-memberships-pro' );?></h3>
144
<table class="form-table">
145
<tbody>
146
<tr>
@@ -168,7 +171,7 @@
168
</tbody>
169
</table>
170
<hr />
171
- <h3><?php _e('reCAPTCHA Settings', 'paid-memberships-pro' ); ?></h3>
172
<table class="form-table">
173
<tbody>
174
<tr>
@@ -201,19 +204,19 @@
201
<tr>
202
<th scope="row"><label for="recaptcha_publickey"><?php _e('reCAPTCHA Site Key', 'paid-memberships-pro' );?>:</label></th>
203
<td>
204
- <input type="text" id="recaptcha_publickey" name="recaptcha_publickey" size="60" value="<?php echo esc_attr($recaptcha_publickey);?>" />
205
</td>
206
</tr>
207
<tr>
208
<th scope="row"><label for="recaptcha_privatekey"><?php _e('reCAPTCHA Secret Key', 'paid-memberships-pro' );?>:</label></th>
209
<td>
210
- <input type="text" id="recaptcha_privatekey" name="recaptcha_privatekey" size="60" value="<?php echo esc_attr($recaptcha_privatekey);?>" />
211
</td>
212
</tr>
213
</tbody>
214
</table>
215
<hr />
216
- <h3><?php _e('Other Settings', 'paid-memberships-pro' ); ?></h3>
217
<table class="form-table">
218
<tbody>
219
<tr>
@@ -239,6 +242,21 @@ if ( pmpro_displayAds() ) {
239
}</pre>
240
</td>
241
</tr>
242
<tr id="hideadslevels_tr" <?php if($hideads != 2) { ?>style="display: none;"<?php } ?>>
243
<th scope="row" valign="top">
244
<label for="hideadslevels"><?php _e('Choose Levels to Hide Ads From', 'paid-memberships-pro' );?>:</label>
@@ -336,13 +354,15 @@ if ( pmpro_displayAds() ) {
336
<input id="<?php echo esc_attr( $field['field_name'] ); ?>"
337
name="<?php echo esc_attr( $field['field_name'] ); ?>"
338
type="<?php echo esc_attr( $field['field_type'] ); ?>"
339
- value="<?php echo esc_attr(pmpro_getOption($field['field_name'])); ?> ">
340
<?php
341
break;
342
case 'textarea':
343
?>
344
<textarea id="<?php echo esc_attr( $field['field_name'] ); ?>"
345
- name="<?php echo esc_attr( $field['field_name'] ); ?>">
346
<?php echo esc_textarea(pmpro_getOption($field['field_name'])); ?>
347
</textarea>
348
<?php
33
pmpro_setOption("hideads");
34
pmpro_setOption("hideadslevels");
35
pmpro_setOption("redirecttosubscription");
36
+ pmpro_setOption("maxnotificationpriority");
37
38
//captcha
39
pmpro_setOption("recaptcha");
69
$filterqueries = pmpro_getOption('filterqueries');
70
$showexcerpts = pmpro_getOption("showexcerpts");
71
$hideadslevels = pmpro_getOption("hideadslevels");
72
+ $maxnotificationpriority = pmpro_getOption("maxnotificationpriority");
73
74
if(is_multisite())
75
$redirecttosubscription = pmpro_getOption("redirecttosubscription");
108
<form action="" method="post" enctype="multipart/form-data">
109
<?php wp_nonce_field('savesettings', 'pmpro_advancedsettings_nonce');?>
110
111
+ <h1 class="wp-heading-inline"><?php esc_html_e( 'Advanced Settings', 'paid-memberships-pro' ); ?></h1>
112
+ <hr class="wp-header-end">
113
114
<table class="form-table">
115
<tbody>
118
<label for="nonmembertext"><?php _e('Message for Logged-in Non-members', 'paid-memberships-pro' );?>:</label>
119
</th>
120
<td>
121
+ <textarea name="nonmembertext" rows="3" cols="50" class="large-text"><?php echo stripslashes($nonmembertext)?></textarea>
122
<p class="description"><?php _e('This message replaces the post content for non-members. Available variables', 'paid-memberships-pro' );?>: !!levels!!, !!referrer!!</p>
123
</td>
124
</tr>
127
<label for="notloggedintext"><?php _e('Message for Logged-out Users', 'paid-memberships-pro' );?>:</label>
128
</th>
129
<td>
130
+ <textarea name="notloggedintext" rows="3" cols="50" class="large-text"><?php echo stripslashes($notloggedintext)?></textarea>
131
<p class="description"><?php _e('This message replaces the post content for logged-out visitors.', 'paid-memberships-pro' );?></p>
132
</td>
133
</tr>
136
<label for="rsstext"><?php _e('Message for RSS Feed', 'paid-memberships-pro' );?>:</label>
137
</th>
138
<td>
139
+ <textarea name="rsstext" rows="3" cols="50" class="large-text"><?php echo stripslashes($rsstext)?></textarea>
140
<p class="description"><?php _e('This message replaces the post content in RSS feeds.', 'paid-memberships-pro' );?></p>
141
</td>
142
</tr>
143
</tbody>
144
</table>
145
<hr />
146
+ <h2 class="title"><?php esc_html_e( 'Content Settings', 'paid-memberships-pro' ); ?></h2>
147
<table class="form-table">
148
<tbody>
149
<tr>
171
</tbody>
172
</table>
173
<hr />
174
+ <h2 class="title"><?php esc_html_e( 'reCAPTCHA Settings', 'paid-memberships-pro' ); ?></h2>
175
<table class="form-table">
176
<tbody>
177
<tr>
204
<tr>
205
<th scope="row"><label for="recaptcha_publickey"><?php _e('reCAPTCHA Site Key', 'paid-memberships-pro' );?>:</label></th>
206
<td>
207
+ <input type="text" id="recaptcha_publickey" name="recaptcha_publickey" value="<?php echo esc_attr($recaptcha_publickey);?>" class="regular-text code" />
208
</td>
209
</tr>
210
<tr>
211
<th scope="row"><label for="recaptcha_privatekey"><?php _e('reCAPTCHA Secret Key', 'paid-memberships-pro' );?>:</label></th>
212
<td>
213
+ <input type="text" id="recaptcha_privatekey" name="recaptcha_privatekey" value="<?php echo esc_attr($recaptcha_privatekey);?>" class="regular-text code" />
214
</td>
215
</tr>
216
</tbody>
217
</table>
218
<hr />
219
+ <h2 clas="title"><?php esc_html_e( 'Other Settings', 'paid-memberships-pro' ); ?></h2>
220
<table class="form-table">
221
<tbody>
222
<tr>
242
}</pre>
243
</td>
244
</tr>
245
+ <tr>
246
+ <th><?php _e( 'Notifications', 'paid-memberships-pro' ); ?></th>
247
+ <td>
248
+ <select name="maxnotificationpriority">
249
+ <option value="5" <?php selected( $maxnotificationpriority, 5 ); ?>>
250
+ <?php _e( 'Show all notifications.', 'paid-memberships-pro' ); ?>
251
+ </option>
252
+ <option value="1" <?php selected( $maxnotificationpriority, 1 ); ?>>
253
+ <?php _e( 'Show only security notifications.', 'paid-memberships-pro' ); ?>
254
+ </option>
255
+ </select>
256
+ <br />
257
+ <p class="description"><?php _e('Notifications are occasionally shown on the Paid Memberships Pro settings pages.', 'paid-memberships-pro' );?></p>
258
+ </td>
259
+ </tr>
260
<tr id="hideadslevels_tr" <?php if($hideads != 2) { ?>style="display: none;"<?php } ?>>
261
<th scope="row" valign="top">
262
<label for="hideadslevels"><?php _e('Choose Levels to Hide Ads From', 'paid-memberships-pro' );?>:</label>
354
<input id="<?php echo esc_attr( $field['field_name'] ); ?>"
355
name="<?php echo esc_attr( $field['field_name'] ); ?>"
356
type="<?php echo esc_attr( $field['field_type'] ); ?>"
357
+ value="<?php echo esc_attr(pmpro_getOption($field['field_name'])); ?> "
358
+ class="regular-text">
359
<?php
360
break;
361
case 'textarea':
362
?>
363
<textarea id="<?php echo esc_attr( $field['field_name'] ); ?>"
364
+ name="<?php echo esc_attr( $field['field_name'] ); ?>"
365
+ class="large-text">
366
<?php echo esc_textarea(pmpro_getOption($field['field_name'])); ?>
367
</textarea>
368
<?php
adminpages/dashboard.php CHANGED
@@ -213,7 +213,7 @@ function pmpro_dashboard_report_recent_members_callback() {
213
<thead>
214
<tr>
215
<th><?php _e( 'Username', 'paid-memberships-pro' );?></th>
216
- <th><?php _e( 'Membership', 'paid-memberships-pro' );?></th>
217
<th><?php _e( 'Joined', 'paid-memberships-pro' );?></th>
218
<th><?php _e( 'Expires', 'paid-memberships-pro' ); ?></th>
219
</tr>
@@ -317,7 +317,12 @@ function pmpro_dashboard_report_recent_orders_callback() {
317
<br /><?php echo $order->billing->name; ?>
318
<?php } ?>
319
</td>
320
- <td><?php echo $order->membership_id; ?></td>
321
<td><?php echo pmpro_formatPrice( $order->total ); ?></td>
322
<td>
323
<?php echo $order->gateway; ?>
213
<thead>
214
<tr>
215
<th><?php _e( 'Username', 'paid-memberships-pro' );?></th>
216
+ <th><?php _e( 'Level', 'paid-memberships-pro' );?></th>
217
<th><?php _e( 'Joined', 'paid-memberships-pro' );?></th>
218
<th><?php _e( 'Expires', 'paid-memberships-pro' ); ?></th>
219
</tr>
317
<br /><?php echo $order->billing->name; ?>
318
<?php } ?>
319
</td>
320
+ <td>
321
+ <?php
322
+ $level = pmpro_getLevel( $order->membership_id );
323
+ echo $level->name;
324
+ ?>
325
+ </td>
326
<td><?php echo pmpro_formatPrice( $order->total ); ?></td>
327
<td>
328
<?php echo $order->gateway; ?>
adminpages/discountcodes.php CHANGED
@@ -365,14 +365,14 @@
365
366
<?php if($edit) { ?>
367
368
- <h2>
369
<?php
370
if($edit > 0)
371
echo __("Edit Discount Code", 'paid-memberships-pro' );
372
else
373
echo __("Add New Discount Code", 'paid-memberships-pro' );
374
?>
375
- </h2>
376
377
<?php if(!empty($pmpro_msg)) { ?>
378
<div id="message" class="<?php if($pmpro_msgt == "success") echo "updated fade"; else echo "error"; ?>"><p><?php echo $pmpro_msg?></p></div>
@@ -489,7 +489,7 @@
489
for($i = 1; $i < 13; $i++)
490
{
491
?>
492
- <option value="<?php echo $i?>" <?php if($i == $selected_starts_month) { ?>selected="selected"<?php } ?>><?php echo date_i18n("M", strtotime($i . "/1/" . $current_year, current_time("timestamp")))?></option>
493
<?php
494
}
495
?>
@@ -507,7 +507,7 @@
507
for($i = 1; $i < 13; $i++)
508
{
509
?>
510
- <option value="<?php echo $i?>" <?php if($i == $selected_expires_month) { ?>selected="selected"<?php } ?>><?php echo date_i18n("M", strtotime($i . "/1/" . $current_year, current_time("timestamp")))?></option>
511
<?php
512
}
513
?>
@@ -560,7 +560,7 @@
560
else
561
$level_checked = false;
562
?>
563
- <div>
564
<input type="hidden" name="all_levels[]" value="<?php echo $level->id?>" />
565
<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();" />
566
<label for="levels_<?php echo $level->id;?>"><?php echo $level->name?></label>
@@ -686,17 +686,16 @@
686
687
<p class="submit topborder">
688
<input name="save" type="submit" class="button button-primary" value="Save Code" />
689
- <input name="cancel" type="button" class="button button-secondary" value="Cancel" onclick="location.href='<?php echo get_admin_url(NULL, '/admin.php?page=pmpro-discountcodes')?>';" />
690
</p>
691
</form>
692
</div>
693
694
<?php } else { ?>
695
696
- <h2>
697
- <?php _e('Memberships Discount Codes', 'paid-memberships-pro' );?>
698
- <a href="admin.php?page=pmpro-discountcodes&edit=-1" class="add-new-h2"><?php _e('Add New Discount Code', 'paid-memberships-pro' );?></a>
699
- </h2>
700
701
<?php
702
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(starts) as starts, UNIX_TIMESTAMP(expires) as expires FROM $wpdb->pmpro_discount_codes ";
365
366
<?php if($edit) { ?>
367
368
+ <h1>
369
<?php
370
if($edit > 0)
371
echo __("Edit Discount Code", 'paid-memberships-pro' );
372
else
373
echo __("Add New Discount Code", 'paid-memberships-pro' );
374
?>
375
+ </h1>
376
377
<?php if(!empty($pmpro_msg)) { ?>
378
<div id="message" class="<?php if($pmpro_msgt == "success") echo "updated fade"; else echo "error"; ?>"><p><?php echo $pmpro_msg?></p></div>
489
for($i = 1; $i < 13; $i++)
490
{
491
?>
492
+ <option value="<?php echo $i?>" <?php if($i == $selected_starts_month) { ?>selected="selected"<?php } ?>><?php echo date_i18n("M", strtotime($i . "/15/" . $current_year, current_time("timestamp")))?></option>
493
<?php
494
}
495
?>
507
for($i = 1; $i < 13; $i++)
508
{
509
?>
510
+ <option value="<?php echo $i?>" <?php if($i == $selected_expires_month) { ?>selected="selected"<?php } ?>><?php echo date_i18n("M", strtotime($i . "/15/" . $current_year, current_time("timestamp")))?></option>
511
<?php
512
}
513
?>
560
else
561
$level_checked = false;
562
?>
563
+ <div class="pmpro_discount_level">
564
<input type="hidden" name="all_levels[]" value="<?php echo $level->id?>" />
565
<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();" />
566
<label for="levels_<?php echo $level->id;?>"><?php echo $level->name?></label>
686
687
<p class="submit topborder">
688
<input name="save" type="submit" class="button button-primary" value="Save Code" />
689
+ <input name="cancel" type="button" class="button" value="Cancel" onclick="location.href='<?php echo get_admin_url(NULL, '/admin.php?page=pmpro-discountcodes')?>';" />
690
</p>
691
</form>
692
</div>
693
694
<?php } else { ?>
695
696
+ <h1 class="wp-heading-inline"><?php esc_html_e( 'Memberships Discount Codes', 'paid-memberships-pro' ); ?></h1>
697
+ <a href="admin.php?page=pmpro-discountcodes&edit=-1" class="page-title-action"><?php esc_html_e( 'Add New Discount Code', 'paid-memberships-pro' ); ?></a>
698
+ <hr class="wp-header-end">
699
700
<?php
701
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(starts) as starts, UNIX_TIMESTAMP(expires) as expires FROM $wpdb->pmpro_discount_codes ";
adminpages/emailsettings.php CHANGED
@@ -80,7 +80,9 @@
80
<form action="" method="post" enctype="multipart/form-data">
81
<?php wp_nonce_field('savesettings', 'pmpro_emailsettings_nonce');?>
82
83
- <h2><?php _e('Email Settings', 'paid-memberships-pro' );?></h2>
84
<p><?php _e('By default, system generated emails are sent from <em><strong>wordpress@yourdomain.com</strong></em>. You can update this from address using the fields below.', 'paid-memberships-pro' );?></p>
85
86
<p><?php _e('To modify the appearance of system generated emails, add the files <em>email_header.html</em> and <em>email_footer.html</em> to your theme\'s directory. This will modify both the WordPress default messages as well as messages generated by Paid Memberships Pro. <a title="Paid Memberships Pro - Member Communications" target="_blank" href="http://www.paidmembershipspro.com/documentation/member-communications/?utm_source=plugin&utm_medium=pmpro-emailsettings&utm_campaign=documentation&utm_content=member-communications">Click here to learn more about Paid Memberships Pro emails</a>.', 'paid-memberships-pro' );?></p>
@@ -92,7 +94,7 @@
92
<label for="from_email"><?php _e('From Email', 'paid-memberships-pro' );?>:</label>
93
</th>
94
<td>
95
- <input type="text" name="from_email" size="60" value="<?php echo esc_attr($from_email);?>" />
96
</td>
97
</tr>
98
<tr>
@@ -100,7 +102,7 @@
100
<label for="from_name"><?php _e('From Name', 'paid-memberships-pro' );?>:</label>
101
</th>
102
<td>
103
- <input type="text" name="from_name" size="60" value="<?php echo esc_attr($from_name);?>" />
104
</td>
105
</tr>
106
<tr>
@@ -127,8 +129,7 @@
127
*/ ?>
128
129
<hr />
130
- <h3><?php _e('Send the site admin emails', 'paid-memberships-pro' );?>:</h3>
131
-
132
<table class="form-table">
133
<tbody>
134
<tr>
@@ -171,8 +172,7 @@
171
</table>
172
173
<hr />
174
- <h3><?php _e('Send members emails', 'paid-memberships-pro' );?>:</h3>
175
-
176
<table class="form-table">
177
<tbody>
178
<tr>
@@ -189,7 +189,7 @@
189
</table>
190
191
<p class="submit">
192
- <input name="savesettings" type="submit" class="button-primary" value="Save Settings" />
193
</p>
194
</form>
195
80
<form action="" method="post" enctype="multipart/form-data">
81
<?php wp_nonce_field('savesettings', 'pmpro_emailsettings_nonce');?>
82
83
+ <h1 class="wp-heading-inline"><?php esc_html_e( 'Email Settings', 'paid-memberships-pro' ); ?></h1>
84
+ <hr class="wp-header-end">
85
+
86
<p><?php _e('By default, system generated emails are sent from <em><strong>wordpress@yourdomain.com</strong></em>. You can update this from address using the fields below.', 'paid-memberships-pro' );?></p>
87
88
<p><?php _e('To modify the appearance of system generated emails, add the files <em>email_header.html</em> and <em>email_footer.html</em> to your theme\'s directory. This will modify both the WordPress default messages as well as messages generated by Paid Memberships Pro. <a title="Paid Memberships Pro - Member Communications" target="_blank" href="http://www.paidmembershipspro.com/documentation/member-communications/?utm_source=plugin&utm_medium=pmpro-emailsettings&utm_campaign=documentation&utm_content=member-communications">Click here to learn more about Paid Memberships Pro emails</a>.', 'paid-memberships-pro' );?></p>
94
<label for="from_email"><?php _e('From Email', 'paid-memberships-pro' );?>:</label>
95
</th>
96
<td>
97
+ <input type="text" name="from_email" value="<?php echo esc_attr($from_email);?>" class="regular-text" />
98
</td>
99
</tr>
100
<tr>
102
<label for="from_name"><?php _e('From Name', 'paid-memberships-pro' );?>:</label>
103
</th>
104
<td>
105
+ <input type="text" name="from_name" value="<?php echo esc_attr($from_name);?>" class="regular-text" />
106
</td>
107
</tr>
108
<tr>
129
*/ ?>
130
131
<hr />
132
+ <h2 class="title"><?php esc_html_e( 'Send the site admin emails', 'paid-memberships-pro' ); ?>:</h2>
133
<table class="form-table">
134
<tbody>
135
<tr>
172
</table>
173
174
<hr />
175
+ <h2 class="title"><?php esc_html_e( 'Send members emails', 'paid-memberships-pro' ); ?>:</h2>
176
<table class="form-table">
177
<tbody>
178
<tr>
189
</table>
190
191
<p class="submit">
192
+ <input name="savesettings" type="submit" class="button-primary" value="Save Settings" />
193
</p>
194
</form>
195
adminpages/membershiplevels.php CHANGED
@@ -260,15 +260,16 @@
260
if($edit) {
261
?>
262
263
- <h2>
264
<?php
265
if($edit > 0)
266
echo __("Edit Membership Level", 'paid-memberships-pro' );
267
else
268
echo __("Add New Membership Level", 'paid-memberships-pro' );
269
?>
270
- </h2>
271
-
272
<div>
273
<?php
274
// get the level...
@@ -351,7 +352,7 @@
351
352
<tr>
353
<th scope="row" valign="top"><label for="name"><?php _e('Name', 'paid-memberships-pro' );?>:</label></th>
354
- <td><input name="name" type="text" size="50" value="<?php echo esc_attr($level->name);?>" /></td>
355
</tr>
356
357
<tr>
@@ -364,7 +365,7 @@
364
else
365
{
366
?>
367
- <textarea rows="10" cols="80" name="description" id="description"><?php echo esc_textarea($level->description);?></textarea>
368
<?php
369
}
370
?>
@@ -382,7 +383,7 @@
382
else
383
{
384
?>
385
- <textarea rows="10" cols="80" name="confirmation" id="confirmation"><?php echo esc_textarea($level->confirmation);?></textarea>
386
<?php
387
}
388
?>
@@ -392,8 +393,8 @@
392
</tr>
393
</tbody>
394
</table>
395
-
396
- <h3 class="topborder"><?php _e('Billing Details', 'paid-memberships-pro' );?></h3>
397
<table class="form-table">
398
<tbody>
399
<tr>
@@ -403,7 +404,7 @@
403
if(pmpro_getCurrencyPosition() == "left")
404
echo $pmpro_currency_symbol;
405
?>
406
- <input name="initial_payment" type="text" size="20" value="<?php echo esc_attr( pmpro_filter_price_for_text_field( $level->initial_payment ) );?>" />
407
<?php
408
if(pmpro_getCurrencyPosition() == "right")
409
echo $pmpro_currency_symbol;
@@ -424,13 +425,13 @@
424
if(pmpro_getCurrencyPosition() == "left")
425
echo $pmpro_currency_symbol;
426
?>
427
- <input name="billing_amount" type="text" size="20" value="<?php echo esc_attr( pmpro_filter_price_for_text_field( $level->billing_amount ) );?>" />
428
<?php
429
if(pmpro_getCurrencyPosition() == "right")
430
echo $pmpro_currency_symbol;
431
?>
432
<?php _e('per', 'paid-memberships-pro' );?>
433
- <input id="cycle_number" name="cycle_number" type="text" size="10" value="<?php echo esc_attr($level->cycle_number);?>" />
434
<select id="cycle_period" name="cycle_period">
435
<?php
436
$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' );
@@ -461,7 +462,7 @@
461
<tr class="recurring_info" <?php if(!pmpro_isLevelRecurring($level)) {?>style="display: none;"<?php } ?>>
462
<th scope="row" valign="top"><label for="billing_limit"><?php _e('Billing Cycle Limit', 'paid-memberships-pro' );?>:</label></th>
463
<td>
464
- <input name="billing_limit" type="text" size="20" value="<?php echo $level->billing_limit?>" />
465
<p class="description">
466
<?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' );?>
467
<?php if ( ( $gateway == "stripe" ) && ! function_exists( 'pmprosbl_plugin_row_meta' ) ) { ?>
@@ -510,13 +511,13 @@
510
if(pmpro_getCurrencyPosition() == "left")
511
echo $pmpro_currency_symbol;
512
?>
513
- <input name="trial_amount" type="text" size="20" value="<?php echo esc_attr( pmpro_filter_price_for_text_field( $level->trial_amount ) );?>" />
514
<?php
515
if(pmpro_getCurrencyPosition() == "right")
516
echo $pmpro_currency_symbol;
517
?>
518
<?php _e('for the first', 'paid-memberships-pro' );?>
519
- <input name="trial_limit" type="text" size="10" value="<?php echo esc_attr($level->trial_limit);?>" />
520
<?php _e('subscription payments', 'paid-memberships-pro' );?>.
521
<?php if($gateway == "stripe") { ?>
522
<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>
@@ -530,8 +531,8 @@
530
531
</tbody>
532
</table>
533
-
534
- <h3 class="topborder"><?php _e('Other Settings', 'paid-memberships-pro' );?></h3>
535
<table class="form-table">
536
<tbody>
537
<tr>
@@ -558,7 +559,7 @@
558
<tr class="expiration_info" <?php if(!pmpro_isLevelExpiring($level)) {?>style="display: none;"<?php } ?>>
559
<th scope="row" valign="top"><label for="billing_amount"><?php _e('Expires In', 'paid-memberships-pro' );?>:</label></th>
560
<td>
561
- <input id="expiration_number" name="expiration_number" type="text" size="10" value="<?php echo esc_attr($level->expiration_number);?>" />
562
<select id="expiration_period" name="expiration_period">
563
<?php
564
$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' );
@@ -596,7 +597,9 @@
596
597
<?php do_action("pmpro_membership_level_after_other_settings"); ?>
598
599
- <h3 class="topborder"><?php _e('Content Settings', 'paid-memberships-pro' );?></h3>
600
<?php
601
// Get the Advanced Settings for filtering queries and showing excerpts.
602
$filterqueries = pmpro_getOption('filterqueries');
@@ -634,8 +637,8 @@
634
</tbody>
635
</table>
636
<p class="submit topborder">
637
- <input name="save" type="submit" class="button-primary" value="<?php _e('Save Level', 'paid-memberships-pro' ); ?>" />
638
- <input name="cancel" type="button" value="<?php _e('Cancel', 'paid-memberships-pro' ); ?>" onclick="location.href='<?php echo add_query_arg( 'page', 'pmpro-membershiplevels' , get_admin_url(NULL, '/admin.php') ); ?>';" />
639
</p>
640
</form>
641
</div>
@@ -752,7 +755,9 @@
752
<input class="button" type="submit" value="<?php _e('Search Levels', 'paid-memberships-pro' );?>" id="search-submit" />
753
</p>
754
</form>
755
- <h2><?php _e('Membership Levels', 'paid-memberships-pro' );?> <a href="<?php echo add_query_arg( array( 'page' => 'pmpro-membershiplevels', 'edit' => -1 ), get_admin_url(null, 'admin.php' ) ); ?>" class="add-new-h2"><?php _e('Add New Level', 'paid-memberships-pro' );?></a></h2>
756
757
<?php if(empty($_REQUEST['s']) && count($reordered_levels) > 1) { ?>
758
<p><?php _e('Drag and drop membership levels to reorder them on the Levels page.', 'paid-memberships-pro' ); ?></p>
260
if($edit) {
261
?>
262
263
+ <h1 class="wp-heading-inline">
264
<?php
265
if($edit > 0)
266
echo __("Edit Membership Level", 'paid-memberships-pro' );
267
else
268
echo __("Add New Membership Level", 'paid-memberships-pro' );
269
?>
270
+ </h1>
271
+ <hr class="wp-header-end">
272
+
273
<div>
274
<?php
275
// get the level...
352
353
<tr>
354
<th scope="row" valign="top"><label for="name"><?php _e('Name', 'paid-memberships-pro' );?>:</label></th>
355
+ <td><input name="name" type="text" value="<?php echo esc_attr($level->name);?>" class="regular-text" /></td>
356
</tr>
357
358
<tr>
365
else
366
{
367
?>
368
+ <textarea rows="10" name="description" id="description" class="large-text"><?php echo esc_textarea($level->description);?></textarea>
369
<?php
370
}
371
?>
383
else
384
{
385
?>
386
+ <textarea rows="10" name="confirmation" id="confirmation" class="large-text"><?php echo esc_textarea($level->confirmation);?></textarea>
387
<?php
388
}
389
?>
393
</tr>
394
</tbody>
395
</table>
396
+ <hr />
397
+ <h2 class="title"><?php _e('Billing Details', 'paid-memberships-pro' );?></h2>
398
<table class="form-table">
399
<tbody>
400
<tr>
404
if(pmpro_getCurrencyPosition() == "left")
405
echo $pmpro_currency_symbol;
406
?>
407
+ <input name="initial_payment" type="text" value="<?php echo esc_attr( pmpro_filter_price_for_text_field( $level->initial_payment ) );?>" class="regular-text" />
408
<?php
409
if(pmpro_getCurrencyPosition() == "right")
410
echo $pmpro_currency_symbol;
425
if(pmpro_getCurrencyPosition() == "left")
426
echo $pmpro_currency_symbol;
427
?>
428
+ <input name="billing_amount" type="text" value="<?php echo esc_attr( pmpro_filter_price_for_text_field( $level->billing_amount ) );?>" class="regular-text" />
429
<?php
430
if(pmpro_getCurrencyPosition() == "right")
431
echo $pmpro_currency_symbol;
432
?>
433
<?php _e('per', 'paid-memberships-pro' );?>
434
+ <input id="cycle_number" name="cycle_number" type="text" value="<?php echo esc_attr($level->cycle_number);?>" class="small-text" />
435
<select id="cycle_period" name="cycle_period">
436
<?php
437
$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' );
462
<tr class="recurring_info" <?php if(!pmpro_isLevelRecurring($level)) {?>style="display: none;"<?php } ?>>
463
<th scope="row" valign="top"><label for="billing_limit"><?php _e('Billing Cycle Limit', 'paid-memberships-pro' );?>:</label></th>
464
<td>
465
+ <input name="billing_limit" type="text" value="<?php echo $level->billing_limit?>" class="small-text" />
466
<p class="description">
467
<?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' );?>
468
<?php if ( ( $gateway == "stripe" ) && ! function_exists( 'pmprosbl_plugin_row_meta' ) ) { ?>
511
if(pmpro_getCurrencyPosition() == "left")
512
echo $pmpro_currency_symbol;
513
?>
514
+ <input name="trial_amount" type="text" value="<?php echo esc_attr( pmpro_filter_price_for_text_field( $level->trial_amount ) );?>" class="regular-text" />
515
<?php
516
if(pmpro_getCurrencyPosition() == "right")
517
echo $pmpro_currency_symbol;
518
?>
519
<?php _e('for the first', 'paid-memberships-pro' );?>
520
+ <input name="trial_limit" type="text" value="<?php echo esc_attr($level->trial_limit);?>" class="small-text" />
521
<?php _e('subscription payments', 'paid-memberships-pro' );?>.
522
<?php if($gateway == "stripe") { ?>
523
<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>
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>
538
<tr>
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' );
597
598
<?php do_action("pmpro_membership_level_after_other_settings"); ?>
599
600
+ <hr />
601
+
602
+ <h2 class="title"><?php esc_html_e( 'Content Settings', 'paid-memberships-pro' ); ?></h2>
603
<?php
604
// Get the Advanced Settings for filtering queries and showing excerpts.
605
$filterqueries = pmpro_getOption('filterqueries');
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' , get_admin_url(NULL, '/admin.php') ); ?>';" />
642
</p>
643
</form>
644
</div>
755
<input class="button" type="submit" value="<?php _e('Search Levels', 'paid-memberships-pro' );?>" id="search-submit" />
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 ), get_admin_url(null, 'admin.php' ) ); ?>" class="page-title-action"><?php esc_html_e( 'Add New Level', 'paid-memberships-pro' ); ?></a>
760
+ <hr class="wp-header-end">
761
762
<?php if(empty($_REQUEST['s']) && count($reordered_levels) > 1) { ?>
763
<p><?php _e('Drag and drop membership levels to reorder them on the Levels page.', 'paid-memberships-pro' ); ?></p>
adminpages/memberslist.php CHANGED
@@ -1,300 +1,35 @@
1
<?php
2
- //only admins can get this
3
- if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_memberslist")))
4
- {
5
- die(__("You do not have permissions to perform this action.", 'paid-memberships-pro' ));
6
- }
7
8
- //vars
9
- global $wpdb;
10
- if(isset($_REQUEST['s']))
11
- $s = sanitize_text_field(trim($_REQUEST['s']));
12
- else
13
- $s = "";
14
-
15
- if(isset($_REQUEST['l']))
16
- $l = sanitize_text_field($_REQUEST['l']);
17
- else
18
- $l = false;
19
-
20
- require_once(dirname(__FILE__) . "/admin_header.php");
21
?>
22
-
23
- <form id="posts-filter" method="get" action="">
24
- <h2>
25
- <?php _e('Members List', 'paid-memberships-pro' );?>
26
- <a target="_blank" href="<?php echo admin_url('admin-ajax.php');?>?action=memberslist_csv&s=<?php echo esc_attr($s);?>&l=<?php echo $l?>" class="add-new-h2"><?php _e('Export to CSV', 'paid-memberships-pro' );?></a>
27
- </h2>
28
- <ul class="subsubsub">
29
- <li>
30
- <?php _e('Show', 'paid-memberships-pro' );?>
31
- <select name="l" onchange="jQuery('#posts-filter').submit();">
32
- <option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'paid-memberships-pro' );?></option>
33
- <?php
34
- $levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
35
- foreach($levels as $level)
36
- {
37
- ?>
38
- <option value="<?php echo $level->id?>" <?php if($l == $level->id) { ?>selected="selected"<?php } ?>><?php echo $level->name?></option>
39
- <?php
40
- }
41
- ?>
42
- <option value="cancelled" <?php if($l == "cancelled") { ?>selected="selected"<?php } ?>><?php _e('Cancelled Members', 'paid-memberships-pro' );?></option>
43
- <option value="expired" <?php if($l == "expired") { ?>selected="selected"<?php } ?>><?php _e('Expired Members', 'paid-memberships-pro' );?></option>
44
- <option value="oldmembers" <?php if($l == "oldmembers") { ?>selected="selected"<?php } ?>><?php _e('Old Members', 'paid-memberships-pro' );?></option>
45
- </select>
46
- </li>
47
- </ul>
48
- <p class="search-box">
49
- <label class="hidden" for="post-search-input"><?php _e('Search Members', 'paid-memberships-pro' );?>:</label>
50
- <input type="hidden" name="page" value="pmpro-memberslist" />
51
- <input id="post-search-input" type="text" value="<?php echo esc_attr($s);?>" name="s"/>
52
- <input class="button" type="submit" value="<?php _e('Search Members', 'paid-memberships-pro' );?>"/>
53
- </p>
54
- <?php
55
- //some vars for the search
56
- if(isset($_REQUEST['pn']))
57
- $pn = intval($_REQUEST['pn']);
58
- else
59
- $pn = 1;
60
-
61
- if(isset($_REQUEST['limit']))
62
- $limit = intval($_REQUEST['limit']);
63
- else
64
- {
65
- /**
66
- * Filter to set the default number of items to show per page
67
- * on the Members List page in the admin.
68
- *
69
- * @since 1.8.4.5
70
- *
71
- * @param int $limit The number of items to show per page.
72
- */
73
- $limit = apply_filters('pmpro_memberslist_per_page', 15);
74
- }
75
-
76
- $end = $pn * $limit;
77
- $start = $end - $limit;
78
-
79
- if($s)
80
- {
81
- $sqlQuery = "SELECT SQL_CALC_FOUND_ROWS u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, mu.cycle_number, mu.billing_limit, mu.trial_amount, mu.trial_limit, UNIX_TIMESTAMP(mu.startdate) as startdate, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->usermeta um ON u.ID = um.user_id LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id ";
82
-
83
- if($l == "oldmembers" || $l == "expired" || $l == "cancelled")
84
- $sqlQuery .= " LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON u.ID = mu2.user_id AND mu2.status = 'active' ";
85
-
86
- $sqlQuery .= " WHERE mu.membership_id > 0 AND (u.user_login LIKE '%" . esc_sql($s) . "%' OR u.user_email LIKE '%" . esc_sql($s) . "%' OR um.meta_value LIKE '%" . esc_sql($s) . "%' OR u.display_name LIKE '%" . esc_sql($s) . "%') ";
87
-
88
- if($l == "oldmembers")
89
- $sqlQuery .= " AND mu.status <> 'active' AND mu2.status IS NULL ";
90
- elseif($l == "expired")
91
- $sqlQuery .= " AND mu.status = 'expired' AND mu2.status IS NULL ";
92
- elseif($l == "cancelled")
93
- $sqlQuery .= " AND mu.status IN('cancelled', 'admin_cancelled') AND mu2.status IS NULL ";
94
- elseif($l)
95
- $sqlQuery .= " AND mu.status = 'active' AND mu.membership_id = '" . esc_sql($l) . "' ";
96
- else
97
- $sqlQuery .= " AND mu.status = 'active' ";
98
-
99
- $sqlQuery .= "GROUP BY u.ID ";
100
-
101
- if($l == "oldmembers" || $l == "expired" || $l == "cancelled")
102
- $sqlQuery .= "ORDER BY enddate DESC ";
103
- else
104
- $sqlQuery .= "ORDER BY u.user_registered DESC ";
105
-
106
- $sqlQuery .= "LIMIT $start, $limit";
107
- }
108
- else
109
- {
110
- $sqlQuery = "SELECT SQL_CALC_FOUND_ROWS u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, mu.cycle_number, mu.billing_limit, mu.trial_amount, mu.trial_limit, UNIX_TIMESTAMP(mu.startdate) as startdate, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id";
111
-
112
- if($l == "oldmembers" || $l == "expired" || $l == "cancelled")
113
- $sqlQuery .= " LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON u.ID = mu2.user_id AND mu2.status = 'active' ";
114
-
115
- $sqlQuery .= " WHERE mu.membership_id > 0 ";
116
-
117
- if($l == "oldmembers")
118
- $sqlQuery .= " AND mu.status <> 'active' AND mu2.status IS NULL ";
119
- elseif($l == "expired")
120
- $sqlQuery .= " AND mu.status = 'expired' AND mu2.status IS NULL ";
121
- elseif($l == "cancelled")
122
- $sqlQuery .= " AND mu.status IN('cancelled', 'admin_cancelled') AND mu2.status IS NULL ";
123
- elseif($l)
124
- $sqlQuery .= " AND mu.status = 'active' AND mu.membership_id = '" . esc_sql($l) . "' ";
125
- else
126
- $sqlQuery .= " AND mu.status = 'active' ";
127
- $sqlQuery .= "GROUP BY u.ID ";
128
-
129
- if($l == "oldmembers" || $l == "expired" || $l == "cancelled")
130
- $sqlQuery .= "ORDER BY enddate DESC ";
131
- else
132
- $sqlQuery .= "ORDER BY u.user_registered DESC ";
133
-
134
- $sqlQuery .= "LIMIT $start, $limit";
135
- }
136
-
137
- $sqlQuery = apply_filters("pmpro_members_list_sql", $sqlQuery);
138
-
139
- $theusers = $wpdb->get_results($sqlQuery);
140
- $totalrows = $wpdb->get_var("SELECT FOUND_ROWS() as found_rows");
141
-
142
- if($theusers)
143
- {
144
- $calculate_revenue = apply_filters("pmpro_memberslist_calculate_revenue", false);
145
- if($calculate_revenue)
146
- {
147
- $initial_payments = pmpro_calculateInitialPaymentRevenue($s, $l);
148
- $recurring_payments = pmpro_calculateRecurringRevenue($s, $l);
149
- ?>
150
- <br class="clear" />
151
- <hr />
152
- <p><?php echo strval($totalrows)?> members found. These members have paid <strong>lt;?php echo number_format($initial_payments)?> in initial payments</strong> and will generate an estimated <strong>lt;?php echo number_format($recurring_payments)?> in revenue over the next year</strong>, or <strong>lt;?php echo number_format($recurring_payments/12)?>/month</strong>. <span class="description">(This estimate does not take into account trial periods or billing limits.)</span></p>
153
- <?php
154
- }
155
- else
156
- {
157
- ?>
158
- <br class="clear" />
159
- <hr />
160
- <p class="description"><?php printf(__("%d members found.", 'paid-memberships-pro' ), $totalrows);?></p>
161
- <?php
162
- }
163
- }
164
- ?>
165
- <table class="widefat">
166
- <thead>
167
- <tr class="thead">
168
- <th><?php _e('ID', 'paid-memberships-pro' );?></th>
169
- <th><?php _e('Username', 'paid-memberships-pro' );?></th>
170
- <th><?php _e('First&nbsp;Name', 'paid-memberships-pro' );?></th>
171
- <th><?php _e('Last&nbsp;Name', 'paid-memberships-pro' );?></th>
172
- <th><?php _e('Email', 'paid-memberships-pro' );?></th>
173
- <?php do_action("pmpro_memberslist_extra_cols_header", $theusers);?>
174
- <th><?php _e('Billing Address', 'paid-memberships-pro' );?></th>
175
- <th><?php _e('Level', 'paid-memberships-pro' );?></th>
176
- <th><?php _e('Fee', 'paid-memberships-pro' );?></th>
177
- <th><?php _e('Joined', 'paid-memberships-pro' );?></th>
178
- <th>
179
- <?php
180
- if($l == "oldmembers")
181
- _e('Ended', 'paid-memberships-pro' );
182
- elseif($l == "cancelled")
183
- _e('Cancelled', 'paid-memberships-pro' );
184
- elseif($l == "expired")
185
- _e('Expired', 'paid-memberships-pro' );
186
- else
187
- _e('Expires', 'paid-memberships-pro' );
188
- ?>
189
- </th>
190
- </tr>
191
- </thead>
192
- <tbody id="users" class="list:user user-list">
193
- <?php
194
- $count = 0;
195
- foreach($theusers as $auser)
196
- {
197
- $auser = apply_filters("pmpro_members_list_user", $auser);
198
- //get meta
199
- $theuser = get_userdata($auser->ID);
200
- ?>
201
- <tr <?php if($count++ % 2 == 0) { ?>class="alternate"<?php } ?>>
202
- <td><?php echo $theuser->ID?></td>
203
- <td class="username column-username">
204
- <?php echo get_avatar($theuser->ID, 32)?>
205
- <strong>
206
- <?php
207
- $userlink = '<a href="user-edit.php?user_id=' . $theuser->ID . '">' . $theuser->user_login . '</a>';
208
- $userlink = apply_filters("pmpro_members_list_user_link", $userlink, $theuser);
209
- echo $userlink;
210
- ?>
211
- </strong>
212
- <br />
213
- <?php
214
- // Set up the hover actions for this user
215
- $actions = apply_filters( 'pmpro_memberslist_user_row_actions', array(), $theuser );
216
- $action_count = count( $actions );
217
- $i = 0;
218
- if($action_count)
219
- {
220
- $out = '<div class="row-actions">';
221
- foreach ( $actions as $action => $link ) {
222
- ++$i;
223
- ( $i == $action_count ) ? $sep = '' : $sep = ' | ';
224
- $out .= "<span class='$action'>$link$sep</span>";
225
- }
226
- $out .= '</div>';
227
- echo $out;
228
- }
229
- ?>
230
- </td>
231
- <td><?php echo $theuser->first_name?></td>
232
- <td><?php echo $theuser->last_name?></td>
233
- <td><a href="mailto:<?php echo esc_attr($theuser->user_email)?>"><?php echo $theuser->user_email?></a></td>
234
- <?php do_action("pmpro_memberslist_extra_cols_body", $theuser);?>
235
- <td>
236
- <?php
237
- echo pmpro_formatAddress(trim($theuser->pmpro_bfirstname . " " . $theuser->pmpro_blastname), $theuser->pmpro_baddress1, $theuser->pmpro_baddress2, $theuser->pmpro_bcity, $theuser->pmpro_bstate, $theuser->pmpro_bzipcode, $theuser->pmpro_bcountry, $theuser->pmpro_bphone);
238
- ?>
239
- </td>
240
- <td><?php echo $auser->membership?></td>
241
- <td>
242
- <?php if((float)$auser->initial_payment > 0) { ?>
243
- <?php echo pmpro_formatPrice($auser->initial_payment);?>
244
- <?php } ?>
245
- <?php if((float)$auser->initial_payment > 0 && (float)$auser->billing_amount > 0) { ?>+<br /><?php } ?>
246
- <?php if((float)$auser->billing_amount > 0) { ?>
247
- <?php echo pmpro_formatPrice($auser->billing_amount);?>/<?php if($auser->cycle_number > 1) { echo $auser->cycle_number . " " . $auser->cycle_period . "s"; } else { echo $auser->cycle_period; } ?>
248
- <?php } ?>
249
- <?php if((float)$auser->initial_payment <= 0 && (float)$auser->billing_amount <= 0) { ?>
250
- -
251
- <?php } ?>
252
- </td>
253
- <td><?php echo date_i18n(get_option("date_format"), strtotime($theuser->user_registered, current_time("timestamp")))?></td>
254
- <td>
255
- <?php
256
- if($auser->enddate)
257
- echo apply_filters("pmpro_memberslist_expires_column", date_i18n(get_option('date_format'), $auser->enddate), $auser);
258
- else
259
- echo __(apply_filters("pmpro_memberslist_expires_column", "Never", $auser), "pmpro");
260
- ?>
261
- </td>
262
- </tr>
263
- <?php
264
- }
265
-
266
- if(!$theusers)
267
- {
268
- ?>
269
- <tr>
270
- <td colspan="9">
271
- <p>
272
- <?php _e( 'No members found.', 'paid-memberships-pro' ); ?>
273
- <?php if ( $l ) { ?>
274
- <a href="<?php echo esc_url( add_query_arg( array( 'page' => 'pmpro-memberslist', 's' => $s ) ) ); ?>"><?php _e( 'Search all levels', 'paid-memberships-pro' );?></a>
275
- <?php } ?>
276
- </p>
277
- <hr />
278
- <p><?php _e( 'You can also try searching:', 'paid-memberships-pro' ); ?>
279
- <ul class="ul-disc">
280
- <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'pmpro-memberslist', 'l' => 'cancelled', 's' => $s ) ) ); ?>"><?php _e( 'Cancelled Members', 'paid-memberships-pro' ); ?></a></li>
281
- <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'pmpro-memberslist', 'l' => 'expired', 's' => $s ) ) ); ?>"><?php _e( 'Expired Members', 'paid-memberships-pro' ); ?></a></li>
282
- <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'pmpro-memberslist', 'l' => 'oldmembers', 's' => $s ) ) ); ?>"><?php _e( 'Old Members', 'paid-memberships-pro' ); ?></a></li>
283
- <li><a href="<?php echo esc_url( add_query_arg( array( 's' => $s ), admin_url( 'users.php' ) ) ); ?>"><?php _e( 'All Users', 'paid-memberships-pro' ); ?></a></li>
284
- </ul>
285
- </td>
286
- </tr>
287
- <?php
288
- }
289
- ?>
290
- </tbody>
291
- </table>
292
</form>
293
294
- <?php
295
- echo pmpro_getPaginationString($pn, $totalrows, $limit, 1, add_query_arg(array("s" => urlencode($s), "l" => $l, "limit" => $limit)));
296
- ?>
297
-
298
<?php if ( ! function_exists( 'pmprorh_add_registration_field' ) ) {
299
$allowed_pmprorh_html = array (
300
'a' => array (
@@ -303,9 +38,9 @@
303
'title' => array(),
304
),
305
);
306
- echo '<br /><p class="description">' . sprintf( wp_kses( __( 'Optional: Capture additional member profile fields using the <a href="%s" title="Paid Memberships Pro - Register Helper Add On" target="_blank">Register Helper Add On</a>.', 'paid-memberships-pro' ), $allowed_pmprorh_html ), 'https://www.paidmembershipspro.com/add-ons/pmpro-register-helper-add-checkout-and-profile-fields/?utm_source=plugin&utm_medium=pmpro-memberslist&utm_campaign=add-ons&utm_content=pmpro-register-helper-add-checkout-and-profile-fields' ) . '</p>';
307
} ?>
308
-
309
<?php
310
- require_once(dirname(__FILE__) . "/admin_footer.php");
311
?>
1
<?php
2
3
+ global $user_list_table;
4
+ // Query, filter, and sort the data.
5
+ $user_list_table = new PMPro_Members_List_Table();
6
+ $user_list_table->prepare_items();
7
+ require_once dirname( __DIR__ ) . '/adminpages/admin_header.php';
8
+
9
+ // Build CSV export link.
10
+ $csv_export_link = admin_url( 'admin-ajax.php' ) . '?action=memberslist_csv';
11
+ if ( isset( $_REQUEST['s'] ) ) {
12
+ $csv_export_link .= '&s=' . esc_attr( sanitize_text_field( trim( $_REQUEST['s'] ) ) );
13
+ }
14
+ if ( isset( $_REQUEST['l'] ) ) {
15
+ $csv_export_link .= '&l=' . sanitize_text_field( trim( $_REQUEST['l'] ) );
16
+ }
17
+
18
+ // Render the List Table.
19
?>
20
+ <h1 class="wp-heading-inline"><?php esc_html_e( 'Members List', 'paid-memberships-pro' ); ?></h1>
21
+ <a target="_blank" href="<?php echo esc_url( $csv_export_link ); ?>" class="page-title-action"><?php esc_html_e( 'Export to CSV', 'paid-memberships-pro' ); ?></a>
22
+ <hr class="wp-header-end">
23
+
24
+ <?php do_action( 'pmpro_memberslist_before_table' ); ?>
25
+ <form id="member-list-form" method="get">
26
+ <input type="hidden" name="page" value="<?php echo $_REQUEST['page']; ?>" />
27
+ <?php
28
+ $user_list_table->search_box( __( 'Search Members', 'paid-memberships-pro' ), 'paid-memberships-pro' );
29
+ $user_list_table->display();
30
+ ?>
31
</form>
32
33
<?php if ( ! function_exists( 'pmprorh_add_registration_field' ) ) {
34
$allowed_pmprorh_html = array (
35
'a' => array (
38
'title' => array(),
39
),
40
);
41
+ echo '<p class="description">' . sprintf( wp_kses( __( 'Optional: Capture additional member profile fields using the <a href="%s" title="Paid Memberships Pro - Register Helper Add On" target="_blank">Register Helper Add On</a>.', 'paid-memberships-pro' ), $allowed_pmprorh_html ), 'https://www.paidmembershipspro.com/add-ons/pmpro-register-helper-add-checkout-and-profile-fields/?utm_source=plugin&utm_medium=pmpro-memberslist&utm_campaign=add-ons&utm_content=pmpro-register-helper-add-checkout-and-profile-fields' ) . '</p>';
42
} ?>
43
+
44
<?php
45
+ require_once dirname( __DIR__ ) . '/adminpages/admin_footer.php';
46
?>
adminpages/orders.php CHANGED
@@ -365,15 +365,14 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
365
366
<?php if ( ! empty( $order ) ) { ?>
367
368
- <h2>
369
- <?php if ( ! empty( $order->id ) ) { ?>
370
- <?php _e( 'Order', 'paid-memberships-pro' ); ?> #<?php echo $order->id; ?>: <?php echo $order->code; ?>
371
- <a title="<?php _e( 'Print', 'paid-memberships-pro' ); ?>" href="<?php echo add_query_arg( array( 'action' => 'pmpro_orders_print_view', 'order' => $order->id ), admin_url('admin-ajax.php' ) ); ?>" class="add-new-h2" target="_blank" ><?php _e( 'Print', 'paid-memberships-pro' ); ?></a>
372
- <a title="<?php _e( 'Email', 'paid-memberships-pro' ); ?>" href="#TB_inline?width=600&height=200&inlineId=email_invoice" class="thickbox email_link add-new-h2" data-order="<?php echo $order->id; ?>"><?php _e( 'Email', 'paid-memberships-pro' ); ?></a>
373
- <?php } else { ?>
374
- <?php _e( 'New Order', 'paid-memberships-pro' ); ?>
375
- <?php } ?>
376
- </h2>
377
378
<?php if ( ! empty( $pmpro_msg ) ) { ?>
379
<div id="message" class="
@@ -409,47 +408,44 @@ if ( function_exists( 'pmpro_add_email_order_modal' ) ) {
409
<th scope="row" valign="top"><label for="code"><?php _e( 'Code', 'paid-memberships-pro' ); ?>:</label></th>
410
<td>
411
<?php
412
- if ( in_array( 'code', $read_only_fields ) ) {
413
- echo $order->code;
414
- } else {
415
- ?>
416
- <input id="code" name="code" type="text" size="50"
417
- value="<?php echo esc_attr( $order->code ); ?>"/>
418
- <?php } ?>
419
<?php if ( $order_id < 0 ) { ?>
420
- <p class="description"><?php _e( 'Randomly generated for you.', 'paid-memberships-pro' ); ?></p><?php } ?>
421
</td>
422
</tr>
423
-
424
<tr>
425
<th scope="row" valign="top"><label for="user_id"><?php _e( 'User ID', 'paid-memberships-pro' ); ?>:</label></th>
426
<td>
427
<?php
428
- if ( in_array( 'user_id', $read_only_fields ) && $order_id > 0 ) {
429
- echo $order->user_id;
430
- } else {
431
- ?>
432
- <input id="user_id" name="user_id" type="text" size="50"
433
- value="<?php echo esc_attr( $order->user_id ); ?>"/>
434
- <?php } ?>
435
</td>
436
</tr>
437
-
438
<tr>
439
- <th scope="row" valign="top"><label for="membership_id"><?php _e( 'Membership Level ID', 'paid-memberships-pro' ); ?>
440
- :</label></th>
441
<td>
442
<?php
443
- if ( in_array( 'membership_id', $read_only_fields ) && $order_id > 0 ) {
444
echo $order->membership_id;
445
- } else {
446
- ?>
447
- <input id="membership_id" name="membership_id" type="text" size="50"
448
- value="<?php echo esc_attr( $order->membership_id ); ?>"/>
449
- <?php } ?>
450
</td>
451
</tr>
452
-
453
<tr>
454
<th scope="row" valign="top"><label for="billing_name"><?php _e( 'Billing Name', 'paid-memberships-pro' ); ?>:</label>
455
</th>
@@ -833,7 +829,7 @@ selected="selected"<?php } ?>><?php _e( 'Live/Production', 'paid-memberships-pro
833
<?php
834
if ( $i == $month ) {
835
?>
836
- selected="selected"<?php } ?>><?php echo date_i18n( 'M', strtotime( $i . '/1/' . $year, current_time( 'timestamp' ) ) ); ?></option>
837
<?php
838
}
839
?>
@@ -940,33 +936,32 @@ selected="selected"<?php } ?>><?php echo date_i18n( 'M', strtotime( $i . '/1/' .
940
<?php } else { ?>
941
942
<form id="posts-filter" method="get" action="">
943
- <h2>
944
- <?php _e( 'Orders', 'paid-memberships-pro' ); ?>
945
- <a href="admin.php?page=pmpro-orders&order=-1"
946
- class="add-new-h2">+ <?php _e( 'Add New Order', 'paid-memberships-pro' ); ?></a>
947
948
- <?php
949
- // build the export URL
950
- $export_url = admin_url( 'admin-ajax.php?action=orders_csv' );
951
- $url_params = array(
952
- 'filter' => $filter,
953
- 's' => $s,
954
- 'l' => $l,
955
- 'start-month' => $start_month,
956
- 'start-day' => $start_day,
957
- 'start-year' => $start_year,
958
- 'end-month' => $end_month,
959
- 'end-day' => $end_day,
960
- 'end-year' => $end_year,
961
- 'predefined-date' => $predefined_date,
962
- 'discount-code' => $discount_code,
963
- 'status' => $status,
964
- );
965
- $export_url = add_query_arg( $url_params, $export_url );
966
- ?>
967
- <a target="_blank" href="<?php echo $export_url; ?>"
968
- class="add-new-h2"><?php _e( 'Export to CSV', 'paid-memberships-pro' ); ?></a>
969
- </h2>
970
971
972
<?php if ( ! empty( $pmpro_msg ) ) { ?>
@@ -1081,8 +1076,7 @@ selected="selected"<?php } ?>><?php echo date_i18n( 'M', strtotime( $i . '/1/' .
1081
<?php } ?>
1082
</select>
1083
1084
-
1085
- <input id="submit" type="submit" value="<?php _e( 'Filter', 'paid-memberships-pro' ); ?>"/>
1086
</li>
1087
</ul>
1088
365
366
<?php if ( ! empty( $order ) ) { ?>
367
368
+ <?php if ( ! empty( $order->id ) ) { ?>
369
+ <h1 class="wp-heading-inline"><?php esc_html_e( 'Order', 'paid-memberships-pro' ); ?> #<?php echo $order->id; ?>: <?php echo $order->code; ?></h1>
370
+ <a title="<?php _e( 'Print', 'paid-memberships-pro' ); ?>" href="<?php echo add_query_arg( array( 'action' => 'pmpro_orders_print_view', 'order' => $order->id ), admin_url('admin-ajax.php' ) ); ?>" class="page-title-action" target="_blank" ><?php _e( 'Print', 'paid-memberships-pro' ); ?></a>
371
+ <a title="<?php _e( 'Email', 'paid-memberships-pro' ); ?>" href="#TB_inline?width=600&height=200&inlineId=email_invoice" class="thickbox email_link page-title-action" data-order="<?php echo $order->id; ?>"><?php _e( 'Email', 'paid-memberships-pro' ); ?></a>
372
+ <?php } else { ?>
373
+ <h1 class="wp-heading-inline"><?php esc_html_e( 'New Order', 'paid-memberships-pro' ); ?></h1>
374
+ <?php } ?>
375
+ <hr class="wp-header-end">
376
377
<?php if ( ! empty( $pmpro_msg ) ) { ?>
378
<div id="message" class="
408
<th scope="row" valign="top"><label for="code"><?php _e( 'Code', 'paid-memberships-pro' ); ?>:</label></th>
409
<td>
410
<?php
411
+ if ( in_array( 'code', $read_only_fields ) ) {
412
+ echo $order->code;
413
+ } else { ?>
414
+ <input id="code" name="code" type="text" value="<?php echo esc_attr( $order->code ); ?>" class="regular-text" />
415
+ <?php
416
+ }
417
+ ?>
418
<?php if ( $order_id < 0 ) { ?>
419
+ <p class="description"><?php _e( 'Randomly generated for you.', 'paid-memberships-pro' ); ?></p>
420
+ <?php } ?>
421
</td>
422
</tr>
423
<tr>
424
<th scope="row" valign="top"><label for="user_id"><?php _e( 'User ID', 'paid-memberships-pro' ); ?>:</label></th>
425
<td>
426
<?php
427
+ if ( in_array( 'user_id', $read_only_fields ) && $order_id > 0 ) {
428
+ echo $order->user_id;
429
+ } else { ?>
430
+ <input id="user_id" name="user_id" type="text" value="<?php echo esc_attr( $order->user_id ); ?>" class="regular-text" />
431
+ <?php
432
+ }
433
+ ?>
434
</td>
435
</tr>
436
<tr>
437
+ <th scope="row" valign="top"><label for="membership_id"><?php _e( 'Membership Level ID', 'paid-memberships-pro' ); ?>:</label></th>
438
<td>
439
<?php
440
+ if ( in_array( 'membership_id', $read_only_fields ) && $order_id > 0 ) {
441
echo $order->membership_id;
442
+ } else { ?>
443
+ <input id="membership_id" name="membership_id" type="text" value="<?php echo esc_attr( $order->membership_id ); ?>" class="regular-text" />
444
+ <?php
445
+ }
446
+ ?>
447
</td>
448
</tr>
449
<tr>
450
<th scope="row" valign="top"><label for="billing_name"><?php _e( 'Billing Name', 'paid-memberships-pro' ); ?>:</label>
451
</th>
829
<?php
830
if ( $i == $month ) {
831
?>
832
+ selected="selected"<?php } ?>><?php echo date_i18n( 'M', strtotime( $i . '/15/' . $year, current_time( 'timestamp' ) ) ); ?></option>
833
<?php
834
}
835
?>
936
<?php } else { ?>
937
938
<form id="posts-filter" method="get" action="">
939
940
+ <h1 class="wp-heading-inline"><?php esc_html_e( 'Orders', 'paid-memberships-pro' ); ?></h1>
941
+ <a href="<?php echo add_query_arg( array( 'page' => 'pmpro-orders', 'order' => -1 ), get_admin_url(null, 'admin.php' ) ); ?>" class="page-title-action"><?php esc_html_e( 'Add New Order', 'paid-memberships-pro' ); ?></a>
942
+
943
+ <?php
944
+ // build the export URL
945
+ $export_url = admin_url( 'admin-ajax.php?action=orders_csv' );
946
+ $url_params = array(
947
+ 'filter' => $filter,
948
+ 's' => $s,
949
+ 'l' => $l,
950
+ 'start-month' => $start_month,
951
+ 'start-day' => $start_day,
952
+ 'start-year' => $start_year,
953
+ 'end-month' => $end_month,
954
+ 'end-day' => $end_day,
955
+ 'end-year' => $end_year,
956
+ 'predefined-date' => $predefined_date,
957
+ 'discount-code' => $discount_code,
958
+ 'status' => $status,
959
+ );
960
+ $export_url = add_query_arg( $url_params, $export_url );
961
+ ?>
962
+ <a target="_blank" href="<?php echo $export_url; ?>" class="page-title-action"><?php _e( 'Export to CSV', 'paid-memberships-pro' ); ?></a>
963
+
964
+ <hr class="wp-header-end">
965
966
967
<?php if ( ! empty( $pmpro_msg ) ) { ?>
1076
<?php } ?>
1077
</select>
1078
1079
+ <input id="submit" class="button" type="submit" value="<?php _e( 'Filter', 'paid-memberships-pro' ); ?>"/>
1080
</li>
1081
</ul>
1082
adminpages/pagesettings.php CHANGED
@@ -105,7 +105,9 @@ require_once(dirname(__FILE__) . "/admin_header.php");
105
106
<form action="<?php echo admin_url('admin.php?page=pmpro-pagesettings');?>" method="post" enctype="multipart/form-data">
107
<?php wp_nonce_field('savesettings', 'pmpro_pagesettings_nonce');?>
108
- <h2><?php _e( 'Page Settings', 'paid-memberships-pro' ); ?></h2>
109
<?php
110
// check if we have all pages
111
if ( $pmpro_pages['account'] ||
105
106
<form action="<?php echo admin_url('admin.php?page=pmpro-pagesettings');?>" method="post" enctype="multipart/form-data">
107
<?php wp_nonce_field('savesettings', 'pmpro_pagesettings_nonce');?>
108
+
109
+ <h1 class="wp-heading-inline"><?php esc_html_e( 'Page Settings', 'paid-memberships-pro' ); ?></h1>
110
+ <hr class="wp-header-end">
111
<?php
112
// check if we have all pages
113
if ( $pmpro_pages['account'] ||
adminpages/paymentsettings.php CHANGED
@@ -107,7 +107,8 @@
107
<form action="" method="post" enctype="multipart/form-data">
108
<?php wp_nonce_field('savesettings', 'pmpro_paymentsettings_nonce');?>
109
110
- <h2><?php _e('Payment Gateway', 'paid-memberships-pro' );?> &amp; <?php _e('SSL Settings', 'paid-memberships-pro' );?></h2>
111
112
<p><?php _e('Learn more about <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> or <a title="Paid Memberships Pro - Payment Gateway Settings" target="_blank" href="https://www.paidmembershipspro.com/documentation/initial-plugin-setup/step-3-payment-gateway-security/?utm_source=plugin&utm_medium=pmpro-paymentsettings&utm_campaign=documentation&utm_content=step-3-payment-gateway-security">Payment Gateway Settings</a>.', 'paid-memberships-pro' ); ?></p>
113
@@ -225,9 +226,9 @@
225
</th>
226
<td>
227
<?php _e('Tax State', 'paid-memberships-pro' );?>:
228
- <input type="text" id="tax_state" name="tax_state" size="4" value="<?php echo esc_attr($tax_state)?>" /> (<?php _e('abbreviation, e.g. "PA"', 'paid-memberships-pro' );?>)
229
&nbsp; <?php _e('Tax Rate', 'paid-memberships-pro' ); ?>:
230
- <input type="text" id="tax_rate" name="tax_rate" size="10" value="<?php echo esc_attr($tax_rate)?>" /> (<?php _e('decimal, e.g. "0.06"', 'paid-memberships-pro' );?>)
231
<p class="description"><?php _e('US only. If values are given, tax will be applied for any members ordering from the selected state.<br />For non-US or more complex tax rules, use the <a target="_blank" href="https://www.paidmembershipspro.com/non-us-taxes-paid-memberships-pro/?utm_source=plugin&utm_medium=pmpro-paymentsettings&utm_campaign=blog&utm_content=non-us-taxes-paid-memberships-pro">pmpro_tax filter</a>.', 'paid-memberships-pro' );?></p>
232
</td>
233
</tr>
@@ -268,7 +269,7 @@
268
<label for="sslseal"><?php _e('SSL Seal Code', 'paid-memberships-pro' );?>:</label>
269
</th>
270
<td>
271
- <textarea id="sslseal" name="sslseal" rows="3" cols="80"><?php echo stripslashes(esc_textarea($sslseal))?></textarea>
272
<p class="description"><?php _e('Your <strong><a 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=link2">SSL Certificate</a></strong> must be installed by your web host. Use this field to display your seal or other trusted merchant images. This field does not accept JavaScript.', 'paid-memberships-pro' ); ?></p>
273
</td>
274
</tr>
@@ -284,7 +285,7 @@
284
</tbody>
285
</table>
286
<p class="submit">
287
- <input name="savesettings" type="submit" class="button-primary" value="<?php _e('Save Settings', 'paid-memberships-pro' );?>" />
288
</p>
289
</form>
290
107
<form action="" method="post" enctype="multipart/form-data">
108
<?php wp_nonce_field('savesettings', 'pmpro_paymentsettings_nonce');?>
109
110
+ <h1 class="wp-heading-inline"><?php esc_html_e( 'Payment Gateway', 'paid-memberships-pro' );?> &amp; <?php esc_html_e( 'SSL Settings', 'paid-memberships-pro' ); ?></h1>
111
+ <hr class="wp-header-end">
112
113
<p><?php _e('Learn more about <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> or <a title="Paid Memberships Pro - Payment Gateway Settings" target="_blank" href="https://www.paidmembershipspro.com/documentation/initial-plugin-setup/step-3-payment-gateway-security/?utm_source=plugin&utm_medium=pmpro-paymentsettings&utm_campaign=documentation&utm_content=step-3-payment-gateway-security">Payment Gateway Settings</a>.', 'paid-memberships-pro' ); ?></p>
114
226
</th>
227
<td>
228
<?php _e('Tax State', 'paid-memberships-pro' );?>:
229
+ <input type="text" id="tax_state" name="tax_state" value="<?php echo esc_attr($tax_state)?>" class="small-text" /> (<?php _e('abbreviation, e.g. "PA"', 'paid-memberships-pro' );?>)
230
&nbsp; <?php _e('Tax Rate', 'paid-memberships-pro' ); ?>:
231
+ <input type="text" id="tax_rate" name="tax_rate" size="10" value="<?php echo esc_attr($tax_rate)?>" class="small-text" /> (<?php _e('decimal, e.g. "0.06"', 'paid-memberships-pro' );?>)
232
<p class="description"><?php _e('US only. If values are given, tax will be applied for any members ordering from the selected state.<br />For non-US or more complex tax rules, use the <a target="_blank" href="https://www.paidmembershipspro.com/non-us-taxes-paid-memberships-pro/?utm_source=plugin&utm_medium=pmpro-paymentsettings&utm_campaign=blog&utm_content=non-us-taxes-paid-memberships-pro">pmpro_tax filter</a>.', 'paid-memberships-pro' );?></p>
233
</td>
234
</tr>
269
<label for="sslseal"><?php _e('SSL Seal Code', 'paid-memberships-pro' );?>:</label>
270
</th>
271
<td>
272
+ <textarea id="sslseal" name="sslseal" rows="3" cols="50" class="large-text"><?php echo stripslashes(esc_textarea($sslseal))?></textarea>
273
<p class="description"><?php _e('Your <strong><a 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=link2">SSL Certificate</a></strong> must be installed by your web host. Use this field to display your seal or other trusted merchant images. This field does not accept JavaScript.', 'paid-memberships-pro' ); ?></p>
274
</td>
275
</tr>
285
</tbody>
286
</table>
287
<p class="submit">
288
+ <input name="savesettings" type="submit" class="button button-primary" value="<?php _e('Save Settings', 'paid-memberships-pro' );?>" />
289
</p>
290
</form>
291
adminpages/reports/login.php CHANGED
@@ -176,9 +176,9 @@ function pmpro_report_login_page()
176
<thead>
177
<tr class="thead">
178
<th><?php _e('ID', 'paid-memberships-pro')?></th>
179
- <th><?php _e('User', 'paid-memberships-pro')?></th>
180
<th><?php _e('Name', 'paid-memberships-pro')?></th>
181
- <th><?php _e('Membership', 'paid-memberships-pro')?></th>
182
<th><?php _e('Joined', 'paid-memberships-pro')?></th>
183
<th><?php _e('Expires', 'paid-memberships-pro')?></th>
184
<th><?php _e('Last Visit', 'paid-memberships-pro')?></th>
176
<thead>
177
<tr class="thead">
178
<th><?php _e('ID', 'paid-memberships-pro')?></th>
179
+ <th><?php _e('Username', 'paid-memberships-pro')?></th>
180
<th><?php _e('Name', 'paid-memberships-pro')?></th>
181
+ <th><?php _e('Level', 'paid-memberships-pro')?></th>
182
<th><?php _e('Joined', 'paid-memberships-pro')?></th>
183
<th><?php _e('Expires', 'paid-memberships-pro')?></th>
184
<th><?php _e('Last Visit', 'paid-memberships-pro')?></th>
classes/class-pmpro-members-list-table.php ADDED
@@ -0,0 +1,687 @@
1
+ <?php
2
+
3
+ if ( ! class_exists( 'WP_List_Table' ) ) {
4
+ require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
5
+ }
6
+
7
+ class PMPro_Members_List_Table extends WP_List_Table {
8
+ /**
9
+ * The text domain of this plugin.
10
+ *
11
+ * @since 2.2.0
12
+ *
13
+ * @access private
14
+ * @var string $plugin_text_domain The text domain of this plugin.
15
+ */
16
+ protected $plugin_text_domain;
17
+
18
+ /**
19
+ * Call the parent constructor to override the defaults $args
20
+ *
21
+ * @param string $plugin_text_domain Text domain of the plugin.
22
+ *
23
+ * @since 2.2.0
24
+ */
25
+ public function __construct() {
26
+
27
+ $this->plugin_text_domain = 'paid-memberships-pro';
28
+
29
+ parent::__construct(
30
+ array(
31
+ 'plural' => 'members',
32
+ // Plural value used for labels and the objects being listed.
33
+ 'singular' => 'member',
34
+ // Singular label for an object being listed, e.g. 'post'.
35
+ 'ajax' => false,
36
+ // If true, the parent class will call the _js_vars() method in the footer
37
+ )
38
+ );
39
+ }
40
+
41
+ /**
42
+ * Prepares the list of items for displaying.
43
+ *
44
+ * Query, filter data, handle sorting, and pagination, and any other data-manipulation required prior to rendering
45
+ *
46
+ * @since 2.2.0
47
+ */
48
+ public function prepare_items() {
49
+ // check if a search was performed.
50
+ $user_search_key = isset( $_REQUEST['s'] ) ? wp_unslash( trim( $_REQUEST['s'] ) ) : '';
51
+
52
+ //$columns = $this->get_columns();
53
+ //$hidden = $this->get_hidden_columns();
54
+ //$sortable = $this->get_sortable_columns();
55
+ //$this->_column_headers = array( $columns, $hidden, $sortable );
56
+ $this->_column_headers = $this->get_column_info();
57
+ // $query = $query . ' where cat_id=' . mysql_real_escape_string( $_GET['cat-filter'] );
58
+ // $this->get_column_info() = $this->_column_headers;
59
+ // check and process any actions such as bulk actions.
60
+ $this->handle_table_actions();
61
+
62
+ // fetch table data
63
+ $table_data = $this->sql_table_data();
64
+ usort( $table_data, array( $this, 'sort_data' ) );
65
+
66
+ // filter the data in case of a search.
67
+ if ( $user_search_key ) {
68
+ $table_data = $this->filter_table_data( $table_data, $user_search_key );
69
+ }
70
+
71
+ // required for pagination
72
+ $users_per_page = $this->get_items_per_page( 'users_per_page' );
73
+ $table_page = $this->get_pagenum();
74
+
75
+ // provide the ordered data to the List Table.
76
+ // we need to manually slice the data based on the current pagination.
77
+ $this->items = array_slice( $table_data, ( ( $table_page - 1 ) * $users_per_page ), $users_per_page );
78
+
79
+ // set the pagination arguments
80
+ $total_users = count( $table_data );
81
+ $this->set_pagination_args(
82
+ array(
83
+ 'total_items' => $total_users,
84
+ 'per_page' => $users_per_page,
85
+ 'total_pages' => ceil( $total_users / $users_per_page ),
86
+ )
87
+ );
88
+ }
89
+
90
+ /**
91
+ * Get a list of columns.
92
+ *
93
+ * The format is: 'internal-name' => 'Title'
94
+ *
95
+ * @since 2.2.0
96
+ *
97
+ * @return array
98
+ */
99
+ public function get_columns() {
100
+ $columns = array(
101
+ // 'cb' => '<input type="checkbox" />',
102
+ 'ID' => 'ID',
103
+ 'username' => 'Username',
104
+ 'first_name' => 'First Name',
105
+ 'last_name' => 'Last Name',
106
+ 'display_name' => 'Display Name',
107
+ 'user_email' => 'Email',
108
+ 'address' => 'Billing Address',
109
+ 'membership' => 'Level',
110
+ 'membership_id' => 'Level ID',
111
+ 'billing_amount' => 'Fee',
112
+ 'joindate' => 'Registered',
113
+ 'startdate' => 'Start Date',
114
+ 'enddate' => 'End Date',
115
+ );
116
+
117
+ if ( isset( $_REQUEST['l'] ) ) {
118
+ $l = sanitize_text_field( $_REQUEST['l'] );
119
+ } else {
120
+ $l = false;
121
+ }
122
+
123
+ if ( 'oldmembers' === $l ) {
124
+ $columns['enddate'] = 'Ended';
125
+ } elseif ( 'expired' === $l ) {
126
+ $columns['enddate'] = 'Expired';
127
+ } elseif ( 'cancelled' === $l ) {
128
+ $columns['enddate'] = 'Cancelled';
129
+ }
130
+
131
+ $columns = apply_filters( 'pmpro_memberslist_extra_cols', $columns );
132
+
133
+ // Re-implementing old hook, will be deprecated.
134
+ ob_start();
135
+ do_action( 'pmpro_memberslist_extra_cols_header' );
136
+ $extra_cols = ob_get_clean();
137
+ preg_match_all( '/<th>(.*?)<\/th>/s', $extra_cols, $matches );
138
+ $custom_field_num = 0;
139
+ foreach ( $matches[1] as $match ) {
140
+ $columns[ 'custom_field_' . $custom_field_num ] = $match;
141
+ $custom_field_num++;
142
+ }
143
+
144
+ return $columns;
145
+ }
146
+
147
+ /**
148
+ * Define which columns are hidden
149
+ *
150
+ * @return Array
151
+ */
152
+ public function get_hidden_columns() {
153
+ $hidden = array(
154
+ 'display_name',
155
+ 'membership_id',
156
+ 'joindate',
157
+ );
158
+ return $hidden;
159
+ }
160
+
161
+ /**
162
+ * Get a list of sortable columns. The format is:
163
+ * 'internal-name' => 'orderby'
164
+ * or
165
+ * 'internal-name' => array( 'orderby', true )
166
+ *
167
+ * The second format will make the initial sorting order be descending
168
+ *
169
+ * @since 2.2.0
170
+ *
171
+ * @return array
172
+ */
173
+ protected function get_sortable_columns() {
174
+ /**
175
+ * actual sorting still needs to be done by prepare_items.
176
+ * specify which columns should have the sort icon.
177
+ *
178
+ * key => value
179
+ * column name_in_list_table => columnname in the db
180
+ */
181
+ return array(
182
+ 'ID' => array(
183
+ 'ID',
184
+ false,
185
+ ),
186
+ 'username' => array(
187
+ 'user_login',
188
+ false,
189
+ ),/*
190
+ 'first_name' => array(
191
+ 'first_name',
192
+ false,
193
+ ),
194
+ 'last_name' => array(
195
+ 'last_name',
196
+ false,
197
+ ),*/
198
+ 'billing_amount' => array(
199
+ 'billing_amount',
200
+ false,
201
+ ),
202
+ 'display_name' => array(
203
+ 'display_name',
204
+ false,
205
+ ),
206
+ 'user_email' => array(
207
+ 'user_email',
208
+ false,
209
+ ),
210
+ 'membership' => array(
211
+ 'membership',
212
+ false,
213
+ ),
214
+ 'membership_id' => array(
215
+ 'membership_id',
216
+ false,
217
+ ),
218
+ 'joindate' => array(
219
+ 'joindate',
220
+ false,
221
+ ),
222
+ 'startdate' => array(
223
+ 'startdate',
224
+ false,
225
+ ),
226
+ 'enddate' => array(
227
+ 'enddate',
228
+ false,
229
+ ),
230
+ );
231
+ }
232
+
233
+ /**
234
+ * Return number of visible columns
235
+ *
236
+ * @since 2.2.0
237
+ *
238
+ * @access public
239
+ * @return int
240
+ */
241
+ public function get_column_count() {
242
+ list ( $columns, $hidden ) = $this->get_column_info();
243
+ $hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) );
244
+ return count( $columns ) - count( $hidden );
245
+ }
246
+
247
+ /**
248
+ * Allows you to sort the data by the variables set in the $_GET
249
+ *
250
+ * @return Mixed
251
+ */
252
+ private function sort_data( $a, $b ) {
253
+ // Set defaults
254
+ $orderby = 'ID';
255
+ $order = 'desc';
256
+
257
+ // If orderby is set, use this as the sort column
258
+ if ( ! empty( $_GET['orderby'] ) ) {
259
+ $orderby = $_GET['orderby'];
260
+ }
261
+
262
+ // If order is set use this as the order
263
+ if ( ! empty( $_GET['order'] ) ) {
264
+ $order = $_GET['order'];
265
+ }
266
+
267
+ if ( is_numeric( $a[ $orderby ] ) && is_numeric( $b[ $orderby ] ) ) {
268
+ $result = intval( $a[ $orderby ] ) > intval( $b[ $orderby ] ) ? 1 : -1;
269
+ } else {
270
+ $result = strcmp( $a[ $orderby ], $b[ $orderby ] );
271
+ }
272
+
273
+ if ( $order === 'asc' ) {
274
+ return $result;
275
+ }
276
+
277
+ return -$result;
278
+ }
279
+
280
+ /**
281
+ * Text displayed when no user data is available
282
+ *
283
+ * @since 2.2.0
284
+ *
285
+ * @return void
286
+ */
287
+ public function no_items() {
288
+ _e( 'No users avaliable.', $this->plugin_text_domain );
289
+ }
290
+
291
+ /**
292
+ * Get the table data
293
+ *
294
+ * @return Array
295
+ */
296
+ private function sql_table_data() {
297
+ global $wpdb;
298
+
299
+ if ( isset( $_REQUEST['l'] ) ) {
300
+ $l = sanitize_text_field( $_REQUEST['l'] );
301
+ } else {
302
+ $l = false;
303
+ }
304
+
305
+ $sql_table_data = array();
306
+
307
+ $mysqli_query =
308
+ "
309
+ SELECT SQL_CALC_FOUND_ROWS u.ID, u.user_login, u.user_email, u.display_name,
310
+ UNIX_TIMESTAMP(u.user_registered) as joindate, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, mu.cycle_number, mu.billing_limit, mu.trial_amount, mu.trial_limit,
311
+ UNIX_TIMESTAMP(mu.startdate) as startdate,
312
+ UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership
313
+ -- um.first_name as first_name, um.last_name as last_name
314
+ FROM $wpdb->users u
315
+ LEFT JOIN $wpdb->usermeta um
316
+ ON u.ID = um.user_id
317
+ LEFT JOIN $wpdb->pmpro_memberships_users mu
318
+ ON u.ID = mu.user_id
319
+ LEFT JOIN $wpdb->pmpro_membership_levels m
320
+ ON mu.membership_id = m.id
321
+ ";
322
+
323
+ if ( 'oldmembers' === $l || 'expired' === $l || 'cancelled' === $l ) {
324
+ $mysqli_query .= " LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON u.ID = mu2.user_id AND mu2.status = 'active' ";
325
+ }
326
+ $mysqli_query .= ' WHERE mu.membership_id > 0';
327
+
328
+ if ( 'oldmembers' === $l ) {
329
+ $mysqli_query .= " AND mu.status <> 'active' AND mu2.status IS NULL ";
330
+ } elseif ( 'expired' === $l ) {
331
+ $mysqli_query .= " AND mu.status = 'expired' AND mu2.status IS NULL ";
332
+ } elseif ( 'cancelled' === $l ) {
333
+ $mysqli_query .= " AND mu.status IN('cancelled', 'admin_cancelled') AND mu2.status IS NULL ";
334
+ } elseif ( $l ) {
335
+ $mysqli_query .= " AND mu.status = 'active' AND mu.membership_id = '" . esc_sql( $l ) . "' ";
336
+ } else {
337
+ $mysqli_query .= " AND mu.status = 'active' ";
338
+ }
339
+ $mysqli_query .= 'GROUP BY u.ID ';
340
+
341
+ if ( 'oldmembers' === $l || 'expired' === $l || 'cancelled' === $l ) {
342
+ $mysqli_query .= 'ORDER BY enddate DESC ';
343
+ } else {
344
+ $mysqli_query .= 'ORDER BY u.user_registered DESC ';
345
+ }
346
+
347
+ $mysqli_query = apply_filters("pmpro_members_list_sql", $mysqli_query);
348
+ $sql_table_data = $wpdb->get_results( $mysqli_query, ARRAY_A );
349
+ return $sql_table_data;
350
+ }
351
+
352
+ /**
353
+ * Filter the table data based on the user search key
354
+ *
355
+ * @since 2.2.0
356
+ *
357
+ * @param array $table_data
358
+ * @param string $search_key
359
+ * @return array
360
+ */
361
+ public function filter_table_data( $table_data, $search_key ) {
362
+ $filtered_table_data = array_values(
363
+ array_filter(
364
+ $table_data,
365
+ function( $row ) use ( $search_key ) {
366
+ foreach ( $row as $row_val ) {
367
+ if ( stripos( $row_val, $search_key ) !== false ) {
368
+ return true;
369
+ }
370
+ }
371
+ }
372
+ )
373
+ );
374
+ return $filtered_table_data;
375
+ }
376
+
377
+ /**
378
+ * Render a column when no column specific method exists.
379
+ *
380
+ * @param array $item
381
+ * @param string $column_name
382
+ *
383
+ * @return mixed
384
+ */
385
+ public function column_default( $item, $column_name ) {
386
+ $item = (array) apply_filters( 'pmpro_members_list_user', (object) $item );
387
+ switch ( $column_name ) {
388
+ case 'ID':
389
+ case 'display_name':
390
+ case 'user_email':
391
+ case 'membership':
392
+ case 'membership_id':
393
+ case 'cycle_period':
394
+ case 'cycle_number':
395
+ return $item[ $column_name ];
396
+ case 'username':
397
+ $avatar = get_avatar( $item['ID'], 32 );
398
+ $userlink = '<a href="user-edit.php?user_id=' . $item['ID'] . '">' . $item['user_login'] . '</a>';
399
+ $userlink = apply_filters( 'pmpro_members_list_user_link', $userlink, get_userdata( $item['ID'] ) );
400
+ $output = $avatar . ' <strong>' . $userlink . '</strong><br />';
401
+
402
+ // Set up the hover actions for this user
403
+ $actions = apply_filters( 'pmpro_memberslist_user_row_actions', array(), (object) $item );
404
+ $action_count = count( $actions );
405
+ $i = 0;
406
+ if ( $action_count ) {
407
+ $output .= '<div class="row-actions">';
408
+ foreach ( $actions as $action => $link ) {
409
+ ++$i;
410
+ ( $i == $action_count ) ? $sep = '' : $sep = ' | ';
411
+ $output .= "<span class='$action'>$link$sep</span>";
412
+ }
413
+ $output .= '</div>';
414
+ }
415
+ return $output;
416
+ case 'billing_amount':
417
+ $billing_amount = '';
418
+ // If there is no payment for the level, show a dash.
419
+ if ( (float)$item['initial_payment'] <= 0 && (float)$item['billing_amount'] <= 0 ) {
420
+ $billing_amount .= esc_html_e( '&#8212;', 'paid-memberships-pro' );
421
+ } else {
422
+ // Display the member's initial payment.
423
+ if ( (float)$item['initial_payment'] > 0 ) {
424
+ $billing_amount .= pmpro_formatPrice( $item['initial_payment'] );
425
+ }
426
+ // If there is a recurring payment, show a plus sign.
427
+ if ( (float)$item['initial_payment'] > 0 && (float)$item['billing_amount'] > 0 ) {
428
+ $billing_amount .= esc_html( ' + ', 'paid-memberships-pro' );
429
+ }
430
+ // If there is a recurring payment, show the recurring payment amount and cycle.
431
+ if ( (float)$item['billing_amount'] > 0 ) {
432
+ $billing_amount .= pmpro_formatPrice( $item['billing_amount'] );
433
+ $billing_amount .= esc_html( ' per ', 'paid-memberships-pro' );
434
+ if ( $item['cycle_number'] > 1 ) {
435
+ $billing_amount .= $item['cycle_number'] . " " . $item['cycle_period'] . "s";
436
+ } else {
437
+ $billing_amount .= $item['cycle_period'];
438
+ }
439
+ }
440
+ }
441
+ return $billing_amount;
442
+ case 'joindate':
443
+ $joindate = $item[ $column_name ];
444
+ return date_i18n( get_option('date_format'), $joindate );
445
+ case 'startdate':
446
+ $startdate = $item[ $column_name ];
447
+ return date_i18n( get_option('date_format'), $startdate );
448
+ case 'enddate':
449
+ $user_object = get_userdata( $item['ID'] );
450
+ if ( 0 == $item['enddate'] ) {
451
+ return __( apply_filters( 'pmpro_memberslist_expires_column', 'Never', $user_object ), 'paid-memberships-pro');
452
+ } else {
453
+ return apply_filters( 'pmpro_memberslist_expires_column', date_i18n( get_option('date_format'), $item['enddate'] ), $user_object );
454
+ }
455
+ default:
456
+ if ( isset( $item->$column_name ) ) {
457
+ return $item->$column_name;
458
+ } elseif ( 0 === strpos( $column_name, 'custom_field_' ) ) {
459
+ // Re-implementing old hook, will be deprecated.
460
+ $user_object = get_userdata( $item['ID'] );
461
+ ob_start();
462
+ do_action( 'pmpro_memberslist_extra_cols_body', $user_object );
463
+ $extra_cols = ob_get_clean();
464
+ preg_match_all( '/<td>(.*?)<\/td>/s', $extra_cols, $matches );
465
+ $custom_field_num = explode( 'custom_field_', $column_name )[1];
466
+ if ( is_numeric( $custom_field_num ) && isset( $matches[1][ intval( $custom_field_num ) ] ) ) {
467
+ return $matches[1][ intval( $custom_field_num ) ];
468
+ }
469
+ }
470
+ }
471
+ }
472
+
473
+ /**
474
+ * Get value for checkbox column.
475
+ *
476
+ * The special 'cb' column
477
+ *
478
+ * @param object $item A row's data
479
+ * @return string Text to be placed inside the column <td>.
480
+ */
481
+ protected function column_cb( $item ) {
482
+ return sprintf(
483
+ '<label class="screen-reader-text" for="user_' . $item['ID'] . '">' . sprintf( __( 'Select %s' ), $item['user_login'] ) . '</label>'
484
+ . "<input type='checkbox' name='users[]' id='user_{$item['ID']}' value='{$item['ID']}' />"
485
+ );
486
+ }
487
+
488
+ /**
489
+ * Get value for first name column.
490
+ *
491
+ * The special 'first_name' column
492
+ *
493
+ * @param object $item A row's data
494
+ * @return string Text to be placed inside the column <td>.
495
+ */
496
+ public function column_first_name( $item ) {
497
+ $user_object = get_userdata( $item['ID'] );
498
+ return ( $user_object->first_name ?: '&#8212;' );
499
+ }
500
+
501
+ /**
502
+ * Get value for last name column.
503
+ *
504
+ * The special 'last_name' column
505
+ *
506
+ * @param object $item A row's data
507
+ * @return string Text to be placed inside the column <td>.
508
+ */
509
+ public function column_last_name( $item ) {
510
+ $user_object = get_userdata( $item['ID'] );
511
+ return ( $user_object->last_name ?: '&#8212;' );
512
+ }
513
+
514
+ /**
515
+ * Get value for Address column.
516
+ *
517
+ * The special 'address' column
518
+ *
519
+ * @param object $item A row's data
520
+ * @return string Text to be placed inside the column <td>.
521
+ */
522
+ public function column_address( $item ) {
523
+ $user_object = get_userdata( $item['ID'] );
524
+ return pmpro_formatAddress( trim( $user_object->pmpro_bfirstname . ' ' . $user_object->pmpro_blastname ), $user_object->pmpro_baddress1, $user_object->pmpro_baddress2, $user_object->pmpro_bcity, $user_object->pmpro_bstate, $user_object->pmpro_bzipcode, $user_object->pmpro_bcountry, $user_object->pmpro_bphone );
525
+ // return ( $user_object->last_name ?: '---' );
526
+ }
527
+
528
+ public function get_some_actions() {
529
+ ?>
530
+ <ul class="subsubsub">
531
+ <li>
532
+ <?php _e( 'Show', 'paid-memberships-pro' ); ?>
533
+ <select name="l" onchange="jQuery('#posts-filter').submit();">
534
+ <option value=""
535
+ <?php
536
+ if ( ! $l ) {
537
+ ?>
538
+ selected="selected"<?php } ?>><?php _e( 'All Levels', 'paid-memberships-pro' ); ?></option>
539
+ <?php
540
+ $levels = $wpdb->get_results(
541
+ "
542
+ SELECT id, name
543
+ FROM $wpdb->pmpro_membership_levels
544
+ ORDER BY name
545
+ "
546
+ );
547
+ foreach ( $levels as $level ) {
548
+ ?>
549
+ <option value="<?php echo $level->id; ?>"
550
+ <?php
551
+ if ( $l == $level->id ) {
552
+ ?>
553
+ selected="selected"<?php } ?>><?php echo $level->name; ?></option>
554
+ <?php
555
+ }
556
+ ?>
557
+ <option value="cancelled"
558
+ <?php
559
+ if ( $l == 'cancelled' ) {
560
+ ?>
561
+ selected="selected"<?php } ?>><?php _e( 'Cancelled Members', 'paid-memberships-pro' ); ?></option>
562
+ <option value="expired"
563
+ <?php
564
+ if ( $l == 'expired' ) {
565
+ ?>
566
+ selected="selected"<?php } ?>><?php _e( 'Expired Members', 'paid-memberships-pro' ); ?></option>
567
+ <option value="oldmembers"
568
+ <?php
569
+ if ( $l == 'oldmembers' ) {
570
+ ?>
571
+ selected="selected"<?php } ?>><?php _e( 'Old Members', 'paid-memberships-pro' ); ?></option>
572
+ </select>
573
+ </li>
574
+ </ul>
575
+ <?php
576
+ }
577
+
578
+ /**
579
+ * Add extra markup in the toolbars before or after the list
580
+ *
581
+ * @param string $which, helps you decide if you add the markup after (bottom) or before (top) the list array( '' => 'Select a Level' )
582
+ */
583
+ function extra_tablenav( $which ) {
584
+ global $membership_levels, $wpdb;
585
+ if ( $which == 'top' ) {
586
+ // The code that goes before the table is here
587
+ if(isset($_REQUEST['l'])) {
588
+ $l = sanitize_text_field($_REQUEST['l']);
589
+ } else {
590
+ $l = false;
591
+ }
592
+ _e('Show', 'paid-memberships-pro' );?>
593
+ <select name="l" onchange="jQuery('#member-list-form').submit();">
594
+ <option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'paid-memberships-pro' );?></option>
595
+ <?php
596
+ $levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
597
+ foreach($levels as $level)
598
+ {
599
+ ?>
600
+ <option value="<?php echo $level->id?>" <?php if($l == $level->id) { ?>selected="selected"<?php } ?>><?php echo $level->name?></option>
601
+ <?php
602
+ }
603
+ ?>
604
+ <option value="cancelled" <?php if($l == "cancelled") { ?>selected="selected"<?php } ?>><?php _e('Cancelled Members', 'paid-memberships-pro' );?></option>
605
+ <option value="expired" <?php if($l == "expired") { ?>selected="selected"<?php } ?>><?php _e('Expired Members', 'paid-memberships-pro' );?></option>
606
+ <option value="oldmembers" <?php if($l == "oldmembers") { ?>selected="selected"<?php } ?>><?php _e('Old Members', 'paid-memberships-pro' );?></option>
607
+ </select>
608
+ <?php
609
+ }
610
+ if ( $which == 'bottom' ) {
611
+ // The code that goes after the table is there
612
+ }
613
+ }
614
+
615
+ /**
616
+ * Process actions triggered by the user
617
+ *
618
+ * @since 2.2.0
619
+ */
620
+ public function handle_table_actions() {
621
+ /**
622
+ * Note: Table bulk_actions can be identified by checking $_REQUEST['action'] and $_REQUEST['action2']
623
+ *
624
+ * action - is set if checkbox from top-most select-all is set, otherwise returns -1
625
+ * action2 - is set if checkbox the bottom-most select-all checkbox is set, otherwise returns -1
626
+ */
627
+
628
+ // check for individual row actions
629
+ $the_table_action = $this->current_action();
630
+
631
+ if ( 'view_usermeta' === $the_table_action ) {
632
+ $nonce = wp_unslash( $_REQUEST['_wpnonce'] );
633
+ // verify the nonce.
634
+ if ( ! wp_verify_nonce( $nonce, 'view_usermeta_nonce' ) ) {
635
+ $this->invalid_nonce_redirect();
636
+ } else {
637
+ $this->graceful_exit();
638
+ }
639
+ }
640
+
641
+ // check for table bulk actions
642
+ if ( ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] === 'bulk-download' ) || ( isset( $_REQUEST['action2'] ) && $_REQUEST['action2'] === 'bulk-download' ) ) {
643
+
644
+ // verify the nonce.
645
+ $nonce = wp_unslash( $_REQUEST['_wpnonce'] );
646
+ /**
647
+ * Note: the nonce field is set by the parent class
648
+ * wp_nonce_field( 'bulk-' . $this->_args['plural'] );
649
+ */
650
+ if ( ! wp_verify_nonce( $nonce, 'bulk-users' ) ) {
651
+ $this->invalid_nonce_redirect();
652
+ } else {
653
+ $this->page_bulk_download( $_REQUEST['users'] );
654
+ $this->graceful_exit();
655
+ }
656
+ }
657
+ }
658
+
659
+ /**
660
+ * Stop execution and exit
661
+ *
662
+ * @since 2.2.0
663
+ *
664
+ * @return void
665
+ */
666
+ public function graceful_exit() {
667
+ exit;
668
+ }
669
+
670
+ /**
671
+ * Die when the nonce check fails.
672
+ *
673
+ * @since 2.2.0
674
+ *
675
+ * @return void
676
+ */
677
+ public function invalid_nonce_redirect() {
678
+ wp_die(
679
+ __( 'Invalid Nonce', $this->plugin_text_domain ),
680
+ __( 'Error', $this->plugin_text_domain ),
681
+ array(
682
+ 'response' => 403,
683
+ 'back_link' => esc_url( add_query_arg( array( 'page' => wp_unslash( $_REQUEST['page'] ) ), admin_url( 'pmpro-membershiplevels' ) ) ),
684
+ )
685
+ );
686
+ }
687
+ }
classes/class.memberorder.php CHANGED
@@ -855,10 +855,14 @@
855
$pmproemail->template = "subscription_cancel_error";
856
$pmproemail->data = array("body"=>"<p>" . sprintf(__("There was an error canceling the subscription for user with ID=%s. You will want to check your payment gateway to see if their subscription is still active.", 'paid-memberships-pro' ), strval($this->user_id)) . "</p><p>Error: " . $this->error . "</p>");
857
$pmproemail->data["body"] .= '<p>' . __('User Email', 'paid-memberships-pro') . ': ' . $order_user->user_email . '</p>';
858
$pmproemail->data["body"] .= '<p>' . __('User Display Name', 'paid-memberships-pro') . ': ' . $order_user->display_name . '</p>';
859
$pmproemail->data["body"] .= '<p>' . __('Order', 'paid-memberships-pro') . ': ' . $this->code . '</p>';
860
$pmproemail->data["body"] .= '<p>' . __('Gateway', 'paid-memberships-pro') . ': ' . $this->gateway . '</p>';
861
$pmproemail->data["body"] .= '<p>' . __('Subscription Transaction ID', 'paid-memberships-pro') . ': ' . $this->subscription_transaction_id . '</p>';
862
$pmproemail->sendEmail(get_bloginfo("admin_email"));
863
} else {
864
//Note: status would have been set to cancelled by the gateway class. So we don't have to update it here.
855
$pmproemail->template = "subscription_cancel_error";
856
$pmproemail->data = array("body"=>"<p>" . sprintf(__("There was an error canceling the subscription for user with ID=%s. You will want to check your payment gateway to see if their subscription is still active.", 'paid-memberships-pro' ), strval($this->user_id)) . "</p><p>Error: " . $this->error . "</p>");
857
$pmproemail->data["body"] .= '<p>' . __('User Email', 'paid-memberships-pro') . ': ' . $order_user->user_email . '</p>';
858
+ $pmproemail->data["body"] .= '<p>' . __('Username', 'paid-memberships-pro') . ': ' . $order_user->user_login . '</p>';
859
$pmproemail->data["body"] .= '<p>' . __('User Display Name', 'paid-memberships-pro') . ': ' . $order_user->display_name . '</p>';
860
$pmproemail->data["body"] .= '<p>' . __('Order', 'paid-memberships-pro') . ': ' . $this->code . '</p>';
861
$pmproemail->data["body"] .= '<p>' . __('Gateway', 'paid-memberships-pro') . ': ' . $this->gateway . '</p>';
862
$pmproemail->data["body"] .= '<p>' . __('Subscription Transaction ID', 'paid-memberships-pro') . ': ' . $this->subscription_transaction_id . '</p>';
863
+ $pmproemail->data["body"] .= '<hr />';
864
+ $pmproemail->data["body"] .= '<p>' . __('Edit User', 'paid-memberships-pro') . ': ' . get_edit_user_link( $this->user_id ) . '</p>';
865
+ $pmproemail->data["body"] .= '<p>' . __('Edit Order', 'paid-memberships-pro') . ': ' . add_query_arg( array( 'page' => 'pmpro-orders', 'order' => $this->id ), admin_url('admin.php' ) ) . '</p>';
866
$pmproemail->sendEmail(get_bloginfo("admin_email"));