Paid Memberships Pro - Version 1.8.7

Version Description

  • BUG: Fixed bug where recurring Stripe orders were saving the customer ID in the subscription_transaction_id instead of the subscription ID. This was causing issues with plugins like AffiliateWP that tried to track recurring orders. After upgrading to 1.8.7, a script will run on your database to fix old recurring orders.
  • BUG: Fixed bug where cancellations weren't showing up in the chart views of the membership stats reports.
  • BUG/ENHANCEMENT: The IPN service will now look for the payment_date parameter to set the timestamp of the recurring order/etc when processing IPN requests.
  • ENHANCEMENT: Added tools to run large database updates (e.g. Stripe fix above) over AJAX to avoid timeouts.
  • ENHANCEMENT: MemberOrder class will now insert/update the timestamp if a ->timestamp or ->datetime variable is set on the object.
  • ENHANCEMENT: Updated the Norwegian translation. (Thanks, Thomas Sjolshagen)
  • ENHANCEMENT: Added Argentine Peso (ARS) as a currency.
  • ENHANCEMENT: Added Nigerian Naira as a currency option. (Thanks, Maria)
  • ENHANCEMENT: Added a second option $conjunction parameter to the pmpro_implodeToEnglish() function. So you can use pmpro_implodeToEnglish($array, 'or') to change the 'and' in the text to 'or' or something different.
  • ENHANCEMENT: The "Sales" numbers on the sales and revenue reports now only includes orders with totals > $0. (More reports updates in the works.)
Download this release

Release Info

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

Code changes from version 1.8.6.8.1 to 1.8.7

Files changed (46) 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 +3 -3
  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/levels.php +1 -1
  39. paid-memberships-pro.php +5 -2
  40. readme.txt +17 -1
  41. services/applydiscountcode.php +37 -37
  42. services/authnet-silent-post.php +4 -1
  43. services/braintree-webhook.php +2 -2
  44. services/ipnhandler.php +5 -2
  45. services/stripe-webhook.php +9 -8
  46. 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
}
@@ -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(
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
}
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(
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 @@
1
+ jQuery(document).ready(function() {
2
+ //find status
3
+ var $status = jQuery('#pmpro_updates_status');
4
+ var $row = 1;
5
+ var $count = 0;
6
+ var $title = document.title;
7
+ var $cycles = ['|','/','-','\\'];
8
+
9
+ //start updates and update status
10
+ if($status.length > 0)
11
+ {
12
+ $status.html($status.html() + '\n' + 'JavaScript Loaded. Starting updates.\n');
13
+
14
+ function pmpro_updates()
15
+ {
16
+ jQuery.ajax({
17
+ url: ajaxurl,type:'GET', timeout: 30000,
18
+ dataType: 'html',
19
+ data: 'action=pmpro_updates',
20
+ error: function(xml){
21
+ alert('Error with update. Try refreshing.');
22
+ },
23
+ success: function(responseHTML){
24
+ if (responseHTML == 'error')
25
+ {
26
+ alert('Error with update. Try refreshing.');
27
+ document.title = $title;
28
+ }
29
+ else if(responseHTML == 'done')
30
+ {
31
+ $status.html($status.html() + '\nDone!');
32
+ document.title = '! ' + $title;
33
+ jQuery('#pmpro_updates_intro').html('All updates are complete.');
34
+ location.reload(1);
35
+ }
36
+ else
37
+ {
38
+ $count++;
39
+ $status.html($status.html() + responseHTML);
40
+ document.title = $cycles[$count%4] + ' ' + $title;
41
+ $update_timer = setTimeout(function() { pmpro_updates();}, 500);
42
+ }
43
+
44
+ //scroll the text area unless the mouse is over it
45
+ if (jQuery('#status:hover').length != 0) {
46
+ $status.scrollTop($status[0].scrollHeight - $status.height());
47
+ }
48
+ }
49
+ });
50
+ }
51
+
52
+ var $update_timer = setTimeout(function() { pmpro_updates();}, 500);
53
+ }
54
+ });
languages/email/fr_FR/billing.html CHANGED
@@ -1,4 +1,4 @@
1
- <p>Vos infos de paiement à !!sitename!! ont été changées.</p>
2
3
<p>Compte : !!display_name!! (!!user_email!!)</p>
4
<p>
@@ -11,6 +11,6 @@
11
Expiration : !!expirationmonth!!/!!expirationyear!!
12
</p>
13
14
- <p>Si vous n'avez pas demandé de changement de cets informations, contactez-nous à !!siteemail!!</p>
15
16
- <p>Pour vous connecter à votre compte : !!login_link!!</p>
1
+ <p>Vos informations de paiement à !!sitename!! ont été changées.</p>
2
3
<p>Compte : !!display_name!! (!!user_email!!)</p>
4
<p>
11
Expiration : !!expirationmonth!!/!!expirationyear!!
12
</p>
13
14
+ <p>Si vous n'avez pas demandé de changement à ces informations, contactez-nous à !!siteemail!!</p>
15
16
+ <p>Pour vous connecter à votre compte : !!login_link!!</p>
languages/pmpro-fa_IR.mo ADDED
Binary file
languages/pmpro-fa_IR.po ADDED
@@ -0,0 +1,4769 @@