Paid Memberships Pro - Version 1.8.7.2

Version Description

  • BUG: Fixed bug where pmpro_activation() was firing on every page load. (Thanks, Tigertech and MegaZ on WordPress.org)
  • BUG: Fixed bugs with internationalized date formats in a few places.
Download this release

Release Info

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

Code changes from version 1.8.6.8.1 to 1.8.7.2

Files changed (49) hide show
  1. adminpages/memberslist.php +1 -1
  2. adminpages/orders-print.php +1 -1
  3. adminpages/orders.php +2 -31
  4. adminpages/reports/memberships.php +9 -9
  5. adminpages/reports/sales.php +3 -3
  6. adminpages/updates.php +29 -0
  7. classes/class.memberorder.php +57 -4
  8. classes/class.pmproemail.php +15 -15
  9. classes/gateways/class.pmprogateway.php +1 -1
  10. classes/gateways/class.pmprogateway_authorizenet.php +1 -1
  11. classes/gateways/class.pmprogateway_braintree.php +1 -1
  12. classes/gateways/class.pmprogateway_check.php +1 -1
  13. classes/gateways/class.pmprogateway_cybersource.php +1 -1
  14. classes/gateways/class.pmprogateway_payflowpro.php +1 -1
  15. classes/gateways/class.pmprogateway_paypal.php +1 -1
  16. classes/gateways/class.pmprogateway_paypalexpress.php +1 -1
  17. classes/gateways/class.pmprogateway_paypalstandard.php +1 -1
  18. classes/gateways/class.pmprogateway_stripe.php +25 -3
  19. classes/gateways/class.pmprogateway_twocheckout.php +1 -1
  20. css/frontend.css +378 -143
  21. includes/adminpages.php +11 -2
  22. includes/content.php +7 -4
  23. includes/currencies.php +2 -0
  24. includes/functions.php +8 -4
  25. includes/lib/recaptchalib.php +1 -1
  26. includes/metaboxes.php +7 -2
  27. includes/updates.php +128 -0
  28. includes/upgradecheck.php +100 -0
  29. js/updates.js +54 -0
  30. languages/email/fr_FR/billing.html +3 -3
  31. languages/pmpro-fa_IR.mo +0 -0
  32. languages/pmpro-fa_IR.po +4769 -0
  33. languages/pmpro-fr_FR.po +56 -56
  34. languages/pmpro-nb_NO.mo +0 -0
  35. languages/pmpro-nb_NO.po +4322 -3279
  36. languages/pmpro.po +1112 -648
  37. languages/pmpro.pot +1106 -639
  38. pages/cancel.php +1 -1
  39. pages/confirmation.php +1 -1
  40. pages/invoice.php +2 -2
  41. pages/levels.php +1 -1
  42. paid-memberships-pro.php +5 -2
  43. readme.txt +20 -1
  44. services/applydiscountcode.php +37 -37
  45. services/authnet-silent-post.php +4 -1
  46. services/braintree-webhook.php +2 -2
  47. services/ipnhandler.php +5 -2
  48. services/stripe-webhook.php +9 -8
  49. services/twocheckout-ins.php +122 -122
adminpages/memberslist.php CHANGED
@@ -268,7 +268,7 @@
268
  </form>
269
 
270
  <?php
271
- echo pmpro_getPaginationString($pn, $totalrows, $limit, 1, get_admin_url(NULL, "/admin.php?page=pmpro-memberslist&s=" . urlencode($s)), "&l=$l&limit=$limit&pn=");
272
  ?>
273
 
274
  <?php
268
  </form>
269
 
270
  <?php
271
+ echo pmpro_getPaginationString($pn, $totalrows, $limit, 1, add_query_arg(array("s" => urlencode($s), "l" => $l, "limit" => $limit)));
272
  ?>
273
 
274
  <?php
adminpages/orders-print.php CHANGED
@@ -14,7 +14,7 @@ if ( ! function_exists( "current_user_can" ) || ( ! current_user_can( "manage_op
14
 
15
  // Do we have an order ID?
16
  if ( empty( $_REQUEST['order'] ) ) {
17
- wp_redirect( admin_url( 'admin..php?page=pmpro-orders' ) );
18
  exit;
19
  }
20
 
14
 
15
  // Do we have an order ID?
16
  if ( empty( $_REQUEST['order'] ) ) {
17
+ wp_redirect( admin_url( 'admin.php?page=pmpro-orders' ) );
18
  exit;
19
  }
20
 
adminpages/orders.php CHANGED
@@ -303,35 +303,6 @@
303
  else
304
  {
305
  $order = new MemberOrder(); //new order
306
-
307
- //defaults
308
- $order->code = $order->getRandomCode();
309
- $order->user_id = "";
310
- $order->membership_id = "";
311
- $order->billing->name = "";
312
- $order->billing->street = "";
313
- $order->billing->city = "";
314
- $order->billing->state = "";
315
- $order->billing->zip = "";
316
- $order->billing->country = "";
317
- $order->billing->phone = "";
318
- $order->subtotal = "";
319
- $order->tax = "";
320
- $order->couponamount = "";
321
- $order->total = "";
322
- $order->payment_type = "";
323
- $order->cardtype = "";
324
- $order->accountnumber = "";
325
- $order->expirationmonth = "";
326
- $order->expirationyear = "";
327
- $order->status = "success";
328
- $order->gateway = pmpro_getOption("gateway");
329
- $order->gateway_environment = pmpro_getOption("gateway_environment");
330
- $order->payment_transaction_id = "";
331
- $order->subscription_transaction_id = "";
332
- $order->affiliate_id = "";
333
- $order->affiliate_subid = "";
334
- $order->notes = "";
335
  }
336
  }
337
  }
@@ -625,7 +596,7 @@
625
  if(!empty($affiliates)) {
626
  ?>
627
  <tr>
628
- <th scope="row" valign="top"><label for="affiliate_id"><?php _e('Affiliate ID', 'pmpro');?>Affiliate ID:</label></th>
629
  <td>
630
  <?php if(in_array("affiliate_id", $read_only_fields) && $order_id > 0) { echo $order->affiliate_id; } else { ?>
631
  <input id="affiliate_id" name="affiliate_id" type="text" size="50" value="<?php echo esc_attr($order->affiliate_id);?>" />
@@ -633,7 +604,7 @@
633
  </td>
634
  </tr>
635
  <tr>
636
- <th scope="row" valign="top"><label for="affiliate_subid"><?php _e('Affiliate SubID', 'pmpro');?>Affiliate SubID:</label></th>
637
  <td>
638
  <?php if(in_array("affiliate_subid", $read_only_fields) && $order_id > 0) { echo $order->affiliate_subid; } else { ?>
639
  <input id="affiliate_subid" name="affiliate_subid" type="text" size="50" value="<?php echo esc_attr($order->affiliate_subid);?>" />
303
  else
304
  {
305
  $order = new MemberOrder(); //new order
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
  }
307
  }
308
  }
596
  if(!empty($affiliates)) {
597
  ?>
598
  <tr>
599
+ <th scope="row" valign="top"><label for="affiliate_id"><?php _e('Affiliate ID', 'pmpro');?>:</label></th>
600
  <td>
601
  <?php if(in_array("affiliate_id", $read_only_fields) && $order_id > 0) { echo $order->affiliate_id; } else { ?>
602
  <input id="affiliate_id" name="affiliate_id" type="text" size="50" value="<?php echo esc_attr($order->affiliate_id);?>" />
604
  </td>
605
  </tr>
606
  <tr>
607
+ <th scope="row" valign="top"><label for="affiliate_subid"><?php _e('Affiliate SubID', 'pmpro');?>:</label></th>
608
  <td>
609
  <?php if(in_array("affiliate_subid", $read_only_fields) && $order_id > 0) { echo $order->affiliate_subid; } else { ?>
610
  <input id="affiliate_subid" name="affiliate_subid" type="text" size="50" value="<?php echo esc_attr($order->affiliate_subid);?>" />
adminpages/reports/memberships.php CHANGED
@@ -162,9 +162,9 @@ function pmpro_report_memberships_page()
162
  if ( $type === "signup_v_cancel" || $type === "signup_v_expiration" || $type === "signup_v_all" ) {
163
  $cols[$i] = new stdClass();
164
  $cols[$i]->signups = 0;
165
- foreach($dates as $date)
166
  {
167
- if( $date->date == $i ) {
168
  $cols[$i]->signups = $date->signups;
169
  }
170
  }
@@ -206,7 +206,7 @@ function pmpro_report_memberships_page()
206
  elseif($period == "annual") //annual
207
  {
208
  }
209
-
210
  $dates = ( ! empty( $cols ) ) ? $cols : $dates;
211
 
212
  // Signups vs. all
@@ -230,16 +230,16 @@ function pmpro_report_memberships_page()
230
 
231
  //restrict by level
232
  if(!empty($l))
233
- $sqlQuery .= "AND membership_id IN(" . $l . ") ";
234
 
235
  $sqlQuery .= " GROUP BY date ORDER BY date ";
236
 
237
- $cdates = $wpdb->get_results($sqlQuery, OBJECT_K);
238
-
239
- foreach( $dates as &$date )
240
  {
241
- if(!empty($cdates) && !empty($cdates[$date->date]))
242
- $date->cancellations = $cdates[$date->date]->cancellations;
243
  else
244
  $date->cancellations = 0;
245
  }
162
  if ( $type === "signup_v_cancel" || $type === "signup_v_expiration" || $type === "signup_v_all" ) {
163
  $cols[$i] = new stdClass();
164
  $cols[$i]->signups = 0;
165
+ foreach($dates as $day => $date)
166
  {
167
+ if( $day == $i ) {
168
  $cols[$i]->signups = $date->signups;
169
  }
170
  }
206
  elseif($period == "annual") //annual
207
  {
208
  }
209
+
210
  $dates = ( ! empty( $cols ) ) ? $cols : $dates;
211
 
212
  // Signups vs. all
230
 
231
  //restrict by level
232
  if(!empty($l))
233
+ $sqlQuery .= "AND mu1.membership_id IN(" . $l . ") ";
234
 
235
  $sqlQuery .= " GROUP BY date ORDER BY date ";
236
 
237
+ $cdates = $wpdb->get_results($sqlQuery, OBJECT_K);
238
+
239
+ foreach( $dates as $day => &$date )
240
  {
241
+ if(!empty($cdates) && !empty($cdates[$day]))
242
+ $date->cancellations = $cdates[$day]->cancellations;
243
  else
244
  $date->cancellations = 0;
245
  }
adminpages/reports/sales.php CHANGED
@@ -132,7 +132,7 @@ function pmpro_report_sales_page()
132
  $gateway_environment = pmpro_getOption("gateway_environment");
133
 
134
  //get data
135
- $sqlQuery = "SELECT $date_function(timestamp) as date, $type_function(total) as value FROM $wpdb->pmpro_membership_orders WHERE timestamp >= '" . $startdate . "' AND status NOT IN('refunded', 'review', 'token', 'error') AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
136
 
137
  if(!empty($enddate))
138
  $sqlQuery .= "AND timestamp < '" . $enddate . "' ";
@@ -327,7 +327,7 @@ function pmpro_getSales($period, $levels = NULL)
327
  if(!empty($cache) && !empty($cache[$period]) && !empty($cache[$period][$levels]))
328
  return $cache[$period][$levels];
329
 
330
- //a sale is an order with status NOT IN('refunded', 'review', 'token', 'error')
331
  if($period == "today")
332
  $startdate = date("Y-m-d", current_time('timestamp'));
333
  elseif($period == "this month")
@@ -341,7 +341,7 @@ function pmpro_getSales($period, $levels = NULL)
341
 
342
  //build query
343
  global $wpdb;
344
- $sqlQuery = "SELECT COUNT(*) FROM $wpdb->pmpro_membership_orders WHERE status NOT IN('refunded', 'review', 'token', 'error') AND timestamp >= '" . $startdate . "' AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
345
 
346
  //restrict by level
347
  if(!empty($levels))
132
  $gateway_environment = pmpro_getOption("gateway_environment");
133
 
134
  //get data
135
+ $sqlQuery = "SELECT $date_function(timestamp) as date, $type_function(total) as value FROM $wpdb->pmpro_membership_orders WHERE total > 0 AND timestamp >= '" . $startdate . "' AND status NOT IN('refunded', 'review', 'token', 'error') AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
136
 
137
  if(!empty($enddate))
138
  $sqlQuery .= "AND timestamp < '" . $enddate . "' ";
327
  if(!empty($cache) && !empty($cache[$period]) && !empty($cache[$period][$levels]))
328
  return $cache[$period][$levels];
329
 
330
+ //a sale is an order with status NOT IN('refunded', 'review', 'token', 'error') with a total > 0
331
  if($period == "today")
332
  $startdate = date("Y-m-d", current_time('timestamp'));
333
  elseif($period == "this month")
341
 
342
  //build query
343
  global $wpdb;
344
+ $sqlQuery = "SELECT COUNT(*) FROM $wpdb->pmpro_membership_orders WHERE total > 0 AND status NOT IN('refunded', 'review', 'token', 'error') AND timestamp >= '" . $startdate . "' AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
345
 
346
  //restrict by level
347
  if(!empty($levels))
adminpages/updates.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //only admins can get this
3
+ if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_updates")))
4
+ {
5
+ die(__("You do not have permissions to perform this action.", "pmpro"));
6
+ }
7
+
8
+ require_once(dirname(__FILE__) . "/admin_header.php");
9
+ ?>
10
+
11
+ <h2><?php _e('Updating Paid Memberships Pro', 'pmpro');?></h2>
12
+
13
+ <?php
14
+ $updates = get_option('pmpro_updates', array());
15
+ if(!empty($updates)) {
16
+ //let's process the first one
17
+ ?>
18
+ <p id="pmpro_updates_intro"><?php _e('Updates are processing. This may take a few minutes to complete.', 'pmpro');?></p>
19
+ <textarea id="pmpro_updates_status" rows="10" cols="60">Loading...</textarea>
20
+
21
+ <?php
22
+ } else {
23
+ ?><p><?php _e('Update complete.');?></p><?php
24
+ }
25
+ ?>
26
+
27
+ <?php
28
+ require_once(dirname(__FILE__) . "/admin_footer.php");
29
+ ?>
classes/class.memberorder.php CHANGED
@@ -4,7 +4,7 @@
4
  /**
5
  * Constructor
6
  */
7
- function MemberOrder($id = NULL)
8
  {
9
  //set up the gateway
10
  $this->setGateway(pmpro_getOption("gateway"));
@@ -18,11 +18,56 @@
18
  return $this->getMemberOrderByCode($id);
19
  }
20
  else
21
- return true; //blank constructor
22
  }
23
 
24
  /**
25
- * Retrieve a member ordr from the DB by ID
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  */
27
  function getMemberOrderByID($id)
28
  {
@@ -458,6 +503,13 @@
458
  if(empty($this->gateway_environment))
459
  $this->gateway_environment = pmpro_getOption("gateway_environment");
460
 
 
 
 
 
 
 
 
461
  if(empty($this->notes))
462
  $this->notes = "";
463
 
@@ -497,6 +549,7 @@
497
  `gateway_environment` = '" . $this->gateway_environment . "',
498
  `payment_transaction_id` = '" . esc_sql($this->payment_transaction_id) . "',
499
  `subscription_transaction_id` = '" . esc_sql($this->subscription_transaction_id) . "',
 
500
  `affiliate_id` = '" . esc_sql($this->affiliate_id) . "',
501
  `affiliate_subid` = '" . esc_sql($this->affiliate_subid) . "',
502
  `notes` = '" . esc_sql($this->notes) . "'
@@ -539,7 +592,7 @@
539
  '" . $this->gateway_environment . "',
540
  '" . esc_sql($this->payment_transaction_id) . "',
541
  '" . esc_sql($this->subscription_transaction_id) . "',
542
- '" . current_time('mysql') . "',
543
  '" . esc_sql($this->affiliate_id) . "',
544
  '" . esc_sql($this->affiliate_subid) . "',
545
  '" . esc_sql($this->notes) . "'
4
  /**
5
  * Constructor
6
  */
7
+ function __construct($id = NULL)
8
  {
9
  //set up the gateway
10
  $this->setGateway(pmpro_getOption("gateway"));
18
  return $this->getMemberOrderByCode($id);
19
  }
20
  else
21
+ return $this->getEmptyMemberOrder(); //blank constructor
22
  }
23
 
24
  /**
25
+ * Returns an empty (but complete) order object.
26
+ *
27
+ * @return stdClass $order - a 'clean' order object
28
+ *
29
+ * @since: 1.8.6.8
30
+ */
31
+ function getEmptyMemberOrder()
32
+ {
33
+
34
+ //defaults
35
+ $order = new stdClass();
36
+ $order->code = $this->getRandomCode();
37
+ $order->user_id = "";
38
+ $order->membership_id = "";
39
+ $order->subtotal = "";
40
+ $order->tax = "";
41
+ $order->couponamount = "";
42
+ $order->total = "";
43
+ $order->payment_type = "";
44
+ $order->cardtype = "";
45
+ $order->accountnumber = "";
46
+ $order->expirationmonth = "";
47
+ $order->expirationyear = "";
48
+ $order->status = "success";
49
+ $order->gateway = pmpro_getOption("gateway");
50
+ $order->gateway_environment = pmpro_getOption("gateway_environment");
51
+ $order->payment_transaction_id = "";
52
+ $order->subscription_transaction_id = "";
53
+ $order->affiliate_id = "";
54
+ $order->affiliate_subid = "";
55
+ $order->notes = "";
56
+
57
+ $order->billing = new stdClass();
58
+ $order->billing->name = "";
59
+ $order->billing->street = "";
60
+ $order->billing->city = "";
61
+ $order->billing->state = "";
62
+ $order->billing->zip = "";
63
+ $order->billing->country = "";
64
+ $order->billing->phone = "";
65
+
66
+ return $order;
67
+ }
68
+
69
+ /**
70
+ * Retrieve a member order from the DB by ID
71
  */
72
  function getMemberOrderByID($id)
73
  {
503
  if(empty($this->gateway_environment))
504
  $this->gateway_environment = pmpro_getOption("gateway_environment");
505
 
506
+ if(empty($this->datetime) && empty($this->timestamp))
507
+ $this->datetime = date("Y-m-d H:s:i", current_time("timestamp")); //use current time
508
+ elseif(empty($this->datetime) && !empty($this->timestamp) && is_numeric($this->timestamp))
509
+ $this->datetime = date("Y-m-d H:s:i", $this->timestamp); //get datetime from timestamp
510
+ elseif(empty($this->datetime) && !empty($this->timestamp))
511
+ $this->datetime = $this->timestamp; //must have a datetime in it
512
+
513
  if(empty($this->notes))
514
  $this->notes = "";
515
 
549
  `gateway_environment` = '" . $this->gateway_environment . "',
550
  `payment_transaction_id` = '" . esc_sql($this->payment_transaction_id) . "',
551
  `subscription_transaction_id` = '" . esc_sql($this->subscription_transaction_id) . "',
552
+ `timestamp` = '" . esc_sql($this->datetime) . "',
553
  `affiliate_id` = '" . esc_sql($this->affiliate_id) . "',
554
  `affiliate_subid` = '" . esc_sql($this->affiliate_subid) . "',
555
  `notes` = '" . esc_sql($this->notes) . "'
592
  '" . $this->gateway_environment . "',
593
  '" . esc_sql($this->payment_transaction_id) . "',
594
  '" . esc_sql($this->subscription_transaction_id) . "',
595
+ '" . esc_sql($this->datetime) . "',
596
  '" . esc_sql($this->affiliate_id) . "',
597
  '" . esc_sql($this->affiliate_subid) . "',
598
  '" . esc_sql($this->notes) . "'
classes/class.pmproemail.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  class PMProEmail
3
  {
4
- function PMProEmail()
5
  {
6
  $this->email = $this->from = $this->fromname = $this->subject = $this->template = $this->data = $this->body = NULL;
7
  }
@@ -162,12 +162,12 @@
162
  //start and end date
163
  $startdate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(startdate) as startdate FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND membership_id = '" . $old_level_id . "' AND status IN('inactive', 'cancelled', 'admin_cancelled') ORDER BY id DESC");
164
  if(!empty($startdate))
165
- $this->data['startdate'] = date(get_option('date_format'), $startdate);
166
  else
167
  $this->data['startdate'] = "";
168
  $enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) as enddate FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND membership_id = '" . $old_level_id . "' AND status IN('inactive', 'cancelled', 'admin_cancelled') ORDER BY id DESC");
169
  if(!empty($enddate))
170
- $this->data['enddate'] = date(get_option('date_format'), $enddate);
171
  else
172
  $this->data['enddate'] = "";
173
 
@@ -215,7 +215,7 @@
215
  $this->template = "checkout_paid";
216
  $this->data["invoice_id"] = $invoice->code;
217
  $this->data["invoice_total"] = pmpro_formatPrice($invoice->total);
218
- $this->data["invoice_date"] = date(get_option('date_format'), $invoice->timestamp);
219
  $this->data["billing_name"] = $invoice->billing->name;
220
  $this->data["billing_street"] = $invoice->billing->street;
221
  $this->data["billing_city"] = $invoice->billing->city;
@@ -262,7 +262,7 @@
262
 
263
  $enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
264
  if($enddate)
265
- $this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", "pmpro"), date(get_option('date_format'), $enddate)) . "</p>\n";
266
  else
267
  $this->data["membership_expiration"] = "";
268
 
@@ -312,7 +312,7 @@
312
  $this->template = "checkout_paid_admin";
313
  $this->data["invoice_id"] = $invoice->code;
314
  $this->data["invoice_total"] = pmpro_formatPrice($invoice->total);
315
- $this->data["invoice_date"] = date(get_option('date_format'), $invoice->timestamp);
316
  $this->data["billing_name"] = $invoice->billing->name;
317
  $this->data["billing_street"] = $invoice->billing->street;
318
  $this->data["billing_city"] = $invoice->billing->city;
@@ -355,7 +355,7 @@
355
 
356
  $enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
357
  if($enddate)
358
- $this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", "pmpro"), date(get_option('date_format'), $enddate)) . "</p>\n";
359
  else
360
  $this->data["membership_expiration"] = "";
361
 
@@ -372,7 +372,7 @@
372
  return false;
373
 
374
  $this->email = $user->user_email;
375
- $this->subject = sprintf(__("Your billing information has been udpated at %s", "pmpro"), get_option("blogname"));
376
  $this->template = "billing";
377
 
378
  $this->data = array(
@@ -425,7 +425,7 @@
425
  return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
426
 
427
  $this->email = get_bloginfo("admin_email");
428
- $this->subject = sprintf(__("Billing information has been udpated for %s at %s", "pmpro"), $user->user_login, get_option("blogname"));
429
  $this->template = "billing_admin";
430
 
431
  $this->data = array(
@@ -629,7 +629,7 @@
629
  "user_email" => $user->user_email,
630
  "invoice_id" => $invoice->code,
631
  "invoice_total" => pmpro_formatPrice($invoice->total),
632
- "invoice_date" => date(get_option('date_format'), $invoice->timestamp),
633
  "billing_name" => $invoice->billing->name,
634
  "billing_street" => $invoice->billing->street,
635
  "billing_city" => $invoice->billing->city,
@@ -660,7 +660,7 @@
660
 
661
  $enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
662
  if($enddate)
663
- $this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", "pmpro"), date(get_option('date_format'), $enddate)) . "</p>\n";
664
  else
665
  $this->data["membership_expiration"] = "";
666
 
@@ -703,7 +703,7 @@
703
  "cycle_period" => $user->membership_level->cycle_period,
704
  "trial_amount" => pmpro_formatPrice($user->membership_level->trial_amount),
705
  "trial_limit" => $user->membership_level->trial_limit,
706
- "trial_end" => date(get_option('date_format'), strtotime(date("m/d/Y", $user->membership_level->startdate) . " + " . $user->membership_level->trial_limit . " " . $user->membership_level->cycle_period), current_time("timestamp"))
707
  );
708
 
709
  return $this->sendEmail();
@@ -746,7 +746,7 @@
746
  $this->email = $user->user_email;
747
  $this->subject = sprintf(__("Your membership at %s will end soon", "pmpro"), get_option("blogname"));
748
  $this->template = "membership_expiring";
749
- $this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "membership_id" => $user->membership_level->id, "membership_level_name" => $user->membership_level->name, "siteemail" => pmpro_getOption("from_email"), "login_link" => wp_login_url(), "enddate" => date(get_option('date_format'), $user->membership_level->enddate), "display_name" => $user->display_name, "user_email" => $user->user_email);
750
 
751
  return $this->sendEmail();
752
  }
@@ -774,7 +774,7 @@
774
 
775
  if(!empty($user->membership_level->enddate))
776
  {
777
- $this->data["membership_change"] .= ". " . sprintf(__("This membership will expire on %s", "pmpro"), date(get_option('date_format'), $user->membership_level->enddate));
778
  }
779
  elseif(!empty($this->expiration_changed))
780
  {
@@ -812,7 +812,7 @@
812
 
813
  if(!empty($user->membership_level->enddate))
814
  {
815
- $this->data["membership_change"] .= ". " . sprintf(__("This membership will expire on %s", "pmpro"), date(get_option('date_format'), $user->membership_level->enddate));
816
  }
817
  elseif(!empty($this->expiration_changed))
818
  {
1
  <?php
2
  class PMProEmail
3
  {
4
+ function __construct()
5
  {
6
  $this->email = $this->from = $this->fromname = $this->subject = $this->template = $this->data = $this->body = NULL;
7
  }
162
  //start and end date
163
  $startdate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(startdate) as startdate FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND membership_id = '" . $old_level_id . "' AND status IN('inactive', 'cancelled', 'admin_cancelled') ORDER BY id DESC");
164
  if(!empty($startdate))
165
+ $this->data['startdate'] = date_i18n(get_option('date_format'), $startdate);
166
  else
167
  $this->data['startdate'] = "";
168
  $enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) as enddate FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND membership_id = '" . $old_level_id . "' AND status IN('inactive', 'cancelled', 'admin_cancelled') ORDER BY id DESC");
169
  if(!empty($enddate))
170
+ $this->data['enddate'] = date_i18n(get_option('date_format'), $enddate);
171
  else
172
  $this->data['enddate'] = "";
173
 
215
  $this->template = "checkout_paid";
216
  $this->data["invoice_id"] = $invoice->code;
217
  $this->data["invoice_total"] = pmpro_formatPrice($invoice->total);
218
+ $this->data["invoice_date"] = date_i18n(get_option('date_format'), $invoice->timestamp);
219
  $this->data["billing_name"] = $invoice->billing->name;
220
  $this->data["billing_street"] = $invoice->billing->street;
221
  $this->data["billing_city"] = $invoice->billing->city;
262
 
263
  $enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
264
  if($enddate)
265
+ $this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", "pmpro"), date_i18n(get_option('date_format'), $enddate)) . "</p>\n";
266
  else
267
  $this->data["membership_expiration"] = "";
268
 
312
  $this->template = "checkout_paid_admin";
313
  $this->data["invoice_id"] = $invoice->code;
314
  $this->data["invoice_total"] = pmpro_formatPrice($invoice->total);
315
+ $this->data["invoice_date"] = date_i18n(get_option('date_format'), $invoice->timestamp);
316
  $this->data["billing_name"] = $invoice->billing->name;
317
  $this->data["billing_street"] = $invoice->billing->street;
318
  $this->data["billing_city"] = $invoice->billing->city;
355
 
356
  $enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
357
  if($enddate)
358
+ $this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", "pmpro"), date_i18n(get_option('date_format'), $enddate)) . "</p>\n";
359
  else
360
  $this->data["membership_expiration"] = "";
361
 
372
  return false;
373
 
374
  $this->email = $user->user_email;
375
+ $this->subject = sprintf(__("Your billing information has been updated at %s", "pmpro"), get_option("blogname"));
376
  $this->template = "billing";
377
 
378
  $this->data = array(
425
  return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
426
 
427
  $this->email = get_bloginfo("admin_email");
428
+ $this->subject = sprintf(__("Billing information has been updated for %s at %s", "pmpro"), $user->user_login, get_option("blogname"));
429
  $this->template = "billing_admin";
430
 
431
  $this->data = array(
629
  "user_email" => $user->user_email,
630
  "invoice_id" => $invoice->code,
631
  "invoice_total" => pmpro_formatPrice($invoice->total),
632
+ "invoice_date" => date_i18n(get_option('date_format'), $invoice->timestamp),
633
  "billing_name" => $invoice->billing->name,
634
  "billing_street" => $invoice->billing->street,
635
  "billing_city" => $invoice->billing->city,
660
 
661
  $enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
662
  if($enddate)
663
+ $this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", "pmpro"), date_i18n(get_option('date_format'), $enddate)) . "</p>\n";
664
  else
665
  $this->data["membership_expiration"] = "";
666
 
703
  "cycle_period" => $user->membership_level->cycle_period,
704
  "trial_amount" => pmpro_formatPrice($user->membership_level->trial_amount),
705
  "trial_limit" => $user->membership_level->trial_limit,
706
+ "trial_end" => date_i18n(get_option('date_format'), strtotime(date_i18n("m/d/Y", $user->membership_level->startdate) . " + " . $user->membership_level->trial_limit . " " . $user->membership_level->cycle_period), current_time("timestamp"))
707
  );
708
 
709
  return $this->sendEmail();
746
  $this->email = $user->user_email;
747
  $this->subject = sprintf(__("Your membership at %s will end soon", "pmpro"), get_option("blogname"));
748
  $this->template = "membership_expiring";
749
+ $this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "membership_id" => $user->membership_level->id, "membership_level_name" => $user->membership_level->name, "siteemail" => pmpro_getOption("from_email"), "login_link" => wp_login_url(), "enddate" => date_i18n(get_option('date_format'), $user->membership_level->enddate), "display_name" => $user->display_name, "user_email" => $user->user_email);
750
 
751
  return $this->sendEmail();
752
  }
774
 
775
  if(!empty($user->membership_level->enddate))
776
  {
777
+ $this->data["membership_change"] .= ". " . sprintf(__("This membership will expire on %s", "pmpro"), date_i18n(get_option('date_format'), $user->membership_level->enddate));
778
  }
779
  elseif(!empty($this->expiration_changed))
780
  {
812
 
813
  if(!empty($user->membership_level->enddate))
814
  {
815
+ $this->data["membership_change"] .= ". " . sprintf(__("This membership will expire on %s", "pmpro"), date_i18n(get_option('date_format'), $user->membership_level->enddate));
816
  }
817
  elseif(!empty($this->expiration_changed))
818
  {
classes/gateways/class.pmprogateway.php CHANGED
@@ -2,7 +2,7 @@
2
  //require_once(dirname(__FILE__) . "/class.pmprogateway.php");
3
  class PMProGateway
4
  {
5
- function PMProGateway($gateway = NULL)
6
  {
7
  $this->gateway = $gateway;
8
  return $this->gateway;
2
  //require_once(dirname(__FILE__) . "/class.pmprogateway.php");
3
  class PMProGateway
4
  {
5
+ function __construct($gateway = NULL)
6
  {
7
  $this->gateway = $gateway;
8
  return $this->gateway;
classes/gateways/class.pmprogateway_authorizenet.php CHANGED
@@ -7,7 +7,7 @@
7
 
8
  class PMProGateway_authorizenet extends PMProGateway
9
  {
10
- function PMProGateway_authorizenet($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  return $this->gateway;
7
 
8
  class PMProGateway_authorizenet extends PMProGateway
9
  {
10
+ function __construct($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  return $this->gateway;
classes/gateways/class.pmprogateway_braintree.php CHANGED
@@ -7,7 +7,7 @@
7
 
8
  class PMProGateway_braintree extends PMProGateway
9
  {
10
- function PMProGateway_braintree($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  $this->gateway_environment = pmpro_getOption("gateway_environment");
7
 
8
  class PMProGateway_braintree extends PMProGateway
9
  {
10
+ function __construct($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  $this->gateway_environment = pmpro_getOption("gateway_environment");
classes/gateways/class.pmprogateway_check.php CHANGED
@@ -7,7 +7,7 @@
7
 
8
  class PMProGateway_check extends PMProGateway
9
  {
10
- function PMProGateway_check($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  return $this->gateway;
7
 
8
  class PMProGateway_check extends PMProGateway
9
  {
10
+ function __construct($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  return $this->gateway;
classes/gateways/class.pmprogateway_cybersource.php CHANGED
@@ -7,7 +7,7 @@
7
 
8
  class PMProGateway_cybersource extends PMProGateway
9
  {
10
- function PMProGateway_cybersource($gateway = NULL)
11
  {
12
  if(!class_exists("CyberSourceSoapClient"))
13
  require_once(dirname(__FILE__) . "/../../includes/lib/CyberSource/cyber_source_soap_client.php");
7
 
8
  class PMProGateway_cybersource extends PMProGateway
9
  {
10
+ function __construct($gateway = NULL)
11
  {
12
  if(!class_exists("CyberSourceSoapClient"))
13
  require_once(dirname(__FILE__) . "/../../includes/lib/CyberSource/cyber_source_soap_client.php");
classes/gateways/class.pmprogateway_payflowpro.php CHANGED
@@ -7,7 +7,7 @@
7
 
8
  class PMProGateway_payflowpro extends PMProGateway
9
  {
10
- function PMProGateway_payflowpro($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  return $this->gateway;
7
 
8
  class PMProGateway_payflowpro extends PMProGateway
9
  {
10
+ function __construct($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  return $this->gateway;
classes/gateways/class.pmprogateway_paypal.php CHANGED
@@ -7,7 +7,7 @@
7
 
8
  class PMProGateway_paypal extends PMProGateway
9
  {
10
- function PMProGateway_paypal($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  return $this->gateway;
7
 
8
  class PMProGateway_paypal extends PMProGateway
9
  {
10
+ function __construct($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  return $this->gateway;
classes/gateways/class.pmprogateway_paypalexpress.php CHANGED
@@ -7,7 +7,7 @@
7
 
8
  class PMProGateway_paypalexpress extends PMProGateway
9
  {
10
- function PMProGateway_paypalexpress($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  return $this->gateway;
7
 
8
  class PMProGateway_paypalexpress extends PMProGateway
9
  {
10
+ function __construct($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  return $this->gateway;
classes/gateways/class.pmprogateway_paypalstandard.php CHANGED
@@ -7,7 +7,7 @@
7
 
8
  class PMProGateway_paypalstandard extends PMProGateway
9
  {
10
- function PMProGateway_paypalstandard($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  return $this->gateway;
7
 
8
  class PMProGateway_paypalstandard extends PMProGateway
9
  {
10
+ function __construct($gateway = NULL)
11
  {
12
  $this->gateway = $gateway;
13
  return $this->gateway;
classes/gateways/class.pmprogateway_stripe.php CHANGED
@@ -19,11 +19,13 @@
19
  *
20
  * @since 1.4
21
  */
22
- function PMProGateway_stripe($gateway = NULL)
23
  {
24
  $this->gateway = $gateway;
25
  $this->gateway_environment = pmpro_getOption("gateway_environment");
26
 
 
 
27
  $this->loadStripeLibrary();
28
  Stripe::setApiKey(pmpro_getOption("stripe_secretkey"));
29
  Stripe::setAPIVersion("2015-07-13");
@@ -31,6 +33,26 @@
31
  return $this->gateway;
32
  }
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  /**
35
  * Load the Stripe API library.
36
  *
@@ -617,7 +639,7 @@
617
  <option value="payment" <?php selected($update['when'], "payment");?>>After Next Payment</option>
618
  <option value="date" <?php selected($update['when'], "date");?>>On Date</option>
619
  </select>
620
- <span class="updates_date" <?php if($uwhen != "date") { ?>style="display: none;"<?php } ?>>
621
  <select name="updates_date_month[]">
622
  <?php
623
  for($i = 1; $i < 13; $i++)
@@ -633,7 +655,7 @@
633
  <input name="updates_date_day[]" type="text" size="2" value="<?php if(!empty($update['date_day'])) echo esc_attr($update['date_day']);?>" />
634
  <input name="updates_date_year[]" type="text" size="4" value="<?php if(!empty($update['date_year'])) echo esc_attr($update['date_year']);?>" />
635
  </span>
636
- <span class="updates_billing" <?php if($uwhen == "no") { ?>style="display: none;"<?php } ?>>
637
  <?php echo $pmpro_currency_symbol?><input name="updates_billing_amount[]" type="text" size="10" value="<?php echo esc_attr($update['billing_amount']);?>" />
638
  <small><?php _e('per', 'pmpro');?></small>
639
  <input name="updates_cycle_number[]" type="text" size="5" value="<?php echo esc_attr($update['cycle_number']);?>" />
19
  *
20
  * @since 1.4
21
  */
22
+ function __construct($gateway = NULL)
23
  {
24
  $this->gateway = $gateway;
25
  $this->gateway_environment = pmpro_getOption("gateway_environment");
26
 
27
+ $this->dependencies();
28
+
29
  $this->loadStripeLibrary();
30
  Stripe::setApiKey(pmpro_getOption("stripe_secretkey"));
31
  Stripe::setAPIVersion("2015-07-13");
33
  return $this->gateway;
34
  }
35
 
36
+ /**
37
+ * Warn if required extensions aren't loaded.
38
+ *
39
+ * @since 1.8.6.8.1
40
+ */
41
+ public function dependencies()
42
+ {
43
+ global $msg, $msgt, $pmpro_stripe_error;
44
+
45
+ $modules = array('curl');
46
+
47
+ foreach($modules as $module){
48
+ if(!extension_loaded($module)){
49
+ $pmpro_stripe_error = true;
50
+ $msg = -1;
51
+ $msgt = sprintf(__("The %s gateway depends on the %s PHP extension. Please enable it, or ask your hosting provider to enable it", "pmpro"), $this->gateway, $module);
52
+ }
53
+ }
54
+ }
55
+
56
  /**
57
  * Load the Stripe API library.
58
  *
639
  <option value="payment" <?php selected($update['when'], "payment");?>>After Next Payment</option>
640
  <option value="date" <?php selected($update['when'], "date");?>>On Date</option>
641
  </select>
642
+ <span class="updates_date" <?php if($update['when'] != "date") { ?>style="display: none;"<?php } ?>>
643
  <select name="updates_date_month[]">
644
  <?php
645
  for($i = 1; $i < 13; $i++)
655
  <input name="updates_date_day[]" type="text" size="2" value="<?php if(!empty($update['date_day'])) echo esc_attr($update['date_day']);?>" />
656
  <input name="updates_date_year[]" type="text" size="4" value="<?php if(!empty($update['date_year'])) echo esc_attr($update['date_year']);?>" />
657
  </span>
658
+ <span class="updates_billing" <?php if($update['when'] == "now") { ?>style="display: none;"<?php } ?>>
659
  <?php echo $pmpro_currency_symbol?><input name="updates_billing_amount[]" type="text" size="10" value="<?php echo esc_attr($update['billing_amount']);?>" />
660
  <small><?php _e('per', 'pmpro');?></small>
661
  <input name="updates_cycle_number[]" type="text" size="5" value="<?php echo esc_attr($update['cycle_number']);?>" />
classes/gateways/class.pmprogateway_twocheckout.php CHANGED
@@ -7,7 +7,7 @@
7
 
8
  class PMProGateway_Twocheckout extends PMProGateway
9
  {
10
- function PMProGateway_Twocheckout($gateway = NULL)
11
  {
12
  if(!class_exists("Twocheckout"))
13
  require_once(dirname(__FILE__) . "/../../includes/lib/Twocheckout/Twocheckout.php");
7
 
8
  class PMProGateway_Twocheckout extends PMProGateway
9
  {
10
+ function __construct($gateway = NULL)
11
  {
12
  if(!class_exists("Twocheckout"))
13
  require_once(dirname(__FILE__) . "/../../includes/lib/Twocheckout/Twocheckout.php");
css/frontend.css CHANGED
@@ -2,194 +2,429 @@
2
  Buttons
3
  ---------------------------------------*/
4
  .pmpro_btn, .pmpro_btn:link, .pmpro_content_message a, .pmpro_content_message a:link {
5
- display: inline-block;
6
  background-color: #EFEFEF;
7
  background-image: none;
8
  border: 1px solid #D6D6D6;
9
  -webkit-border-radius: 4px;
10
- -moz-border-radius: 4px;
11
- border-radius: 4px;
12
- padding: 6px 12px;
13
- margin: 0;
14
  color: #444;
 
 
15
  font-size: 12px;
16
  font-weight: 700;
17
- text-transform: none;
18
- text-decoration: none;
19
  text-align: center;
20
- white-space: nowrap;
21
- vertical-align: middle;
22
- cursor: pointer;
23
  -webkit-user-select: none;
24
- -moz-user-select: none;
25
- -ms-user-select: none;
26
- -o-user-select: none;
27
- user-select: none;
 
 
28
  }
29
-
30
  .pmpro_btn:focus, .pmpro_content_message a:focus {
31
- outline: thin dotted;
32
- outline: 5px auto -webkit-focus-ring-color;
33
- outline-offset: -2px;
34
  }
35
-
36
  .pmpro_btn:hover, .pmpro_btn:focus, .pmpro_content_message a:focus, .pmpro_content_message a:hover {
37
- color: #000;
38
- background-color: #FAFAFA;
39
- text-decoration: none;
40
  }
41
-
42
  .pmpro_btn:active,
43
  .pmpro_btn.active {
44
- background-image: none;
45
- outline: 0;
46
- -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
47
- box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
48
  }
49
-
50
  .pmpro_btn.disabled,
51
  .pmpro_btn[disabled],
52
  fieldset[disabled] .pmpro_btn {
53
- pointer-events: none;
54
- cursor: not-allowed;
55
- opacity: 0.65;
56
- filter: alpha(opacity=65);
57
- -webkit-box-shadow: none;
58
- box-shadow: none;
59
- }
60
-
61
- .pmpro_btn.pmpro_cancel, .pmpro_btn.pmpro_cancel:link {background: none; border: none; margin: 0 0 0 10px; }
 
 
 
62
  /*---------------------------------------
63
  Forms
64
  ---------------------------------------*/
65
- form.pmpro_form div {clear: left; margin: .5em 0 1em 0; }
66
- form.pmpro_form label {float: left; margin: 3px 10px 0 0; width: 200px; font-weight: bold; text-align: right; }
67
- form.pmpro_form label.pmpro_normal {float: none; margin: 0 0 0 0; width: auto; font-weight: normal; text-align: auto;}
68
- .pmpro_clickable {cursor: pointer;}
69
- form.pmpro_form .likelabel {font-weight: bold; }
70
- form.pmpro_form .input, form.pmpro_form textarea, form.pmpro_form select {border: 1px solid #AAA; display: inline-block; margin: 0 3px 0 0; padding: 3px; width: auto; max-width: 60%; }
71
- form.pmpro_form textarea {font-family: Arial, Helvetica, sans-serif; font-size: 12px; }
72
- form.pmpro_form select {margin: 2px 0 0 0 ; font-size: 12px;}
73
- form.pmpro_form .lite {color: #666; }
74
- form.pmpro_form .leftmar {margin: 8px 0 0 210px; }
75
-
76
- form.pmpro_form .pmpro_captcha {margin: 0 0 0 210px !important; }
77
- form.pmpro_form .pmpro_captcha div {clear: none; margin: 0; }
78
- form.pmpro_form .pmpro_submit {margin-left: 210px; }
79
- form.pmpro_form .pmpro_submit span {float: left; }
80
- form.pmpro_form #pmpro_processing_message {margin: 5px 0 0 10px; font-style: italic; color: #999; }
81
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  /*--------------------------------------------------
83
  Messages - Success, Error, Alert
84
  ----------------------------------------------------*/
85
- .pmpro_message {background-color: #d9edf7; margin: .5em 0; padding: 10px 15px; color: #31708f; font-size: 14px; font-weight: 400; line-height: 1.5em; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; border: 1px solid #bce8f1; }
86
-
87
- .pmpro_success {background-color: #dff0d8; color: #3c763d; border-color: #d6e9c6; }
88
- .pmpro_error {background-color: #f2dede; color: #a94442; border-color: #ebccd1; }
89
- .pmpro_alert {background-color: #fcf8e3; color: #8a6d3b; border-color: #faebcc;}
90
-
91
- .pmpro_content_message a {margin: 5px 5px 0 0; }
92
-
93
- .pmpro_message a {color: #245269; text-decoration: underline; }
94
- .pmpro_success a {color: #2b542c; }
95
- .pmpro_error a {color: #843534; }
96
- .pmpro_alert a {color: #66512c; }
97
-
98
- input.pmpro_error {background-image: none;}
99
- select.pmpro_error {background-image: none;}
100
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  /*---------------------------------------
102
  Membership Checkout
103
  ---------------------------------------*/
104
- .pmpro_checkout thead th {font-weight: bold; color: #444; padding: 10px; }
105
- .pmpro_checkout tbody td {padding: 10px; }
106
- .pmpro_checkout tr.odd td {background: rgba(125,125,125,.1); }
107
- .pmpro_checkout tr.selected td {background: #FFC; }
108
- .pmpro_checkout tr.active td {background: #FFC; }
109
- .pmpro_checkout .name {font-weight: bold; }
110
- .pmpro_checkout ul {margin: 5px 0 0 20px; padding: 0; font-size: .8em; color: #444; }
111
-
112
- .pmpro_checkout tfoot td {padding: 10px; color: #444; }
113
- .pmpro_checkout .topfoot td {border-top: 2px solid #CCC;}
114
- .pmpro_checkout .total td {border-top: 1px solid #CCC; font-size: 1.2em; font-weight: bold; padding-bottom: 30px;}
115
- .pmpro_checkout tfoot .entercode td {background: #EEE; }
116
-
117
- .pmpro_checkout td.rtbdr {border-right: 1px solid #CCC; }
118
-
119
- .pmpro_checkout select {font-size: 11px; }
120
-
121
- .pmpro_thead-name {float: left; width: 55%; }
122
- .pmpro_thead-msg {float: right; font-size: .9em; font-style: italic; font-weight: normal; text-align: right; width: 45%; }
123
-
124
- .pmpro_ordersummary {float: right; }
125
-
126
- #pmpro_license { background: #FFF; padding: 5px; border: 1px solid #CCC; height: 200px; margin: 3px; color: #666; overflow: auto; }
127
-
128
- .pmpro_sslseal {float: right; clear: none !important; margin: 0 !important; }
129
-
130
- a.pmpro_radio {text-decoration: none; color: #000;}
131
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  /*---------------------------------------
133
  Membership Invoice
134
  ---------------------------------------*/
135
  .pmpro_invoice { }
136
-
137
-
138
  /*---------------------------------------
139
  Membership Account
140
  ---------------------------------------*/
141
- #pmpro_account .pmpro_box {border-top: 1px solid #CCC; padding: 1em 0; margin: 1em 0; }
142
- #pmpro_account .pmpro_box h3 {margin: 0; padding: 0; border: none; background: none; }
143
- #pmpro_account .pmpro_box p {margin: .5em 0 0 0; padding: 0; }
144
- #pmpro_account .pmpro_box ul {margin-bottom: 0; }
145
-
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  #pmpro_account #pmpro_account-membership { }
147
  #pmpro_account #pmpro_account-profile { }
148
  #pmpro_account #pmpro_account-billing { }
149
  #pmpro_account #pmpro_account-invoices { }
150
  #pmpro_account #pmpro_account-links { }
151
-
152
- .pmpro_actionlinks {font-size: .8em; margin: .25em 0 0 0; }
153
- .pmpro_actionlinks a {display: inline-block; padding: 0 5px 0 0; margin: 0; text-decoration: none; }
154
- .pmpro_actionlinks a:last-child {padding: 0; }
155
- .pmpro_hidden {display: none;}
156
- li.pmpro_more {list-style-type: none; text-align: center; margin-left: -20px; padding-left: 0;}
157
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  /*---------------------------------------
159
  Membership Levels
160
  ---------------------------------------*/
161
- #pmpro_levels_table {background: #FFF; }
162
- #pmpro_levels_table .pmpro_btn {display: block; }
163
-
 
 
 
164
  /*---------------------------------------
165
  Misc
166
  ---------------------------------------*/
167
- .pmpro_a-right {float: right; width: auto; text-align: right; text-decoration: underline; font-size: 11px; }
168
- .pmpro_a-print {float: right; width: auto; text-decoration: none; color: #345395; background: url(../images/printer.gif) top left no-repeat; padding: 0px 0px 2px 20px; font-size: 11px; line-height: 16px; cursor: pointer; }
169
-
170
- .pmpro_red {color: #CC0000; }
171
- .pmpro_grey {color: #999; }
172
-
173
- .top1em {margin-top: 1em;}
174
- .bot1em {margin-bottom: 1em;}
175
- .bot0em {margin-bottom: 0em;}
176
- .clear {clear: both; }
177
-
178
- .pmpro_small {font-size: .8em;}
179
-
180
- @media (max-width:768px){
181
- #pmpro_levels_table {border: none; }
182
- #pmpro_levels_table th {display: none; }
183
- #pmpro_levels_table td {border: none; display: block; padding: 0 10px; text-align: center; }
184
- #pmpro_levels_table td:first-child {font-size: 1.4em; padding-top: 10px; }
185
- #pmpro_levels_table td:last-child {padding-bottom: 10px; padding-top: 10px; }
186
- form.pmpro_form label {display: block; margin: 0; text-align: left; width: 100%; }
187
- form.pmpro_form label.pmpro_normal, #pmpro_tos_fields label {display: inline-block; }
188
- form.pmpro_form input[type=text].input, form.pmpro_form input[type=password].input {width: 90%; }
189
- form.pmpro_form input[type=text]#other_discount_code, form.pmpro_form input[type=text]#CVV, form.pmpro_form input[type=text]#discount_code {width: 40%; }
190
- form.pmpro_form #pmpro_payment_information_fields .pmpro_thead-msg {float: none; margin-bottom: 10px; text-align: left; text-wrap: normal; white-space: normal; }
191
- form.pmpro_form .leftmar {margin: 2px 0 0 0; }
192
- form.pmpro_form .pmpro_submit {margin-left: 0; }
193
- form.pmpro_form .pmpro_submit #pmpro_submit_span {display: block; float: none; }
194
- form.pmpro_form .pmpro_btn {display: block; width: 100%; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  }
2
  Buttons
3
  ---------------------------------------*/
4
  .pmpro_btn, .pmpro_btn:link, .pmpro_content_message a, .pmpro_content_message a:link {
 
5
  background-color: #EFEFEF;
6
  background-image: none;
7
  border: 1px solid #D6D6D6;
8
  -webkit-border-radius: 4px;
9
+ -moz-border-radius: 4px;
10
+ border-radius: 4px;
 
 
11
  color: #444;
12
+ cursor: pointer;
13
+ display: inline-block;
14
  font-size: 12px;
15
  font-weight: 700;
16
+ margin: 0;
17
+ padding: 6px 12px;
18
  text-align: center;
19
+ text-decoration: none;
20
+ text-transform: none;
 
21
  -webkit-user-select: none;
22
+ -moz-user-select: none;
23
+ -ms-user-select: none;
24
+ -o-user-select: none;
25
+ user-select: none;
26
+ vertical-align: middle;
27
+ white-space: nowrap;
28
  }
 
29
  .pmpro_btn:focus, .pmpro_content_message a:focus {
30
+ outline: thin dotted;
31
+ outline: 5px auto -webkit-focus-ring-color;
32
+ outline-offset: -2px;
33
  }
 
34
  .pmpro_btn:hover, .pmpro_btn:focus, .pmpro_content_message a:focus, .pmpro_content_message a:hover {
35
+ background-color: #FAFAFA;
36
+ color: #000;
37
+ text-decoration: none;
38
  }
 
39
  .pmpro_btn:active,
40
  .pmpro_btn.active {
41
+ background-image: none;
42
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
43
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
44
+ outline: 0;
45
  }
 
46
  .pmpro_btn.disabled,
47
  .pmpro_btn[disabled],
48
  fieldset[disabled] .pmpro_btn {
49
+ -webkit-box-shadow: none;
50
+ box-shadow: none;
51
+ cursor: not-allowed;
52
+ filter: alpha(opacity=65);
53
+ opacity: 0.65;
54
+ pointer-events: none;
55
+ }
56
+ .pmpro_btn.pmpro_cancel, .pmpro_btn.pmpro_cancel:link {
57
+ background: none;
58
+ border: none;
59
+ margin: 0 0 0 10px;
60
+ }
61
  /*---------------------------------------
62
  Forms
63
  ---------------------------------------*/
64
+ form.pmpro_form div {
65
+ clear: left;
66
+ margin: .5em 0 1em 0;
67
+ }
68
+ form.pmpro_form label {
69
+ float: left;
70
+ font-weight: bold;
71
+ margin: 3px 10px 0 0;
72
+ text-align: right;
73
+ width: 200px;
74
+ }
75
+ form.pmpro_form label.pmpro_normal {
76
+ display: inline-block;
77
+ float: none;
78
+ font-weight: normal;
79
+ margin: 0 0 0 0;
80
+ text-align: auto;
81
+ width: auto;
82
+ }
83
+ form.pmpro_form input[type=checkbox]#tos {
84
+ display: inline-block;
85
+ width: auto;
86
+ }
87
+ .pmpro_clickable {
88
+ cursor: pointer;
89
+ }
90
+ form.pmpro_form .likelabel {
91
+ font-weight: bold;
92
+ }
93
+ form.pmpro_form .input, form.pmpro_form textarea, form.pmpro_form select {
94
+ border: 1px solid #AAA;
95
+ display: inline-block;
96
+ margin: 0 3px 0 0;
97
+ max-width: 60%;
98
+ padding: 3px;
99
+ width: auto;
100
+ }
101
+ form.pmpro_form textarea {
102
+ font-family: Arial, Helvetica, sans-serif;
103
+ font-size: 12px;
104
+ }
105
+ form.pmpro_form select {
106
+ font-size: 12px;
107
+ margin: 2px 0 0 0;
108
+ }
109
+ form.pmpro_form .lite {
110
+ color: #666;
111
+ }
112
+ form.pmpro_form .leftmar {
113
+ margin: 8px 0 0 210px;
114
+ }
115
+ form.pmpro_form .pmpro_captcha {
116
+ margin: 0 0 0 210px !important;
117
+ }
118
+ form.pmpro_form .pmpro_captcha div {
119
+ clear: none;
120
+ margin: 0;
121
+ }
122
+ form.pmpro_form .pmpro_submit {
123
+ margin-left: 210px;
124
+ }
125
+ form.pmpro_form .pmpro_submit span {
126
+ float: left;
127
+ }
128
+ form.pmpro_form #pmpro_processing_message {
129
+ color: #999;
130
+ font-style: italic;
131
+ margin: 5px 0 0 10px;
132
+ }
133
  /*--------------------------------------------------
134
  Messages - Success, Error, Alert
135
  ----------------------------------------------------*/
136
+ .pmpro_message {
137
+ background-color: #d9edf7;
138
+ border: 1px solid #bce8f1;
139
+ -webkit-border-radius: 4px;
140
+ -moz-border-radius: 4px;
141
+ border-radius: 4px;
142
+ color: #31708f;
143
+ font-size: 14px;
144
+ font-weight: 400;
145
+ line-height: 1.5em;
146
+ margin: .5em 0;
147
+ padding: 10px 15px;
148
+ }
149
+ .pmpro_success {
150
+ background-color: #dff0d8;
151
+ border-color: #d6e9c6;
152
+ color: #3c763d;
153
+ }
154
+ .pmpro_error {
155
+ background-color: #f2dede;
156
+ border-color: #ebccd1;
157
+ color: #a94442;
158
+ }
159
+ .pmpro_alert {
160
+ background-color: #fcf8e3;
161
+ border-color: #faebcc;
162
+ color: #8a6d3b;
163
+ }
164
+ .pmpro_content_message a {
165
+ margin: 5px 5px 0 0;
166
+ }
167
+ .pmpro_message a {
168
+ color: #245269;
169
+ text-decoration: underline;
170
+ }
171
+ .pmpro_success a {
172
+ color: #2b542c;
173
+ }
174
+ .pmpro_error a {
175
+ color: #843534;
176
+ }
177
+ .pmpro_alert a {
178
+ color: #66512c;
179
+ }
180
+ input.pmpro_error {
181
+ background-image: none;
182
+ }
183
+ select.pmpro_error {
184
+ background-image: none;
185
+ }
186
  /*---------------------------------------
187
  Membership Checkout
188
  ---------------------------------------*/
189
+ .pmpro_checkout thead th {
190
+ color: #444;
191
+ font-weight: bold;
192
+ padding: 10px;
193
+ }
194
+ .pmpro_checkout tbody td {
195
+ padding: 10px;
196
+ }
197
+ .pmpro_checkout tr.odd td {
198
+ background: rgba(125,125,125,.1);
199
+ }
200
+ .pmpro_checkout tr.selected td {
201
+ background: #FFC;
202
+ }
203
+ .pmpro_checkout tr.active td {
204
+ background: #FFC;
205
+ }
206
+ .pmpro_checkout .name {
207
+ font-weight: bold;
208
+ }
209
+ .pmpro_checkout ul {
210
+ color: #444;
211
+ font-size: .8em;
212
+ margin: 5px 0 0 20px;
213
+ padding: 0;
214
+ }
215
+ .pmpro_checkout tfoot td {
216
+ color: #444;
217
+ padding: 10px;
218
+ }
219
+ .pmpro_checkout .topfoot td {
220
+ border-top: 2px solid #CCC;
221
+ }
222
+ .pmpro_checkout .total td {
223
+ border-top: 1px solid #CCC;
224
+ font-size: 1.2em;
225
+ font-weight: bold;
226
+ padding-bottom: 30px;
227
+ }
228
+ .pmpro_checkout tfoot .entercode td {
229
+ background: #EEE;
230
+ }
231
+ .pmpro_checkout td.rtbdr {
232
+ border-right: 1px solid #CCC;
233
+ }
234
+ .pmpro_checkout select {
235
+ font-size: 11px;
236
+ }
237
+ .pmpro_thead-name {
238
+ float: left;
239
+ width: 55%;
240
+ }
241
+ .pmpro_thead-msg {
242
+ float: right;
243
+ font-size: .9em;
244
+ font-style: italic;
245
+ font-weight: normal;
246
+ text-align: right;
247
+ width: 45%;
248
+ }
249
+ .pmpro_ordersummary {
250
+ float: right;
251
+ }
252
+ #pmpro_license {
253
+ background: #FFF;
254
+ border: 1px solid #CCC;
255
+ color: #666;
256
+ height: 200px;
257
+ margin: 3px;
258
+ overflow: auto;
259
+ padding: 5px;
260
+ }
261
+ .pmpro_sslseal {
262
+ clear: none !important;
263
+ float: right;
264
+ margin: 0 !important;
265
+ }
266
+ a.pmpro_radio {
267
+ color: #000;
268
+ text-decoration: none;
269
+ }
270
  /*---------------------------------------
271
  Membership Invoice
272
  ---------------------------------------*/
273
  .pmpro_invoice { }
 
 
274
  /*---------------------------------------
275
  Membership Account
276
  ---------------------------------------*/
277
+ #pmpro_account .pmpro_box {
278
+ border-top: 1px solid #CCC;
279
+ margin: 1em 0;
280
+ padding: 1em 0;
281
+ }
282
+ #pmpro_account .pmpro_box h3 {
283
+ background: none;
284
+ border: none;
285
+ margin: 0;
286
+ padding: 0;
287
+ }
288
+ #pmpro_account .pmpro_box p {
289
+ margin: .5em 0 0 0;
290
+ padding: 0;
291
+ }
292
+ #pmpro_account .pmpro_box ul {
293
+ margin-bottom: 0;
294
+ }
295
  #pmpro_account #pmpro_account-membership { }
296
  #pmpro_account #pmpro_account-profile { }
297
  #pmpro_account #pmpro_account-billing { }
298
  #pmpro_account #pmpro_account-invoices { }
299
  #pmpro_account #pmpro_account-links { }
300
+ .pmpro_actionlinks {
301
+ font-size: .8em;
302
+ margin: .25em 0 0 0;
303
+ }
304
+ .pmpro_actionlinks a {
305
+ display: inline-block;
306
+ margin: 0;
307
+ padding: 0 5px 0 0;
308
+ text-decoration: none;
309
+ }
310
+ .pmpro_actionlinks a:last-child {
311
+ padding: 0;
312
+ }
313
+ .pmpro_hidden {
314
+ display: none;
315
+ }
316
+ li.pmpro_more {
317
+ list-style-type: none;
318
+ margin-left: -20px;
319
+ padding-left: 0;
320
+ text-align: center;
321
+ }
322
  /*---------------------------------------
323
  Membership Levels
324
  ---------------------------------------*/
325
+ #pmpro_levels_table {
326
+ background: #FFF;
327
+ }
328
+ #pmpro_levels_table .pmpro_btn {
329
+ display: block;
330
+ }
331
  /*---------------------------------------
332
  Misc
333
  ---------------------------------------*/
334
+ .pmpro_a-right {
335
+ float: right;
336
+ font-size: 11px;
337
+ text-align: right;
338
+ text-decoration: underline;
339
+ width: auto;
340
+ }
341
+ .pmpro_a-print {
342
+ background: url(../images/printer.gif) top left no-repeat;
343
+ color: #345395;
344
+ cursor: pointer;
345
+ float: right;
346
+ font-size: 11px;
347
+ line-height: 16px;
348
+ padding: 0px 0px 2px 20px;
349
+ text-decoration: none;
350
+ width: auto;
351
+ }
352
+ .pmpro_red {
353
+ color: #CC0000;
354
+ }
355
+ .pmpro_grey {
356
+ color: #999;
357
+ }
358
+ .top1em {
359
+ margin-top: 1em;
360
+ }
361
+ .bot1em {
362
+ margin-bottom: 1em;
363
+ }
364
+ .bot0em {
365
+ margin-bottom: 0em;
366
+ }
367
+ .clear {
368
+ clear: both;
369
+ }
370
+ .pmpro_small {
371
+ font-size: .8em;
372
+ }
373
+ @media (max-width:768px) {
374
+ #pmpro_levels_table {
375
+ border: none;
376
+ }
377
+ #pmpro_levels_table th {
378
+ display: none;
379
+ }
380
+ #pmpro_levels_table td {
381
+ border: none;
382
+ display: block;
383
+ padding: 0 10px;
384
+ text-align: center;
385
+ }
386
+ #pmpro_levels_table td:first-child {
387
+ font-size: 1.4em;
388
+ padding-top: 10px;
389
+ }
390
+ #pmpro_levels_table td:last-child {
391
+ padding-bottom: 10px;
392
+ padding-top: 10px;
393
+ }
394
+ form.pmpro_form label {
395
+ display: block;
396
+ margin: 0;
397
+ text-align: left;
398
+ width: 100%;
399
+ }
400
+ form.pmpro_form label.pmpro_normal, #pmpro_tos_fields label {
401
+ display: inline-block;
402
+ }
403
+ form.pmpro_form input[type=text].input, form.pmpro_form input[type=password].input {
404
+ width: 90%;
405
+ }
406
+ form.pmpro_form input[type=text]#other_discount_code, form.pmpro_form input[type=text]#CVV, form.pmpro_form input[type=text]#discount_code {
407
+ width: 40%;
408
+ }
409
+ form.pmpro_form #pmpro_payment_information_fields .pmpro_thead-msg {
410
+ float: none;
411
+ margin-bottom: 10px;
412
+ text-align: left;
413
+ text-wrap: normal;
414
+ white-space: normal;
415
+ }
416
+ form.pmpro_form .leftmar {
417
+ margin: 2px 0 0 0;
418
+ }
419
+ form.pmpro_form .pmpro_submit {
420
+ margin-left: 0;
421
+ }
422
+ form.pmpro_form .pmpro_submit #pmpro_submit_span {
423
+ display: block;
424
+ float: none;
425
+ }
426
+ form.pmpro_form .pmpro_btn {
427
+ display: block;
428
+ width: 100%;
429
+ }
430
  }
includes/adminpages.php CHANGED
@@ -15,7 +15,8 @@ function pmpro_getPMProCaps()
15
  'pmpro_memberslist',
16
  'pmpro_reports',
17
  'pmpro_orders',
18
- 'pmpro_discountcodes'
 
19
  );
20
 
21
  return $pmpro_caps;
@@ -54,7 +55,11 @@ function pmpro_add_pages()
54
  add_submenu_page('pmpro-membershiplevels', __('Reports', 'pmpro'), __('Reports', 'pmpro'), 'pmpro_reports', 'pmpro-reports', 'pmpro_reports');
55
  add_submenu_page('pmpro-membershiplevels', __('Orders', 'pmpro'), __('Orders', 'pmpro'), 'pmpro_orders', 'pmpro-orders', 'pmpro_orders');
56
  add_submenu_page('pmpro-membershiplevels', __('Discount Codes', 'pmpro'), __('Discount Codes', 'pmpro'), 'pmpro_discountcodes', 'pmpro-discountcodes', 'pmpro_discountcodes');
57
-
 
 
 
 
58
  //rename the automatically added Memberships submenu item
59
  global $submenu;
60
  if(!empty($submenu['pmpro-membershiplevels']))
@@ -229,6 +234,10 @@ function pmpro_orders()
229
  require_once(PMPRO_DIR . "/adminpages/orders.php");
230
  }
231
 
 
 
 
 
232
 
233
  /*
234
  Function to add links to the plugin action links
15
  'pmpro_memberslist',
16
  'pmpro_reports',
17
  'pmpro_orders',
18
+ 'pmpro_discountcodes',
19
+ 'pmpro_updates'
20
  );
21
 
22
  return $pmpro_caps;
55
  add_submenu_page('pmpro-membershiplevels', __('Reports', 'pmpro'), __('Reports', 'pmpro'), 'pmpro_reports', 'pmpro-reports', 'pmpro_reports');
56
  add_submenu_page('pmpro-membershiplevels', __('Orders', 'pmpro'), __('Orders', 'pmpro'), 'pmpro_orders', 'pmpro-orders', 'pmpro_orders');
57
  add_submenu_page('pmpro-membershiplevels', __('Discount Codes', 'pmpro'), __('Discount Codes', 'pmpro'), 'pmpro_discountcodes', 'pmpro-discountcodes', 'pmpro_discountcodes');
58
+
59
+ //updates page only if needed
60
+ if(pmpro_isUpdateRequired())
61
+ add_submenu_page('pmpro-membershiplevels', __('Updates Required', 'pmpro'), __('Updates Required', 'pmpro'), 'pmpro_updates', 'pmpro-updates', 'pmpro_updates');
62
+
63
  //rename the automatically added Memberships submenu item
64
  global $submenu;
65
  if(!empty($submenu['pmpro-membershiplevels']))
234
  require_once(PMPRO_DIR . "/adminpages/orders.php");
235
  }
236
 
237
+ function pmpro_updates()
238
+ {
239
+ require_once(PMPRO_DIR . "/adminpages/updates.php");
240
+ }
241
 
242
  /*
243
  Function to add links to the plugin action links
includes/content.php CHANGED
@@ -15,8 +15,11 @@ function pmpro_has_membership_access($post_id = NULL, $user_id = NULL, $return_m
15
  if(!$post_id)
16
  return true;
17
 
 
 
 
18
  //if no post or current_user object, set them up
19
- if(!empty($post->ID) && $post_id == $post->ID)
20
  $mypost = $post;
21
  else
22
  $mypost = get_post($post_id);
@@ -27,7 +30,7 @@ function pmpro_has_membership_access($post_id = NULL, $user_id = NULL, $return_m
27
  $myuser = get_userdata($user_id);
28
 
29
  //for these post types, we want to check the parent
30
- if($mypost->post_type == "attachment" || $mypost->post_type == "revision")
31
  {
32
  $mypost = get_post($mypost->post_parent);
33
  }
@@ -35,7 +38,7 @@ function pmpro_has_membership_access($post_id = NULL, $user_id = NULL, $return_m
35
  // Allow plugins and themes to find the protected post
36
  $mypost = apply_filters( 'pmpro_membership_access_post', $mypost, $myuser );
37
 
38
- if($mypost->post_type == "post")
39
  {
40
  $post_categories = wp_get_post_categories($mypost->ID);
41
 
@@ -53,7 +56,7 @@ function pmpro_has_membership_access($post_id = NULL, $user_id = NULL, $return_m
53
  else
54
  {
55
  //are any membership levels associated with this page?
56
- $sqlQuery = "SELECT m.id, m.name FROM $wpdb->pmpro_memberships_pages mp LEFT JOIN $wpdb->pmpro_membership_levels m ON mp.membership_id = m.id WHERE mp.page_id = '" . $mypost->ID . "'";
57
  }
58
 
59
 
15
  if(!$post_id)
16
  return true;
17
 
18
+ if (!isset($post->post_type))
19
+ return true;
20
+
21
  //if no post or current_user object, set them up
22
+ if( isset($post->ID) && !empty($post->ID) && $post_id == $post->ID)
23
  $mypost = $post;
24
  else
25
  $mypost = get_post($post_id);
30
  $myuser = get_userdata($user_id);
31
 
32
  //for these post types, we want to check the parent
33
+ if(isset($mypost->post_type) && in_array( $mypost->post_type, array("attachment", "revision")))
34
  {
35
  $mypost = get_post($mypost->post_parent);
36
  }
38
  // Allow plugins and themes to find the protected post
39
  $mypost = apply_filters( 'pmpro_membership_access_post', $mypost, $myuser );
40
 
41
+ if(isset($mypost->post_type) && $mypost->post_type == "post")
42
  {
43
  $post_categories = wp_get_post_categories($mypost->ID);
44
 
56
  else
57
  {
58
  //are any membership levels associated with this page?
59
+ $sqlQuery = "SELECT m.id, m.name FROM $wpdb->pmpro_memberships_pages mp LEFT JOIN $wpdb->pmpro_membership_levels m ON mp.membership_id = m.id WHERE mp.page_id = '" . $post_id . "'";
60
  }
61
 
62
 
includes/currencies.php CHANGED
@@ -25,6 +25,7 @@
25
  'symbol' => '&pound;',
26
  'position' => 'left'
27
  ),
 
28
  'AUD' => __('Australian Dollars (&#36;)', 'pmpro'),
29
  'BRL' => array(
30
  'name' => __('Brazilian Real (R&#36;)', 'pmpro'),
@@ -54,6 +55,7 @@
54
  ),
55
  'MYR' => __('Malaysian Ringgits', 'pmpro'),
56
  'MXN' => __('Mexican Peso (&#36;)', 'pmpro'),
 
57
  'NZD' => __('New Zealand Dollar (&#36;)', 'pmpro'),
58
  'NOK' => __('Norwegian Krone', 'pmpro'),
59
  'PHP' => __('Philippine Pesos', 'pmpro'),
25
  'symbol' => '&pound;',
26
  'position' => 'left'
27
  ),
28
+ 'ARS' => __('Argentine Peso (&#36;)', 'pmpro'),
29
  'AUD' => __('Australian Dollars (&#36;)', 'pmpro'),
30
  'BRL' => array(
31
  'name' => __('Brazilian Real (R&#36;)', 'pmpro'),
55
  ),
56
  'MYR' => __('Malaysian Ringgits', 'pmpro'),
57
  'MXN' => __('Mexican Peso (&#36;)', 'pmpro'),
58
+ 'NGN' => __('Nigerian Naira (&#8358;)', 'pmpro'),
59
  'NZD' => __('New Zealand Dollar (&#36;)', 'pmpro'),
60
  'NOK' => __('Norwegian Krone', 'pmpro'),
61
  'PHP' => __('Philippine Pesos', 'pmpro'),
includes/functions.php CHANGED
@@ -614,7 +614,7 @@ function pmpro_hasMembershipLevel($levels = NULL, $user_id = NULL)
614
  elseif(in_array("E", $levels) || in_array("e", $levels)) {
615
  $sql = "SELECT id FROM $wpdb->pmpro_memberships_users WHERE user_id=$user_id AND status='expired' LIMIT 1";
616
  $expired = $wpdb->get_var($sql);
617
- return !empty($expired);
618
  }
619
  }
620
  else
@@ -1379,7 +1379,7 @@ function pmpro_no_quotes($s, $quotes = array("'", '"'))
1379
  }
1380
 
1381
  //from: http://www.php.net/manual/en/function.implode.php#86845
1382
- function pmpro_implodeToEnglish($array)
1383
  {
1384
  // sanity check
1385
  if (!$array || !count ($array))
@@ -1392,7 +1392,11 @@ function pmpro_implodeToEnglish($array)
1392
  if (!count ($array))
1393
  return $last;
1394
 
1395
- return implode (', ', $array).' ' . __('and', 'pmpro') . ' '.$last;
 
 
 
 
1396
  }
1397
 
1398
  //from yoast wordpress seo
@@ -2176,4 +2180,4 @@ function pmpro_generatePages($pages) {
2176
  }
2177
 
2178
  return $pages_created;
2179
- }
614
  elseif(in_array("E", $levels) || in_array("e", $levels)) {
615
  $sql = "SELECT id FROM $wpdb->pmpro_memberships_users WHERE user_id=$user_id AND status='expired' LIMIT 1";
616
  $expired = $wpdb->get_var($sql);
617
+ $return = !empty($expired);
618
  }
619
  }
620
  else
1379
  }
1380
 
1381
  //from: http://www.php.net/manual/en/function.implode.php#86845
1382
+ function pmpro_implodeToEnglish($array, $conjunction = 'and')
1383
  {
1384
  // sanity check
1385
  if (!$array || !count ($array))
1392
  if (!count ($array))
1393
  return $last;
1394
 
1395
+ //possibly translate the conjunction
1396
+ if($conjunction == 'and')
1397
+ $conjunction = __('and', 'pmpro');
1398
+
1399
+ return implode (', ', $array).' ' . $conjunction . ' '.$last;
1400
  }
1401
 
1402
  //from yoast wordpress seo
2180
  }
2181
 
2182
  return $pages_created;
2183
+ }
includes/lib/recaptchalib.php CHANGED
@@ -55,7 +55,7 @@ class pmpro_ReCaptcha
55
  *
56
  * @param string $secret shared secret between site and ReCAPTCHA server.
57
  */
58
- function pmpro_ReCaptcha($secret)
59
  {
60
  if ($secret == null || $secret == "") {
61
  die("To use reCAPTCHA you must get an API key from <a href='"
55
  *
56
  * @param string $secret shared secret between site and ReCAPTCHA server.
57
  */
58
+ function __construct($secret)
59
  {
60
  if ($secret == null || $secret == "") {
61
  die("To use reCAPTCHA you must get an API key from <a href='"
includes/metaboxes.php CHANGED
@@ -34,9 +34,14 @@ function pmpro_page_meta()
34
  }
35
  ?>
36
  </ul>
37
- <?php if('post' == get_post_type($post) && $in_member_cat) { ?>
 
38
  <p class="pmpro_meta_notice">* <?php _e("This post is already protected for this level because it is within a category that requires membership.", "pmpro");?></p>
39
- <?php } ?>
 
 
 
 
40
  <?php
41
  }
42
 
34
  }
35
  ?>
36
  </ul>
37
+ <?php
38
+ if('post' == get_post_type($post) && $in_member_cat) { ?>
39
  <p class="pmpro_meta_notice">* <?php _e("This post is already protected for this level because it is within a category that requires membership.", "pmpro");?></p>
40
+ <?php
41
+ }
42
+
43
+ do_action('pmpro_after_require_membership_metabox', $post);
44
+ ?>
45
  <?php
46
  }
47
 
includes/updates.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* This file contains functions used to process required database updates sometimes logged after PMPro is upgraded. */
3
+
4
+ /*
5
+ Is there an update?
6
+ */
7
+ function pmpro_isUpdateRequired() {
8
+ $updates = get_option('pmpro_updates', array());
9
+ return(!empty($updates));
10
+ }
11
+
12
+ /**
13
+ * Update option to require an update.
14
+ * @param string $update
15
+ *
16
+ * @since 1.8.7
17
+ */
18
+ function pmpro_addUpdate($update) {
19
+ $updates = get_option('pmpro_updates', array());
20
+ $updates[] = $update;
21
+ $updates = array_unique($updates);
22
+
23
+ update_option('pmpro_updates', $updates, 'no');
24
+ }
25
+
26
+ /**
27
+ * Update option to remove an update.
28
+ * @param string $update
29
+ *
30
+ * @since 1.8.7
31
+ */
32
+ function pmpro_removeUpdate($update) {
33
+ $updates = get_option('pmpro_updates', array());
34
+ $key = array_search($update,$updates);
35
+ if($key!==false){
36
+ unset($updates[$key]);
37
+ }
38
+
39
+ update_option('pmpro_updates', $updates, 'no');
40
+ }
41
+
42
+ /*
43
+ Enqueue updates.js if needed
44
+ */
45
+ function pmpro_enqueue_update_js() {
46
+ if(!empty($_REQUEST['page']) && $_REQUEST['page'] == 'pmpro-updates') {
47
+ wp_enqueue_script( 'pmpro-updates', plugin_dir_url( dirname(__FILE__) ) . 'js/updates.js' );
48
+ }
49
+ }
50
+ add_action('admin_enqueue_scripts', 'pmpro_enqueue_update_js');
51
+
52
+ /*
53
+ Load an update via AJAX
54
+ */
55
+ function pmpro_wp_ajax_pmpro_updates() {
56
+ //get updates
57
+ $updates = get_option('pmpro_updates', array());
58
+
59
+ //run update or let them know we're done
60
+ if(!empty($updates)) {
61
+ //get the latest one and run it
62
+ call_user_func($updates[0]);
63
+ echo ". ";
64
+ } else {
65
+ echo "done";
66
+ }
67
+
68
+ exit;
69
+ }
70
+ add_action('wp_ajax_pmpro_updates', 'pmpro_wp_ajax_pmpro_updates');
71
+
72
+ /*
73
+ Redirect away from updates page if there are no updates
74
+ */
75
+ function pmpro_admin_init_updates_redirect() {
76
+ if(is_admin() && !empty($_REQUEST['page']) && $_REQUEST['page'] == 'pmpro-updates' && !pmpro_isUpdateRequired()) {
77
+ wp_redirect(admin_url('admin.php?page=pmpro-membershiplevels&updatescomplete=1'));
78
+ exit;
79
+ }
80
+ }
81
+ add_action('init', 'pmpro_admin_init_updates_redirect');
82
+
83
+ /*
84
+ Show admin notice if an update is required and not already on the updates page.
85
+ */
86
+ if(pmpro_isUpdateRequired() && (empty($_REQUEST['page']) || $_REQUEST['page'] != 'pmpro-updates'))
87
+ add_action('admin_notices', 'pmpro_updates_notice');
88
+
89
+ /*
90
+ Function to show an admin notice linking to the updates page.
91
+ */
92
+ function pmpro_updates_notice() {
93
+ ?>
94
+ <div class="update-nag">
95
+ <p>
96
+ <?php
97
+ echo __( 'Paid Memberships Pro Data Update Required', 'pmpro' );
98
+ ?>
99
+ </p>
100
+ <p>
101
+ <?php
102
+ echo '<a class="button button-primary" href="' . admin_url('admin.php?page=pmpro-updates') . '">' . __('Start the Update', 'pmpro') . '</a>';
103
+ ?>
104
+ </p>
105
+ </div>
106
+ <?php
107
+ }
108
+
109
+ /*
110
+ Show admin notice when updates are complete.
111
+ */
112
+ if(is_admin() && !empty($_REQUEST['updatescomplete']))
113
+ add_action('admin_notices', 'pmpro_updates_notice_complete');
114
+
115
+ /*
116
+ Function to show an admin notice linking to the updates page.
117
+ */
118
+ function pmpro_updates_notice_complete() {
119
+ ?>
120
+ <div class="updated notice notice-success is-dismissible">
121
+ <p>
122
+ <?php
123
+ echo __('All Paid Memberships Pro updates have finished.', 'pmpro' );
124
+ ?>
125
+ </p>
126
+ </div>
127
+ <?php
128
+ }
includes/upgradecheck.php CHANGED
@@ -106,6 +106,12 @@ function pmpro_checkForUpgrades()
106
  $pmpro_db_version = 1.791;
107
  }
108
 
 
 
 
 
 
 
109
  //add level meta table
110
  /*
111
  if($pmpro_db_version < 1.87) {
@@ -127,6 +133,100 @@ function pmpro_upgrade_1_8_7() {
127
  return 1.87;
128
  }
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  function pmpro_upgrade_1_7()
131
  {
132
  pmpro_db_delta(); //just a db delta
106
  $pmpro_db_version = 1.791;
107
  }
108
 
109
+ //fix subscription ids on stripe orders
110
+ if($pmpro_db_version < 1.869) {
111
+ pmpro_upgrade_1_8_6_9();
112
+ $pmpro_db_version = 1.869;
113
+ }
114
+
115
  //add level meta table
116
  /*
117
  if($pmpro_db_version < 1.87) {
133
  return 1.87;
134
  }
135
 
136
+ /*
137
+ Upgrade to 1.8.6.9
138
+
139
+ 1. Find all orders for stripe gateway with a subscription_transaction_id LIKE 'cus_%'
140
+ 2. Search for an order for the same user_id and membership_id with a subscription_transaction_id LIKE 'sub_%'
141
+ 3. Replace subscription_transaction_id field.
142
+ */
143
+ function pmpro_upgrade_1_8_6_9() {
144
+ global $wpdb;
145
+ $orders = $wpdb->get_results("SELECT id, user_id, membership_id, subscription_transaction_id FROM $wpdb->pmpro_membership_orders WHERE gateway = 'stripe' AND subscription_transaction_id LIKE 'cus_%'");
146
+
147
+ if(!empty($orders)) {
148
+ if(count($orders) > 100) {
149
+ //if more than 100 orders, we'll need to do this via AJAX
150
+ pmpro_addUpdate('pmpro_upgrade_1_8_6_9_ajax');
151
+ } else {
152
+ //less than 100, let's just do them now
153
+ $subids = array();
154
+
155
+ foreach($orders as $order) {
156
+ if(!empty($subids[$order->subscription_transaction_id])) {
157
+ $wpdb->query("UPDATE $wpdb->pmpro_membership_orders SET subscription_transaction_id = '" . esc_sql($subids[$order->subscription_transaction_id]) . "' WHERE id = '" . $order->id . "' LIMIT 1");
158
+
159
+ //echo "Updating subid for #" . $order->id . " " . $order->subscription_transaction_id . ".<br />";
160
+ }
161
+ elseif(isset($subids[$order->subscription_transaction_id])) {
162
+ //no sub id found, so let it go
163
+
164
+ //echo "No subid found for #" . $order->id . " " . $order->subscription_transaction_id . " in cache.<br />";
165
+ }
166
+ else {
167
+ //need to look for a sub id in the database
168
+ $subid = $wpdb->get_var("SELECT subscription_transaction_id FROM $wpdb->pmpro_membership_orders WHERE membership_id = '" . $order->membership_id . "' AND user_id = '" . $order->user_id . "' AND subscription_transaction_id LIKE 'sub_%' LIMIT 1");
169
+ $subids[$order->subscription_transaction_id] = $subid;
170
+ if(!empty($subid)) {
171
+ $wpdb->query("UPDATE $wpdb->pmpro_membership_orders SET subscription_transaction_id = '" . esc_sql($subid) . "' WHERE id = '" . $order->id . "' LIMIT 1");
172
+
173
+ //echo "Updating subid for #" . $order->id . " " . $order->subscription_transaction_id . ".<br />";
174
+ }
175
+ else {
176
+ //echo "No subid found for #" . $order->id . " " . $order->subscription_transaction_id . ".<br />";
177
+ }
178
+ }
179
+ }
180
+ }
181
+ }
182
+
183
+ pmpro_setOption("db_version", "1.869");
184
+ return 1.869;
185
+ }
186
+
187
+ /*
188
+ If a site has > 100 orders then we run this pasrt of the update via AJAX from the updates page.
189
+ */
190
+ function pmpro_upgrade_1_8_6_9_ajax() {
191
+ global $wpdb;
192
+
193
+ //keeping track of which order we're working on
194
+ $last_order_id = get_option('pmpro_upgrade_1_8_6_9_last_order_id', 0);
195
+
196
+ //get orders
197
+ $orders = $wpdb->get_results("SELECT id, user_id, membership_id, subscription_transaction_id FROM $wpdb->pmpro_membership_orders WHERE id > $last_order_id AND gateway = 'stripe' AND subscription_transaction_id LIKE 'cus_%' ORDER BY id LIMIT 100");
198
+
199
+ if(empty($orders)) {
200
+ //done with this update
201
+ pmpro_removeUpdate('pmpro_upgrade_1_8_6_9_ajax');
202
+ delete_option('pmpro_upgrade_1_8_6_9_last_order_id');
203
+ } else {
204
+ $subids = array(); //cache of subids found
205
+ foreach($orders as $order) {
206
+ $last_order_id = $order->id; //keeping track of the last order we processed
207
+ if(!empty($subids[$order->subscription_transaction_id])) {
208
+ $wpdb->query("UPDATE $wpdb->pmpro_membership_orders SET subscription_transaction_id = '" . esc_sql($subids[$order->subscription_transaction_id]) . "' WHERE id = '" . $order->id . "' LIMIT 1");
209
+ }
210
+ elseif(isset($subids[$order->subscription_transaction_id])) {
211
+ //no sub id found, so let it go
212
+ }
213
+ else {
214
+ //need to look for a sub id in the database
215
+ $subid = $wpdb->get_var("SELECT subscription_transaction_id FROM $wpdb->pmpro_membership_orders WHERE membership_id = '" . $order->membership_id . "' AND user_id = '" . $order->user_id . "' AND subscription_transaction_id LIKE 'sub_%' LIMIT 1");
216
+ $subids[$order->subscription_transaction_id] = $subid;
217
+ if(!empty($subid)) {
218
+ $wpdb->query("UPDATE $wpdb->pmpro_membership_orders SET subscription_transaction_id = '" . esc_sql($subid) . "' WHERE id = '" . $order->id . "' LIMIT 1");
219
+ }
220
+ else {
221
+ //no sub id found, so let it go
222
+ }
223
+ }
224
+ }
225
+
226
+ update_option('pmpro_upgrade_1_8_6_9_last_order_id', $last_order_id);
227
+ }
228
+ }
229
+
230
  function pmpro_upgrade_1_7()
231
  {
232
  pmpro_db_delta(); //just a db delta
js/updates.js ADDED
@@ -0,0 +1,54 @@