Paid Memberships Pro - Version 1.8.9.1

Version Description

  • BUG: Fixed bug where some recurring orders members who checked out with Stripe in very old versions of PMPro would show up as orders with a blank user_id and membership_id. This update includes a fix for this and an update script to fix old orders affected by this.
  • BUG: Fixed bug where the Stripe class activation/deactivation methods were setup too late to actually run on activation/deactivation.
  • BUG: Updated the Stripe class to use the same language and markup in the Payment Information section as the default checkout.
  • BUG: Now forcing pmpro_getMembershipLevelForUser() in admin change emails.
  • BUG: Fixed warning in comments_array and comments_open filters. (Thanks, Mihail Chepovskiy)
  • BUG: Fixed format error for dates when saving orders. (Thanks, EmreErdogan)
  • BUG: Fixed bug that was causing issues in the cancellations report.
  • BUG: Fixed the pmpro_cron_expiration_warnings script to properly skip deleted and already expired members.
  • BUG: Reverted code to generate the CVV popup URL.
  • BUG: Fixed a couple bugs in the pmpro_loadTemplate function.
  • BUG/ENHANCEMENT: Updated URL used in the IPN Handler API calls to match the latest PayPal docs. (Thanks, pbaylies)
  • BUG/ENHANCEMENT: Overhauled the orders list CSV export for improved performance. There is still scaling work to be done on the exports, but timeouts and memory errors will happen much less often.
  • ENHANCEMENT: Added Greek (el_GR) translation. (Thanks, Alexandros Karypidis)
  • ENHANCEMENT: Added $order as a parameter to the pmpro_orders_user_row_actions hook. (Thanks, SquareLines)
  • ENHANCEMENT: Added a warning to backup your database to the update notice.
Download this release

Release Info

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

Code changes from version 1.8.9 to 1.8.9.1

Files changed (56) hide show
  1. adminpages/memberslist-csv.php +8 -2
  2. adminpages/orders-csv.php +529 -255
  3. adminpages/orders.php +1041 -856
  4. adminpages/reports/memberships.php +32 -14
  5. classes/class.memberorder.php +10 -3
  6. classes/class.pmproemail.php +2 -3
  7. classes/gateways/class.pmprogateway_braintree.php +2 -3
  8. classes/gateways/class.pmprogateway_stripe.php +46 -6
  9. includes/content.php +19 -7
  10. includes/functions.php +5 -11
  11. includes/updates.php +2 -6
  12. includes/updates/upgrade_1_8_9_1.php +146 -0
  13. includes/upgradecheck.php +9 -0
  14. languages/email/el_GR/admin_change.html +8 -0
  15. languages/email/el_GR/admin_change_admin.html +6 -0
  16. languages/email/el_GR/billable_invoice.html +7 -0
  17. languages/email/el_GR/billing.html +17 -0
  18. languages/email/el_GR/billing_admin.html +18 -0
  19. languages/email/el_GR/billing_failure.html +12 -0
  20. languages/email/el_GR/billing_failure_admin.html +12 -0
  21. languages/email/el_GR/cancel.html +4 -0
  22. languages/email/el_GR/cancel_admin.html +9 -0
  23. languages/email/el_GR/checkout_check.html +18 -0
  24. languages/email/el_GR/checkout_check_admin.html +18 -0
  25. languages/email/el_GR/checkout_express.html +15 -0
  26. languages/email/el_GR/checkout_express_admin.html +15 -0
  27. languages/email/el_GR/checkout_free.html +9 -0
  28. languages/email/el_GR/checkout_free_admin.html +9 -0
  29. languages/email/el_GR/checkout_freetrial.html +20 -0
  30. languages/email/el_GR/checkout_freetrial_admin.html +20 -0
  31. languages/email/el_GR/checkout_paid.html +24 -0
  32. languages/email/el_GR/checkout_paid_admin.html +24 -0
  33. languages/email/el_GR/checkout_trial.html +24 -0
  34. languages/email/el_GR/checkout_trial_admin.html +25 -0
  35. languages/email/el_GR/credit_card_expiring.html +14 -0
  36. languages/email/el_GR/default.html +1 -0
  37. languages/email/el_GR/footer.html +5 -0
  38. languages/email/el_GR/header.html +2 -0
  39. languages/email/el_GR/invoice.html +20 -0
  40. languages/email/el_GR/membership_expired.html +8 -0
  41. languages/email/el_GR/membership_expiring.html +7 -0
  42. languages/email/el_GR/trial_ending.html +9 -0
  43. languages/pmpro-el_GR.mo +0 -0
  44. languages/pmpro-el_GR.po +5778 -0
  45. languages/pmpro.mo +0 -0
  46. languages/pmpro.po +479 -376
  47. languages/pmpro.pot +479 -376
  48. pages/checkout.php +3 -8
  49. paid-memberships-pro.php +2 -2
  50. preheaders/checkout.php +794 -720
  51. readme.txt +18 -1
  52. services/authnet-silent-post.php +4 -0
  53. services/braintree-webhook.php +2 -0
  54. services/ipnhandler.php +610 -660
  55. services/stripe-webhook.php +38 -10
  56. services/twocheckout-ins.php +5 -2
adminpages/memberslist-csv.php CHANGED
@@ -501,8 +501,14 @@
501
  //close the temp file
502
  fclose($csv_fh);
503
 
504
- //make sure we get the right file size
505
- clearstatcache( true, $filename );
 
 
 
 
 
 
506
 
507
  //did we accidentally send errors/warnings to browser?
508
  if (headers_sent())
501
  //close the temp file
502
  fclose($csv_fh);
503
 
504
+ if (version_compare(phpversion(), '5.3.0', '>')) {
505
+
506
+ //make sure we get the right file size
507
+ clearstatcache( true, $filename );
508
+ } else {
509
+ // for any PHP version prior to v5.3.0
510
+ clearstatcache();
511
+ }
512
 
513
  //did we accidentally send errors/warnings to browser?
514
  if (headers_sent())
adminpages/orders-csv.php CHANGED
@@ -1,297 +1,571 @@
1
  <?php
2
- //only admins can get this
3
- if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_orderscsv")))
4
- {
5
- die(__("You do not have permissions to perform this action.", "pmpro"));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  }
7
 
8
- global $wpdb;
9
-
10
- //get users
11
- if(isset($_REQUEST['s']))
12
- $s = sanitize_text_field($_REQUEST['s']);
13
- else
14
- $s = "";
15
-
16
- if(isset($_REQUEST['l']))
17
- $l = intval($_REQUEST['l']);
18
- else
19
- $l = false;
20
-
21
- if(isset($_REQUEST['start-month']))
22
- $start_month = intval($_REQUEST['start-month']);
23
- else
24
- $start_month = "1";
25
-
26
- if(isset($_REQUEST['start-day']))
27
- $start_day = intval($_REQUEST['start-day']);
28
- else
29
- $start_day = "1";
30
-
31
- if(isset($_REQUEST['start-year']))
32
- $start_year = intval($_REQUEST['start-year']);
33
- else
34
- $start_year = date("Y");
35
-
36
- if(isset($_REQUEST['end-month']))
37
- $end_month = intval($_REQUEST['end-month']);
38
- else
39
- $end_month = date("n");
40
-
41
- if(isset($_REQUEST['end-day']))
42
- $end_day = intval($_REQUEST['end-day']);
43
- else
44
- $end_day = date("j");
45
-
46
- if(isset($_REQUEST['end-year']))
47
- $end_year = intval($_REQUEST['end-year']);
48
- else
49
- $end_year = date("Y");
50
-
51
- if(isset($_REQUEST['predefined-date']))
52
- $predefined_date = sanitize_text_field($_REQUEST['predefined-date']);
53
- else
54
- $predefined_date = "This Month";
55
-
56
- if(isset($_REQUEST['status']))
57
- $status = sanitize_text_field($_REQUEST['status']);
58
- else
59
- $status = "";
60
-
61
- if(isset($_REQUEST['filter']))
62
- $filter = sanitize_text_field($_REQUEST['filter']);
63
- else
64
- $filter = "all";
65
-
66
- //some vars for the search
67
- if(!empty($_REQUEST['pn']))
68
- $pn = intval($_REQUEST['pn']);
69
- else
70
- $pn = 1;
71
-
72
- if(!empty($_REQUEST['limit']))
73
- $limit = intval($_REQUEST['limit']);
74
- else
75
- $limit = false;
76
-
77
- if($limit)
78
- {
79
- $end = $pn * $limit;
80
- $start = $end - $limit;
81
  }
82
- else
83
- {
84
- $end = NULL;
85
- $start = NULL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  }
87
 
88
- //filters
89
- if($filter == "all" || !$filter)
90
- $condition = "1=1";
91
- elseif($filter == "within-a-date-range")
92
- {
93
- $start_date = $start_year."-".$start_month."-".$start_day;
94
- $end_date = $end_year."-".$end_month."-".$end_day;
95
 
96
- //add times to dates
97
- $start_date = $start_date . " 00:00:00";
98
- $end_date = $end_date . " 23:59:59";
99
 
100
- $condition = "timestamp BETWEEN '".$start_date."' AND '".$end_date."'";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  }
102
- elseif($filter == "predefined-date-range")
103
- {
104
- if($predefined_date == "Last Month")
105
- {
106
- $start_date = date("Y-m-d", strtotime("first day of last month", current_time("timestamp")));
107
- $end_date = date("Y-m-d", strtotime("last day of last month", current_time("timestamp")));
108
- }
109
- elseif($predefined_date == "This Month")
110
- {
111
- $start_date = date("Y-m-d", strtotime("first day of this month", current_time("timestamp")));
112
- $end_date = date("Y-m-d", strtotime("last day of this month", current_time("timestamp")));
113
- }
114
- elseif($predefined_date == "This Year")
115
- {
116
- $year = date('Y');
117
- $start_date = date("Y-m-d", strtotime("first day of January $year", current_time("timestamp")));
118
- $end_date = date("Y-m-d", strtotime("last day of December $year", current_time("timestamp")));
119
- }
120
 
121
- elseif($predefined_date == "Last Year")
122
- {
123
- $year = date('Y') - 1;
124
- $start_date = date("Y-m-d", strtotime("first day of January $year", current_time("timestamp")));
125
- $end_date = date("Y-m-d", strtotime("last day of December $year", current_time("timestamp")));
126
- }
127
 
128
- //add times to dates
129
- $start_date = $start_date . " 00:00:00";
130
- $end_date = $end_date . " 23:59:59";
131
 
132
- $condition = "timestamp BETWEEN '".esc_sql($start_date)."' AND '".esc_sql($end_date)."'";
133
- }
134
- elseif($filter == "within-a-level")
135
- {
136
- $condition = "membership_id = " . esc_sql($l);
137
- }
138
- elseif($filter == "within-a-status")
139
- {
140
- $condition = "status = '" . esc_sql($status) . "' ";
141
- }
142
 
143
- //string search
144
- if($s)
145
- {
146
- $sqlQuery = "SELECT SQL_CALC_FOUND_ROWS o.id FROM $wpdb->pmpro_membership_orders o LEFT JOIN $wpdb->users u ON o.user_id = u.ID LEFT JOIN $wpdb->pmpro_membership_levels l ON o.membership_id = l.id ";
147
 
148
- $join_with_usermeta = apply_filters("pmpro_orders_search_usermeta", false);
149
- if($join_with_usermeta)
150
- $sqlQuery .= "LEFT JOIN $wpdb->usermeta um ON o.user_id = um.user_id ";
151
 
152
- $sqlQuery .= "WHERE (1=2 ";
 
 
 
153
 
154
- $fields = array("o.id", "o.code", "o.billing_name", "o.billing_street", "o.billing_city", "o.billing_state", "o.billing_zip", "o.billing_phone", "o.payment_type", "o.cardtype", "o.accountnumber", "o.status", "o.gateway", "o.gateway_environment", "o.payment_transaction_id", "o.subscription_transaction_id", "u.user_login", "u.user_email", "u.display_name", "l.name");
 
 
 
 
155
 
156
- if($join_with_usermeta)
157
- $fields[] = "um.meta_value";
158
 
159
- $fields = apply_filters("pmpro_orders_search_fields", $fields);
 
 
160
 
161
- foreach($fields as $field)
162
- $sqlQuery .= " OR " . $field . " LIKE '%" . esc_sql($s) . "%' ";
163
- $sqlQuery .= ") ";
 
164
 
165
- $sqlQuery .= "AND " . $condition . " ";
 
166
 
167
- $sqlQuery .= "GROUP BY o.id ORDER BY o.id DESC, o.timestamp DESC ";
168
- }
169
- else
 
 
 
 
 
 
 
 
170
  {
171
- $sqlQuery = "SELECT SQL_CALC_FOUND_ROWS id FROM $wpdb->pmpro_membership_orders WHERE ".$condition." ORDER BY id DESC, timestamp DESC ";
 
172
  }
173
 
174
- if(!empty($start) && !empty($limit))
175
- $sqlQuery .= "LIMIT $start, $limit";
176
-
177
- $order_ids = $wpdb->get_col($sqlQuery);
178
-
179
- //begin output
180
- header("Content-type: text/csv");
181
-
182
- $filename = "orders.csv";
183
- /*
184
- Insert logic here for building filename from $filter and other values.
185
- */
186
- header("Content-Disposition: attachment; filename=$filename;");
187
-
188
- $csvoutput = "id,user_id,user_login,first_name,last_name,user_email,billing_name,billing_street,billing_city,billing_state,billing_zip,billing_country,billing_phone,membership_id,level_name,subtotal,tax,couponamount,total,payment_type,cardtype,accountnumber,expirationmonth,expirationyear,status,gateway,gateway_environment,payment_transaction_id,subscription_transaction_id,discount_code_id,discount_code,timestamp";
189
-
190
- //these are the meta_keys for the fields (arrays are object, property. so e.g. $theuser->ID)
191
- $default_columns = array(
192
- array("order", "id"),
193
- array("user", "ID"),
194
- array("user", "user_login"),
195
- array("user", "first_name"),
196
- array("user", "last_name"),
197
- array("user", "user_email"),
198
- array("order", "billing", "name"),
199
- array("order", "billing", "street"),
200
- array("order", "billing", "city"),
201
- array("order", "billing", "state"),
202
- array("order", "billing", "zip"),
203
- array("order", "billing", "country"),
204
- array("order", "billing", "phone"),
205
- array("order", "membership_id"),
206
- array("level", "name"),
207
- array("order", "subtotal"),
208
- array("order", "tax"),
209
- array("order", "couponamount"),
210
- array("order", "total"),
211
- array("order", "payment_type"),
212
- array("order", "cardtype"),
213
- array("order", "accountnumber"),
214
- array("order", "expirationmonth"),
215
- array("order", "expirationyear"),
216
- array("order", "status"),
217
- array("order", "gateway"),
218
- array("order", "gateway_environment"),
219
- array("order", "payment_transaction_id"),
220
- array("order", "subscription_transaction_id"),
221
- array("discount_code", "id"),
222
- array("discount_code", "code")
223
- );
224
 
225
- //any extra columns
226
- $extra_columns = apply_filters("pmpro_orders_csv_extra_columns", array());
227
- if(!empty($extra_columns))
228
- {
229
- foreach($extra_columns as $heading => $callback)
230
- {
231
- $csvoutput .= "," . $heading;
232
  }
233
  }
234
 
235
- $csvoutput .= "\n";
 
 
 
 
 
 
 
 
 
 
 
236
 
237
- //output
238
- echo $csvoutput;
239
- $csvoutput = "";
 
 
 
240
 
241
- if($order_ids)
242
  {
243
- foreach($order_ids as $order_id)
244
- {
245
- $order = new MemberOrder();
246
- $order->nogateway = true;
247
- $order->getMemberOrderByID($order_id);
248
- $user = get_userdata($order->user_id);
249
- $level = $order->getMembershipLevel();
250
- $sqlQuery = "SELECT c.id, c.code FROM $wpdb->pmpro_discount_codes_uses cu LEFT JOIN $wpdb->pmpro_discount_codes c ON cu.code_id = c.id WHERE cu.order_id = '" . $order_id . "' LIMIT 1";
251
- $discount_code = $wpdb->get_row($sqlQuery);
252
-
253
- //default columns
254
- if(!empty($default_columns))
255
- {
256
- $count = 0;
257
- foreach($default_columns as $col)
258
- {
259
- //add comma after the first item
260
- $count++;
261
- if($count > 1)
262
- $csvoutput .= ",";
263
-
264
- //checking $object->property. note the double $$
265
- if(!empty($col[2]) && isset($$col[0]->$col[1]->$col[2]))
266
- $csvoutput .= pmpro_enclose($$col[0]->$col[1]->$col[2]); //output the value
267
- elseif(!empty($$col[0]->$col[1]))
268
- $csvoutput .= pmpro_enclose($$col[0]->$col[1]); //output the value
269
- }
270
- }
271
 
272
- //timestamp
273
- $csvoutput .= "," . pmpro_enclose(date(get_option('date_format') . ' ' . get_option('time_format'), $order->timestamp));
 
 
 
 
 
 
 
274
 
275
- //any extra columns
276
- if(!empty($extra_columns))
277
- {
278
- foreach($extra_columns as $heading => $callback)
279
- {
280
- $csvoutput .= "," . pmpro_enclose(call_user_func($callback, $order));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
  }
 
 
282
  }
 
 
 
 
 
283
 
284
- $csvoutput .= "\n";
 
 
 
 
285
 
286
- //output
287
- echo $csvoutput;
288
- $csvoutput = "";
289
  }
290
- }
291
 
292
- print $csvoutput;
293
 
294
- function pmpro_enclose($s)
 
 
 
 
 
 
 
 
 
 
295
  {
296
- return "\"" . str_replace("\"", "\\\"", $s) . "\"";
 
 
 
 
 
 
 
 
 
297
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+ //only admins can get this
3
+ if ( ! function_exists( "current_user_can" ) || ( ! current_user_can( "manage_options" ) && ! current_user_can( "pmpro_orderscsv" ) ) ) {
4
+ die( __( "You do not have permissions to perform this action.", "pmpro" ) );
5
+ }
6
+
7
+ define('PMPRO_BENCHMARK', true);
8
+
9
+ if (!defined('PMPRO_BENCHMARK'))
10
+ define('PMPRO_BENCHMARK', false);
11
+
12
+ $start_memory = memory_get_usage(true);;
13
+ $start_time = microtime(true);
14
+
15
+ if (true === PMPRO_BENCHMARK)
16
+ {
17
+ error_log(str_repeat('-', 10) . date('Y-m-d H:i:s') . str_repeat('-', 10));
18
+ }
19
+
20
+ /**
21
+ * Filter to set max number of order records to process at a time
22
+ * for the export (helps manage memory footprint)
23
+ *
24
+ * NOTE: Use the pmpro_before_orders_list_csv_export hook to increase memory "on-the-fly"
25
+ * Can reset with the pmpro_after_orders_list_csv_export hook
26
+ *
27
+ * @since 1.8.9
28
+ */
29
+ //set the number of orders we'll load to try and protect ourselves from OOM errors
30
+ $max_orders_per_loop = apply_filters( 'pmpro_set_max_orders_per_export_loop', 2000 );
31
+
32
+ global $wpdb;
33
+
34
+ //get users
35
+ if ( isset( $_REQUEST['s'] ) ) {
36
+ $s = sanitize_text_field( $_REQUEST['s'] );
37
+ } else {
38
+ $s = "";
39
+ }
40
+
41
+ if ( isset( $_REQUEST['l'] ) ) {
42
+ $l = intval( $_REQUEST['l'] );
43
+ } else {
44
+ $l = false;
45
+ }
46
+
47
+ if ( isset( $_REQUEST['start-month'] ) ) {
48
+ $start_month = intval( $_REQUEST['start-month'] );
49
+ } else {
50
+ $start_month = "1";
51
+ }
52
+
53
+ if ( isset( $_REQUEST['start-day'] ) ) {
54
+ $start_day = intval( $_REQUEST['start-day'] );
55
+ } else {
56
+ $start_day = "1";
57
+ }
58
+
59
+ if ( isset( $_REQUEST['start-year'] ) ) {
60
+ $start_year = intval( $_REQUEST['start-year'] );
61
+ } else {
62
+ $start_year = date( "Y" );
63
+ }
64
+
65
+ if ( isset( $_REQUEST['end-month'] ) ) {
66
+ $end_month = intval( $_REQUEST['end-month'] );
67
+ } else {
68
+ $end_month = date( "n" );
69
+ }
70
+
71
+ if ( isset( $_REQUEST['end-day'] ) ) {
72
+ $end_day = intval( $_REQUEST['end-day'] );
73
+ } else {
74
+ $end_day = date( "j" );
75
+ }
76
+
77
+ if ( isset( $_REQUEST['end-year'] ) ) {
78
+ $end_year = intval( $_REQUEST['end-year'] );
79
+ } else {
80
+ $end_year = date( "Y" );
81
+ }
82
+
83
+ if ( isset( $_REQUEST['predefined-date'] ) ) {
84
+ $predefined_date = sanitize_text_field( $_REQUEST['predefined-date'] );
85
+ } else {
86
+ $predefined_date = "This Month";
87
+ }
88
+
89
+ if ( isset( $_REQUEST['status'] ) ) {
90
+ $status = sanitize_text_field( $_REQUEST['status'] );
91
+ } else {
92
+ $status = "";
93
+ }
94
+
95
+ if ( isset( $_REQUEST['filter'] ) ) {
96
+ $filter = sanitize_text_field( $_REQUEST['filter'] );
97
+ } else {
98
+ $filter = "all";
99
+ }
100
+
101
+ //some vars for the search
102
+ if ( ! empty( $_REQUEST['pn'] ) ) {
103
+ $pn = intval( $_REQUEST['pn'] );
104
+ } else {
105
+ $pn = 1;
106
+ }
107
+
108
+ if ( ! empty( $_REQUEST['limit'] ) ) {
109
+ $limit = intval( $_REQUEST['limit'] );
110
+ } else {
111
+ $limit = false;
112
+ }
113
+
114
+ if ( $limit ) {
115
+ $end = $pn * $limit;
116
+ $start = $end - $limit;
117
+ } else {
118
+ $end = null;
119
+ $start = null;
120
+ }
121
+
122
+ //filters
123
+ if ( $filter == "all" || ! $filter ) {
124
+ $condition = "1=1";
125
+ } elseif ( $filter == "within-a-date-range" ) {
126
+ $start_date = $start_year . "-" . $start_month . "-" . $start_day;
127
+ $end_date = $end_year . "-" . $end_month . "-" . $end_day;
128
+
129
+ //add times to dates
130
+ $start_date = $start_date . " 00:00:00";
131
+ $end_date = $end_date . " 23:59:59";
132
+
133
+ $condition = "timestamp BETWEEN '" . $start_date . "' AND '" . $end_date . "'";
134
+ } elseif ( $filter == "predefined-date-range" ) {
135
+ if ( $predefined_date == "Last Month" ) {
136
+ $start_date = date( "Y-m-d", strtotime( "first day of last month", current_time( "timestamp" ) ) );
137
+ $end_date = date( "Y-m-d", strtotime( "last day of last month", current_time( "timestamp" ) ) );
138
+ } elseif ( $predefined_date == "This Month" ) {
139
+ $start_date = date( "Y-m-d", strtotime( "first day of this month", current_time( "timestamp" ) ) );
140
+ $end_date = date( "Y-m-d", strtotime( "last day of this month", current_time( "timestamp" ) ) );
141
+ } elseif ( $predefined_date == "This Year" ) {
142
+ $year = date( 'Y' );
143
+ $start_date = date( "Y-m-d", strtotime( "first day of January $year", current_time( "timestamp" ) ) );
144
+ $end_date = date( "Y-m-d", strtotime( "last day of December $year", current_time( "timestamp" ) ) );
145
+ } elseif ( $predefined_date == "Last Year" ) {
146
+ $year = date( 'Y' ) - 1;
147
+ $start_date = date( "Y-m-d", strtotime( "first day of January $year", current_time( "timestamp" ) ) );
148
+ $end_date = date( "Y-m-d", strtotime( "last day of December $year", current_time( "timestamp" ) ) );
149
  }
150
 
151
+ //add times to dates
152
+ $start_date = $start_date . " 00:00:00";
153
+ $end_date = $end_date . " 23:59:59";
154
+
155
+ $condition = "timestamp BETWEEN '" . esc_sql( $start_date ) . "' AND '" . esc_sql( $end_date ) . "'";
156
+ } elseif ( $filter == "within-a-level" ) {
157
+ $condition = "membership_id = " . esc_sql( $l );
158
+ } elseif ( $filter == "within-a-status" ) {
159
+ $condition = "status = '" . esc_sql( $status ) . "' ";
160
+ }
161
+
162
+ //string search
163
+ if ( ! empty( $s ) ) {
164
+ $sqlQuery = "
165
+ SELECT SQL_CALC_FOUND_ROWS o.id
166
+ FROM {$wpdb->pmpro_membership_orders} AS o
167
+ LEFT JOIN $wpdb->users u ON o.user_id = u.ID
168
+ LEFT JOIN $wpdb->pmpro_membership_levels l ON o.membership_id = l.id
169
+ ";
170
+
171
+ $join_with_usermeta = apply_filters( "pmpro_orders_search_usermeta", false );
172
+
173
+ if ( ! empty( $join_with_usermeta ) ) {
174
+ $sqlQuery .= "LEFT JOIN $wpdb->usermeta um ON o.user_id = um.user_id ";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  }
176
+
177
+ $sqlQuery .= "WHERE (1=2 ";
178
+
179
+ $fields = array(
180
+ "o.id",
181
+ "o.code",
182
+ "o.billing_name",
183
+ "o.billing_street",
184
+ "o.billing_city",
185
+ "o.billing_state",
186
+ "o.billing_zip",
187
+ "o.billing_phone",
188
+ "o.payment_type",
189
+ "o.cardtype",
190
+ "o.accountnumber",
191
+ "o.status",
192
+ "o.gateway",
193
+ "o.gateway_environment",
194
+ "o.payment_transaction_id",
195
+ "o.subscription_transaction_id",
196
+ "u.user_login",
197
+ "u.user_email",
198
+ "u.display_name",
199
+ "l.name"
200
+ );
201
+
202
+ if ( ! empty( $join_with_usermeta ) ) {
203
+ $fields[] = "um.meta_value";
204
  }
205
 
206
+ $fields = apply_filters( "pmpro_orders_search_fields", $fields );
 
 
 
 
 
 
207
 
208
+ foreach ( $fields as $field ) {
209
+ $sqlQuery .= " OR " . $field . " LIKE '%" . esc_sql( $s ) . "%' ";
210
+ }
211
 
212
+ $sqlQuery .= ") ";
213
+ $sqlQuery .= "AND " . $condition . " ";
214
+ $sqlQuery .= "GROUP BY o.id ORDER BY o.id DESC, o.timestamp DESC ";
215
+
216
+ } else {
217
+ $sqlQuery = "
218
+ SELECT SQL_CALC_FOUND_ROWS id
219
+ FROM {$wpdb->pmpro_membership_orders}
220
+ WHERE {$condition}
221
+ ORDER BY id DESC, timestamp DESC
222
+ ";
223
+ }
224
+
225
+ if ( ! empty( $start ) && ! empty( $limit ) ) {
226
+ $sqlQuery .= "LIMIT $start, $limit";
227
+ }
228
+
229
+ $headers = array();
230
+ $headers[] = "Content-Type: text/csv";
231
+ $headers[] = "Cache-Control: max-age=0, no-cache, no-store";
232
+ $headers[] = "Pragma: no-cache";
233
+ $headers[] = "Connection: close";
234
+
235
+ $filename = "orders.csv";
236
+ /*
237
+ Insert logic here for building filename from $filter and other values.
238
+ */
239
+ $filename = apply_filters( 'pmpro_orders_csv_export_filename', $filename );
240
+ $headers[] = "Content-Disposition: attachment; filename={$filename};";
241
+
242
+ $csv_file_header_array = array(
243
+ "id",
244
+ "user_id",
245
+ "user_login",
246
+ "first_name",
247
+ "last_name",
248
+ "user_email",
249
+ "billing_name",
250
+ "billing_street",
251
+ "billing_city",
252
+ "billing_state",
253
+ "billing_zip",
254
+ "billing_country",
255
+ "billing_phone",
256
+ "membership_id",
257
+ "level_name",
258
+ "subtotal",
259
+ "tax",
260
+ "couponamount",
261
+ "total",
262
+ "payment_type",
263
+ "cardtype",
264
+ "accountnumber",
265
+ "expirationmonth",
266
+ "expirationyear",
267
+ "status",
268
+ "gateway",
269
+ "gateway_environment",
270
+ "payment_transaction_id",
271
+ "subscription_transaction_id",
272
+ "discount_code_id",
273
+ "discount_code",
274
+ "timestamp"
275
+ );
276
+
277
+ //these are the meta_keys for the fields (arrays are object, property. so e.g. $theuser->ID)
278
+ $default_columns = array(
279
+ array( "order", "id" ),
280
+ array( "user", "ID" ),
281
+ array( "user", "user_login" ),
282
+ array( "user", "first_name" ),
283
+ array( "user", "last_name" ),
284
+ array( "user", "user_email" ),
285
+ array( "order", "billing", "name" ),
286
+ array( "order", "billing", "street" ),
287
+ array( "order", "billing", "city" ),
288
+ array( "order", "billing", "state" ),
289
+ array( "order", "billing", "zip" ),
290
+ array( "order", "billing", "country" ),
291
+ array( "order", "billing", "phone" ),
292
+ array( "order", "membership_id" ),
293
+ array( "level", "name" ),
294
+ array( "order", "subtotal" ),
295
+ array( "order", "tax" ),
296
+ array( "order", "couponamount" ),
297
+ array( "order", "total" ),
298
+ array( "order", "payment_type" ),
299
+ array( "order", "cardtype" ),
300
+ array( "order", "accountnumber" ),
301
+ array( "order", "expirationmonth" ),
302
+ array( "order", "expirationyear" ),
303
+ array( "order", "status" ),
304
+ array( "order", "gateway" ),
305
+ array( "order", "gateway_environment" ),
306
+ array( "order", "payment_transaction_id" ),
307
+ array( "order", "subscription_transaction_id" ),
308
+ array( "discount_code", "id" ),
309
+ array( "discount_code", "code" )
310
+ );
311
+
312
+ $default_columns = apply_filters( "pmpro_order_list_csv_default_columns", $default_columns );
313
+
314
+ $csv_file_header_array = apply_filters( "pmpro_order_list_csv_export_header_array", $csv_file_header_array );
315
+
316
+ $dateformat = apply_filters( 'pmpro_order_list_csv_dateformat', get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
317
+
318
+ //any extra columns
319
+ $extra_columns = apply_filters( "pmpro_order_list_csv_extra_columns", array() );
320
+
321
+ if ( ! empty( $extra_columns ) ) {
322
+ foreach ( $extra_columns as $heading => $callback ) {
323
+ $csv_file_header_array[] = $heading;
324
  }
325
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
 
327
+ $csv_file_header = implode( ',', $csv_file_header_array ) . "\n";
 
 
 
 
 
328
 
329
+ // Generate a temporary file to store the data in.
330
+ $tmp_dir = apply_filters( 'pmpro_order_list_csv_export_tmp_dir', sys_get_temp_dir() );
331
+ $filename = tempnam( $tmp_dir, 'pmpro_olcsv_' );
332
 
333
+ // open in append mode
334
+ $csv_fh = fopen( $filename, 'a' );
 
 
 
 
 
 
 
 
335
 
336
+ //write the CSV header to the file
337
+ fprintf( $csv_fh, '%s', $csv_file_header );
 
 
338
 
339
+ $order_ids = $wpdb->get_col( $sqlQuery );
340
+ $orders_found = count( $order_ids );
 
341
 
342
+ if ( empty( $order_ids ) ) {
343
+ // send data to remote browser
344
+ pmpro_transmit_order_content( $csv_fh, $filename, $headers );
345
+ }
346
 
347
+ if (PMPRO_BENCHMARK)
348
+ {
349
+ $pre_action_time = microtime(true);
350
+ $pre_action_memory = memory_get_usage(true);
351
+ }
352
 
353
+ do_action('pmpro_before_order_list_csv_export', $order_ids);
 
354
 
355
+ $i_start = 0;
356
+ $i_limit = 0;
357
+ $iterations = 1;
358
 
359
+ if ( $orders_found >= $max_orders_per_loop ) {
360
+ $iterations = ceil( $orders_found / $max_orders_per_loop );
361
+ $i_limit = $max_orders_per_loop;
362
+ }
363
 
364
+ $end = 0;
365
+ $time_limit = ini_get( 'max_execution_time' );
366
 
367
+ if (PMPRO_BENCHMARK)
368
+ {
369
+ error_log("PMPRO_BENCHMARK - Total records to process: {$orders_found}");
370
+ error_log("PMPRO_BENCHMARK - Will process {$iterations} iterations of max {$max_orders_per_loop} records per iteration.");
371
+ $pre_iteration_time = microtime(true);
372
+ $pre_iteration_memory = memory_get_usage(true);
373
+ }
374
+
375
+ for ( $ic = 1; $ic <= $iterations; $ic ++ ) {
376
+
377
+ if (PMPRO_BENCHMARK)
378
  {
379
+ $start_iteration_time = microtime(true);
380
+ $start_iteration_memory = memory_get_usage(true);
381
  }
382
 
383
+ // avoiding timeouts (modify max run-time for export)
384
+ if ( $end != 0 ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
 
386
+ $iteration_diff = $end - $start;
387
+ $new_time_limit = ceil( $iteration_diff * $iterations * 1.2 );
388
+
389
+ if ( $time_limit < $new_time_limit ) {
390
+ $time_limit = $new_time_limit;
391
+ set_time_limit( $time_limit );
 
392
  }
393
  }
394
 
395
+ $start = current_time( 'timestamp' );
396
+
397
+ // get the first order id
398
+ $first_oid = $order_ids[ $i_start ];
399
+
400
+ //get last UID, will depend on which iteration we're on.
401
+ if ( $ic != $iterations ) {
402
+ $last_oid = $order_ids[ ( $i_start + ( $max_orders_per_loop - 1 ) ) ];
403
+ } else {
404
+ // Final iteration, so last UID is the last record in the users array
405
+ $last_oid = $order_ids[ ( $orders_found - 1 ) ];
406
+ }
407
 
408
+ //increment starting position
409
+ if ( $iterations > 1 ) {
410
+ $i_start += $max_orders_per_loop;
411
+ }
412
+ // get the order list we should process
413
+ $order_list = array_slice( $order_ids, $i_start, ( $i_start + ( $max_orders_per_loop - 1 ) ) );
414
 
415
+ if (PMPRO_BENCHMARK)
416
  {
417
+ $pre_orderdata_time = microtime(true);
418
+ $pre_orderdata_memory = memory_get_usage(true);
419
+ }
420
+
421
+ foreach ( $order_list as $order_id ) {
422
+
423
+ $csvoutput = array();
424
+
425
+ $order = new MemberOrder();
426
+ $order->nogateway = true;
427
+
428
+ $order->getMemberOrderByID( $order_id );
429
+
430
+ $user = get_userdata( $order->user_id );
431
+ $level = $order->getMembershipLevel();
 
 
 
 
 
 
 
 
 
 
 
 
 
432
 
433
+ $sqlQuery = $wpdb->prepare( "
434
+ SELECT c.id, c.code
435
+ FROM {$wpdb->pmpro_discount_codes_uses} AS cu
436
+ LEFT JOIN {$wpdb->pmpro_discount_codes} AS c
437
+ ON cu.code_id = c.id
438
+ WHERE cu.order_id = %s
439
+ LIMIT 1",
440
+ $order_id
441
+ );
442
 
443
+ $discount_code = $wpdb->get_row( $sqlQuery );
444
+
445
+ //default columns
446
+ if ( ! empty( $default_columns ) ) {
447
+ $count = 0;
448
+ foreach ( $default_columns as $col ) {
449
+
450
+ //checking $object->property. note the double $$
451
+ switch ( count( $col ) ) {
452
+ case 3:
453
+ $val = isset( ${$col[0]}->{$col[1]}->{$col[2]} ) ? ${$col[0]}->{$col[1]}->{$col[2]} : null;
454
+ break;
455
+
456
+ case 2:
457
+ $val = isset( ${$col[0]}->{$col[1]} ) ? ${$col[0]}->{$col[1]} : null;
458
+ break;
459
+
460
+ default:
461
+
462
+ $val = null;
463
  }
464
+
465
+ array_push( $csvoutput, pmpro_enclose( $val ) );
466
  }
467
+ }
468
+
469
+ //timestamp
470
+ $ts = date( $dateformat, $order->timestamp );
471
+ array_push( $csvoutput, pmpro_enclose( $ts ) );
472
 
473
+ //any extra columns
474
+ if ( ! empty( $extra_columns ) ) {
475
+ foreach ( $extra_columns as $heading => $callback ) {
476
+ $val = call_user_func( $callback, $order );
477
+ $val = ! empty( $val ) ? $val : null;
478
 
479
+ array_push( $csvoutput, pmpro_enclose( $val ) );
480
+ }
 
481
  }
 
482
 
483
+ $line = implode( ',', $csvoutput ) . "\n";
484
 
485
+ //output
486
+ fprintf( $csv_fh, "%s", $line );
487
+
488
+ $line = null;
489
+ $csvoutput = null;
490
+
491
+ $end = current_time( 'timestamp' );
492
+
493
+ } // end of foreach orders
494
+
495
+ if (PMPRO_BENCHMARK)
496
  {
497
+ $after_data_time = microtime(true);
498
+ $after_data_memory = memory_get_peak_usage(true);
499
+
500
+ $time_processing_data = $after_data_time - $start_time;
501
+ $memory_processing_data = $after_data_memory - $start_memory;
502
+
503
+ list($sec, $usec) = explode('.', $time_processing_data);
504
+
505
+ error_log("PMPRO_BENCHMARK - Time processing data: {$sec}.{$usec} seconds");
506
+ error_log("PMPRO_BENCHMARK - Peak memory usage: " . number_format($memory_processing_data, false, '.', ',') . " bytes");
507
  }
508
+
509
+ $order_list = null;
510
+ wp_cache_flush();
511
+ }
512
+
513
+ pmpro_transmit_order_content( $csv_fh, $filename, $headers );
514
+
515
+ function pmpro_enclose( $s ) {
516
+ return "\"" . str_replace( "\"", "\\\"", $s ) . "\"";
517
+ }
518
+
519
+
520
+ function pmpro_transmit_order_content( $csv_fh, $filename, $headers = array() ) {
521
+
522
+ //close the temp file
523
+ fclose( $csv_fh );
524
+
525
+ if ( version_compare( phpversion(), '5.3.0', '>' ) ) {
526
+
527
+ //make sure we get the right file size
528
+ clearstatcache( true, $filename );
529
+ } else {
530
+ // for any PHP version prior to v5.3.0
531
+ clearstatcache();
532
+ }
533
+
534
+ //did we accidentally send errors/warnings to browser?
535
+ if ( headers_sent() ) {
536
+ echo str_repeat( '-', 75 ) . "<br/>\n";
537
+ echo 'Please open a support case and paste in the warnings/errors you see above this text to\n ';
538
+ echo 'the <a href="http://paidmembershipspro.com/support/" target="_blank">Paid Memberships Pro support forum</a><br/>\n';
539
+ echo str_repeat( "=", 75 ) . "<br/>\n";
540
+ echo file_get_contents( $filename );
541
+ echo str_repeat( "=", 75 ) . "<br/>\n";
542
+ }
543
+
544
+ //transmission
545
+ if ( ! empty( $headers ) ) {
546
+ //set the download size
547
+ $headers[] = "Content-Length: " . filesize( $filename );
548
+
549
+ //set headers
550
+ foreach ( $headers as $header ) {
551
+ header( $header . "\r\n" );
552
+ }
553
+
554
+ // disable compression for the duration of file download
555
+ if ( ini_get( 'zlib.output_compression' ) ) {
556
+ ini_set( 'zlib.output_compression', 'Off' );
557
+ }
558
+
559
+ // open and send the file contents to the remote location
560
+ $fh = fopen( $filename, 'rb' );
561
+ fpassthru( $fh );
562
+ fclose( $fh );
563
+
564
+ // remove the temp file
565
+ unlink( $filename );
566
+ }
567
+
568
+ //allow user to clean up after themselves
569
+ do_action( 'pmpro_after_order_csv_export' );
570
+ exit;
571
+ }
adminpages/orders.php CHANGED
<
@@ -1,636 +1,769 @@
1
  <?php
2
- //only admins can get this
3
- if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_orders")))
4
- {
5
- die(__("You do not have permissions to perform this action.", "pmpro"));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  }
7
 
8
- //vars
9
- global $wpdb;
10
- if(isset($_REQUEST['s']))
11
- $s = sanitize_text_field(trim($_REQUEST['s']));
12
- else
13
- $s = "";
14
-
15
- if(isset($_REQUEST['l']))
16
- $l = intval($_REQUEST['l']);
17
- else
18
- $l = false;
19
-
20
- if(isset($_REQUEST['start-month']))
21
- $start_month = intval($_REQUEST['start-month']);
22
- else
23
- $start_month = "1";
24
-
25
- if(isset($_REQUEST['start-day']))
26
- $start_day = intval($_REQUEST['start-day']);
27
- else
28
- $start_day = "1";
29
-
30
- if(isset($_REQUEST['start-year']))
31
- $start_year = intval($_REQUEST['start-year']);
32
- else
33
- $start_year = date("Y");
34
-
35
- if(isset($_REQUEST['end-month']))
36
- $end_month = intval($_REQUEST['end-month']);
37
- else
38
- $end_month = date("n");
39
-
40
- if(isset($_REQUEST['end-day']))
41
- $end_day = intval($_REQUEST['end-day']);
42
- else
43
- $end_day = date("j");
44
-
45
- if(isset($_REQUEST['end-year']))
46
- $end_year = intval($_REQUEST['end-year']);
47
- else
48
- $end_year = date("Y");
49
-
50
- if(isset($_REQUEST['predefined-date']))
51
- $predefined_date = sanitize_text_field($_REQUEST['predefined-date']);
52
- else
53
- $predefined_date = "This Month";
54
-
55
- if(isset($_REQUEST['status']))
56
- $status = sanitize_text_field($_REQUEST['status']);
57
- else
58
- $status = "";
59
-
60
- if(isset($_REQUEST['filter']))
61
- $filter = sanitize_text_field($_REQUEST['filter']);
62
- else
63
- $filter = "all";
64
-
65
- //some vars for the search
66
- if(isset($_REQUEST['pn']))
67
- $pn = intval($_REQUEST['pn']);
68
- else
69
- $pn = 1;
70
-
71
- if(isset($_REQUEST['limit']))
72
- $limit = intval($_REQUEST['limit']);
73
- else
74
- {
75
- /**
76
- * Filter to set the default number of items to show per page
77
- * on the Orders page in the admin.
78
- *
79
- * @since 1.8.4.5
80
- *
81
- * @param int $limit The number of items to show per page.
82
- */
83
- $limit = apply_filters('pmpro_orders_per_page', 15);
84
  }
85
 
86
- $end = $pn * $limit;
87
- $start = $end - $limit;
88
-
89
- //filters
90
- if(empty($filter) || $filter === "all")
91
- {
92
- $condition = "1=1";
93
- $filter = "all";
 
 
 
 
 
 
94
  }
95
- elseif($filter == "within-a-date-range")
96
- {
97
- $start_date = $start_year."-".$start_month."-".$start_day;
98
- $end_date = $end_year."-".$end_month."-".$end_day;
99
-
100
- //add times to dates
101
- $start_date = $start_date . " 00:00:00";
102
- $end_date = $end_date . " 23:59:59";
103
-
104
- $condition = "timestamp BETWEEN '".esc_sql($start_date)."' AND '".esc_sql($end_date)."'";
 
 
 
 
 
 
 
 
 
105
  }
106
- elseif($filter == "predefined-date-range")
107
- {
108
- if($predefined_date == "Last Month")
109
- {
110
- $start_date = date("Y-m-d", strtotime("first day of last month", current_time("timestamp")));
111
- $end_date = date("Y-m-d", strtotime("last day of last month", current_time("timestamp")));
112
- }
113
- elseif($predefined_date == "This Month")
114
- {
115
- $start_date = date("Y-m-d", strtotime("first day of this month", current_time("timestamp")));
116
- $end_date = date("Y-m-d", strtotime("last day of this month", current_time("timestamp")));
117
- }
118
- elseif($predefined_date == "This Year")
119
- {
120
- $year = date('Y');
121
- $start_date = date("Y-m-d", strtotime("first day of January $year", current_time("timestamp")));
122
- $end_date = date("Y-m-d", strtotime("last day of December $year", current_time("timestamp")));
123
- }
124
 
125
- elseif($predefined_date == "Last Year")
126
- {
127
- $year = date('Y') - 1;
128
- $start_date = date("Y-m-d", strtotime("first day of January $year", current_time("timestamp")));
129
- $end_date = date("Y-m-d", strtotime("last day of December $year", current_time("timestamp")));
130
- }
131
-
132
- //add times to dates
133
- $start_date = $start_date . " 00:00:00";
134
- $end_date = $end_date . " 23:59:59";
135
-
136
- $condition = "timestamp BETWEEN '".esc_sql($start_date)."' AND '".esc_sql($end_date)."'";
137
  }
138
- elseif($filter == "within-a-level")
139
- {
140
- $condition = "membership_id = " . esc_sql($l);
141
  }
142
- elseif($filter == "within-a-status")
143
- {
144
- $condition = "status = '" . esc_sql($status) . "' ";
145
  }
146
-
147
- //emailing?
148
- if(!empty($_REQUEST['email']) && !empty($_REQUEST['order']))
149
- {
150
- $email = new PMProEmail();
151
- $user = get_user_by('email', $_REQUEST['email']);
152
- $order = new MemberOrder($_REQUEST['order']);
153
- if($email->sendBillableInvoiceEmail($user, $order))
154
- {
155
- $pmpro_msg = __("Invoice emailed successfully.", "pmpro");
156
- $pmpro_msgt = "success";
157
- }
158
- else
159
- {
160
- $pmpro_msg = __("Error emailing invoice.", "pmpro");
161
- $pmpro_msgt = "error";
162
- }
163
-
164
- //clean up so we stay on the orders list view
165
- unset($_REQUEST['order']);
166
- $order = NULL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  }
168
 
169
- //deleting?
170
- if(!empty($_REQUEST['delete']))
171
- {
172
- $dorder = new MemberOrder(intval($_REQUEST['delete']));
173
- if($dorder->deleteMe())
174
- {
175
- $pmpro_msg = __("Order deleted successfully.", "pmpro");
176
- $pmpro_msgt = "success";
177
  }
178
- else
179
- {
180
- $pmpro_msg = __("Error deleting order.", "pmpro");
181
- $pmpro_msgt = "error";
182
  }
183
  }
184
 
185
- $thisyear = date("Y");
186
-
187
- //this array stores fields that should be read only
188
- $read_only_fields = apply_filters("pmpro_orders_read_only_fields", array("code", "payment_transaction_id", "subscription_transaction_id"));
189
-
190
- //saving?
191
- if(!empty($_REQUEST['save']))
192
- {
193
- //start with old order if applicable
194
- $order_id = intval($_REQUEST['order']);
195
- if($order_id > 0)
196
- $order = new MemberOrder($order_id);
197
- else
198
- $order = new MemberOrder();
199
-
200
- //update values
201
- if(!in_array("code", $read_only_fields) && isset($_POST['code']))
202
- $order->code = $_POST['code'];
203
- if(!in_array("user_id", $read_only_fields) && isset($_POST['user_id']))
204
- $order->user_id = intval($_POST['user_id']);
205
- if(!in_array("membership_id", $read_only_fields) && isset($_POST['membership_id']))
206
- $order->membership_id = intval($_POST['membership_id']);
207
- if(!in_array("billing_name", $read_only_fields) && isset($_POST['billing_name']))
208
- $order->billing->name = stripslashes($_POST['billing_name']);
209
- if(!in_array("billing_street", $read_only_fields) && isset($_POST['billing_street']))
210
- $order->billing->street = stripslashes($_POST['billing_street']);
211
- if(!in_array("billing_city", $read_only_fields) && isset($_POST['billing_city']))
212
- $order->billing->city = stripslashes($_POST['billing_city']);
213
- if(!in_array("billing_state", $read_only_fields) && isset($_POST['billing_state']))
214
- $order->billing->state = stripslashes($_POST['billing_state']);
215
- if(!in_array("billing_zip", $read_only_fields) && isset($_POST['billing_zip']))
216
- $order->billing->zip = $_POST['billing_zip'];
217
- if(!in_array("billing_country", $read_only_fields) && isset($_POST['billing_country']))
218
- $order->billing->country = stripslashes($_POST['billing_country']);
219
- if(!in_array("billing_phone", $read_only_fields) && isset($_POST['billing_phone']))
220
- $order->billing->phone = $_POST['billing_phone'];
221
- if(!in_array("subtotal", $read_only_fields) && isset($_POST['subtotal']))
222
- $order->subtotal = $_POST['subtotal'];
223
- if(!in_array("tax", $read_only_fields) && isset($_POST['tax']))
224
- $order->tax = $_POST['tax'];
225
- if(!in_array("couponamount", $read_only_fields) && isset($_POST['couponamount']))
226
- $order->couponamount = $_POST['couponamount'];
227
- if(!in_array("total", $read_only_fields) && isset($_POST['total']))
228
- $order->total = $_POST['total'];
229
- if(!in_array("payment_type", $read_only_fields) && isset($_POST['payment_type']))
230
- $order->payment_type = $_POST['payment_type'];
231
- if(!in_array("cardtype", $read_only_fields) && isset($_POST['cardtype']))
232
- $order->cardtype = $_POST['cardtype'];
233
- if(!in_array("accountnumber", $read_only_fields) && isset($_POST['accountnumber']))
234
- $order->accountnumber = $_POST['accountnumber'];
235
- if(!in_array("expirationmonth", $read_only_fields) && isset($_POST['expirationmonth']))
236
- $order->expirationmonth = $_POST['expirationmonth'];
237
- if(!in_array("expirationyear", $read_only_fields) && isset($_POST['expirationyear']))
238
- $order->expirationyear = $_POST['expirationyear'];
239
- if(!in_array("ExpirationDate", $read_only_fields) && isset($_POST['ExpirationDate']))
240
- $order->ExpirationDate = $order->expirationmonth . $order->expirationyear;
241
- if(!in_array("status", $read_only_fields) && isset($_POST['status']))
242
- $order->status = stripslashes($_POST['status']);
243
- if(!in_array("gateway", $read_only_fields) && isset($_POST['gateway']))
244
- $order->gateway = $_POST['gateway'];
245
- if(!in_array("gateway_environment", $read_only_fields) && isset($_POST['gateway_environment']))
246
- $order->gateway_environment = $_POST['gateway_environment'];
247
- if(!in_array("payment_transaction_id", $read_only_fields) && isset($_POST['payment_transaction_id']))
248
- $order->payment_transaction_id = $_POST['payment_transaction_id'];
249
- if(!in_array("subscription_transaction_id", $read_only_fields) && isset($_POST['subscription_transaction_id']))
250
- $order->subscription_transaction_id = $_POST['subscription_transaction_id'];
251
- if(!in_array("notes", $read_only_fields) && isset($_POST['notes']))
252
- $order->notes = stripslashes($_POST['notes']);
253
-
254
- //affiliate stuff
255
- $affiliates = apply_filters("pmpro_orders_show_affiliate_ids", false);
256
- if(!empty($affiliates))
257
- {
258
- if(!in_array("affiliate_id", $read_only_fields))
259
- $order->affiliate_id = $_POST['affiliate_id'];
260
- if(!in_array("affiliate_subid", $read_only_fields))
261
- $order->affiliate_subid = $_POST['affiliate_subid'];
262
- }
263
-
264
- //save
265
- if($order->saveOrder() !== false)
266
- {
267
- //handle timestamp
268
- if($order->updateTimestamp($_POST['ts_year'], $_POST['ts_month'], $_POST['ts_day']) !== false)
269
- {
270
- $pmpro_msg = __("Order saved successfully.", "pmpro");
271
- $pmpro_msgt = "success";
272
- }
273
- else
274
- {
275
- $pmpro_msg = __("Error updating order timestamp.", "pmpro");
276
- $pmpro_msgt = "error";
277
- }
278
- }
279
- else
280
- {
281
- $pmpro_msg = __("Error saving order.", "pmpro");
282
  $pmpro_msgt = "error";
283
  }
 
 
 
284
  }
285
- else
286
- {
287
- //order passed?
288
- if(!empty($_REQUEST['order']))
289
- {
290
- $order_id = intval($_REQUEST['order']);
291
- if($order_id > 0)
292
- $order = new MemberOrder($order_id);
293
- elseif(!empty($_REQUEST['copy']))
294
- {
295
- $order = new MemberOrder(intval($_REQUEST['copy']));
296
-
297
- //new id
298
- $order->id = NULL;
299
-
300
- //new code
301
- $order->code = $order->getRandomCode();
302
- }
303
- else
304
- {
305
- $order = new MemberOrder(); //new order
306
- }
307
  }
308
  }
 
309
 
310
- require_once(dirname(__FILE__) . "/admin_header.php");
311
  ?>
312
 
313
- <?php if(!empty($order)) { ?>
314
 
315
  <h2>
316
- <?php if(!empty($order->id)) { ?>
317
- <?php _e('Order', 'pmpro');?> #<?php echo $order->id?>: <?php echo $order->code?>
318
  <?php } else { ?>
319
- <?php _e('New Order', 'pmpro');?>
320
  <?php } ?>
321
  </h2>
322
 
323
- <?php if(!empty($pmpro_msg)) { ?>
324
- <div id="message" class="<?php if($pmpro_msgt == "success") echo "updated fade"; else echo "error"; ?>"><p><?php echo $pmpro_msg?></p></div>
 
 
 
 
325
  <?php } ?>
326
 
327
  <form method="post" action="">
328
 
329
  <table class="form-table">
330
  <tbody>
331
- <tr>
332
- <th scope="row" valign="top"><label>ID:</label></th>
333
- <td><?php if(!empty($order->id)) echo $order->id; else echo __("This will be generated when you save.", "pmpro");?></td>
334
- </tr>
 
 
 
 
335
 
336
- <tr>
337
- <th scope="row" valign="top"><label for="code"><?php _e('Code', 'pmpro');?>:</label></th>
338
- <td>
339
- <?php if(in_array("code", $read_only_fields)) { echo $order->code; } else { ?>
340
- <input id="code" name="code" type="text" size="50" value="<?php echo esc_attr($order->code);?>" />
341
- <?php } ?>
342
- <?php if($order_id < 0) { ?><small class="pmpro_lite"><?php _e('Randomly generated for you.', 'pmpro');?></small><?php } ?>
343
- </td>
344
- </tr>
 
 
 
 
 
345
 
346
- <tr>
347
- <th scope="row" valign="top"><label for="user_id"><?php _e('User ID', 'pmpro');?>:</label></th>
348
- <td>
349
- <?php if(in_array("user_id", $read_only_fields) && $order_id > 0) { echo $order->user_id; } else { ?>
350
- <input id="user_id" name="user_id" type="text" size="50" value="<?php echo esc_attr($order->user_id);?>" />
351
- <?php } ?>
352
- </td>
353
- </tr>
 
 
 
354
 
355
- <tr>
356
- <th scope="row" valign="top"><label for="membership_id"><?php _e('Membership Level ID', 'pmpro');?>:</label></th>
357
- <td>
358
- <?php if(in_array("membership_id", $read_only_fields) && $order_id > 0) { echo $order->membership_id; } else { ?>
359
- <input id="membership_id" name="membership_id" type="text" size="50" value="<?php echo esc_attr($order->membership_id);?>" />
360
- <?php } ?>
361
- </td>
362
- </tr>
 
 
 
 
363
 
364
- <tr>
365
- <th scope="row" valign="top"><label for="billing_name"><?php _e('Billing Name', 'pmpro');?>:</label></th>
366
- <td>
367
- <?php if(in_array("billing_name", $read_only_fields) && $order_id > 0) { echo $order->billing_name; } else { ?>
368
- <input id="billing_name" name="billing_name" type="text" size="50" value="<?php echo esc_attr($order->billing->name);?>" />
369
- <?php } ?>
370
- </td>
371
- </tr>
372
- <tr>
373
- <th scope="row" valign="top"><label for="billing_street"><?php _e('Billing Street', 'pmpro');?>:</label></th>
374
- <td>
375
- <?php if(in_array("billing_street", $read_only_fields) && $order_id > 0) { echo $order->billing_street; } else { ?>
376
- <input id="billing_street" name="billing_street" type="text" size="50" value="<?php echo esc_attr($order->billing->street);?>" /></td>
377
- <?php } ?>
378
- </tr>
379
- <tr>
380
- <th scope="row" valign="top"><label for="billing_city"><?php _e('Billing City', 'pmpro');?>:</label></th>
381
- <td>
382
- <?php if(in_array("billing_city", $read_only_fields) && $order_id > 0) { echo $order->billing_city; } else { ?>
383
- <input id="billing_city" name="billing_city" type="text" size="50" value="<?php echo esc_attr($order->billing->city);?>" /></td>
384
- <?php } ?>
385
- </tr>
386
- <tr>
387
- <th scope="row" valign="top"><label for="billing_state"><?php _e('Billing State', 'pmpro');?>:</label></th>
388
- <td>
389
- <?php if(in_array("billing_state", $read_only_fields) && $order_id > 0) { echo $order->billing_state; } else { ?>
390
- <input id="billing_state" name="billing_state" type="text" size="50" value="<?php echo esc_attr($order->billing->state);?>" /></td>
391
- <?php } ?>
392
- </tr>
393
- <tr>
394
- <th scope="row" valign="top"><label for="billing_zip"><?php _e('Billing Postal Code', 'pmpro');?>:</label></th>
395
- <td>
396
- <?php if(in_array("billing_zip", $read_only_fields) && $order_id > 0) { echo $order->billing_zip; } else { ?>
397
- <input id="billing_zip" name="billing_zip" type="text" size="50" value="<?php echo esc_attr($order->billing->zip);?>" /></td>
398
- <?php } ?>
399
- </tr>
400
- <tr>
401
- <th scope="row" valign="top"><label for="billing_country"><?php _e('Billing Country', 'pmpro');?>:</label></th>
402
- <td>
403
- <?php if(in_array("billing_country", $read_only_fields) && $order_id > 0) { echo $order->billing_country; } else { ?>
404
- <input id="billing_country" name="billing_country" type="text" size="50" value="<?php echo esc_attr($order->billing->country);?>" />
405
- <?php } ?>
406
- </td>
407
- </tr>
408
- <tr>
409
- <th scope="row" valign="top"><label for="billing_phone"><?php _e('Billing Phone', 'pmpro');?>:</label></th>
410
- <td>
411
- <?php if(in_array("billing_phone", $read_only_fields) && $order_id > 0) { echo $order->billing_phone; } else { ?>
412
- <input id="billing_phone" name="billing_phone" type="text" size="50" value="<?php echo esc_attr($order->billing->phone);?>" />
413
- <?php } ?>
414
- </td>
415
- </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
416
 
417
- <tr>
418
- <th scope="row" valign="top"><label for="subtotal"><?php _e('Sub Total', 'pmpro');?>:</label></th>
419
- <td>
420
- <?php if(in_array("subtotal", $read_only_fields) && $order_id > 0) { echo $order->subtotal; } else { ?>
421
- <input id="subtotal" name="subtotal" type="text" size="10" value="<?php echo esc_attr($order->subtotal);?>" />
422
- <?php } ?>
423
- </td>
424
- </tr>
425
- <tr>
426
- <th scope="row" valign="top"><label for="tax"><?php _e('Tax', 'pmpro');?>:</label></th>
427
- <td>
428
- <?php if(in_array("tax", $read_only_fields) && $order_id > 0) { echo $order->tax; } else { ?>
429
- <input id="tax" name="tax" type="text" size="10" value="<?php echo esc_attr($order->tax);?>" />
430
- <?php } ?>
431
- </td>
432
- </tr>
433
- <tr>
434
- <th scope="row" valign="top"><label for="couponamount"><?php _e('Coupon Amount', 'pmpro');?>:</label></th>
435
- <td>
436
- <?php if(in_array("couponamount", $read_only_fields) && $order_id > 0) { echo $order->couponamount; } else { ?>
437
- <input id="couponamount" name="couponamount" type="text" size="10" value="<?php echo esc_attr($order->couponamount);?>" />
438
- <?php } ?>
439
- </td>
440
- </tr>
441
- <tr>
442
- <th scope="row" valign="top"><label for="total"><?php _e('Total', 'pmpro');?>:</label></th>
443
- <td>
444
- <?php if(in_array("total", $read_only_fields) && $order_id > 0) { echo $order->total; } else { ?>
445
- <input id="total" name="total" type="text" size="10" value="<?php echo esc_attr($order->total);?>" />
446
- <?php } ?>
447
- <small class="pmpro_lite"><?php _e('Should be subtotal + tax - couponamount.', 'pmpro');?></small>
448
- </td>
449
- </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
450
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
  <tr>
452
- <th scope="row" valign="top"><label for="payment_type"><?php _e('Payment Type', 'pmpro');?>:</label></th>
453
- <td>
454
- <?php if(in_array("payment_type", $read_only_fields) && $order_id > 0) { echo $order->payment_type; } else { ?>
455
- <input id="payment_type" name="payment_type" type="text" size="50" value="<?php echo esc_attr($order->payment_type);?>" />
456
- <?php } ?>
457
- <small class="pmpro_lite"><?php _e('e.g. PayPal Express, PayPal Standard, Credit Card.', 'pmpro');?></small>
458
- </td>
459
- </tr>
460
- <tr>
461
- <th scope="row" valign="top"><label for="cardtype"><?php _e('Card Type', 'pmpro');?></label></th>
462
- <td>
463
- <?php if(in_array("cardtype", $read_only_fields) && $order_id > 0) { echo $order->cardtype; } else { ?>
464
- <input id="cardtype" name="cardtype" type="text" size="50" value="<?php echo esc_attr($order->cardtype);?>" />
465
- <?php } ?>
466
- <small class="pmpro_lite"><?php _e('e.g. Visa, MasterCard, AMEX, etc', 'pmpro');?></small>
467
- </td>
468
- </tr>
469
- <tr>
470
- <th scope="row" valign="top"><label for="accountnumber"><?php _e('Account Number', 'pmpro');?>:</label></th>
471
- <td>
472
- <?php if(in_array("accountnumber", $read_only_fields) && $order_id > 0) { echo $order->accountnumber; } else { ?>
473
- <input id="accountnumber" name="accountnumber" type="text" size="50" value="<?php echo esc_attr($order->accountnumber);?>" />
474
- <?php } ?>
475
- <small class="pmpro_lite"><?php _e('Obscure all but last 4 digits.', 'pmpro');?></small>
476
- </td>
477
- </tr>
478
- <?php if(in_array("ExpirationDate", $read_only_fields) && $order_id > 0) { echo $order->ExpirationDate; } else { ?>
479
- <tr>
480
- <th scope="row" valign="top"><label for="expirationmonth"><?php _e('Expiration Month', 'pmpro');?>:</label></th>
481
  <td>
482
- <input id="expirationmonth" name="expirationmonth" type="text" size="10" value="<?php echo esc_attr($order->expirationmonth);?>" />
 
483
  <small class="pmpro_lite">MM</small>
484
  </td>
485
  </tr>
486
  <tr>
487
- <th scope="row" valign="top"><label for="expirationyear"><?php _e('Expiration Year', 'pmpro');?>:</label></th>
 
488
  <td>
489
- <input id="expirationyear" name="expirationyear" type="text" size="10" value="<?php echo esc_attr($order->expirationyear);?>" />
 
490
  <small class="pmpro_lite">YYYY</small>
491
  </td>
492
  </tr>
493
- <?php } ?>
494
- <tr>
495
- <th scope="row" valign="top"><label for="status"><?php _e('Status', 'pmpro');?>:</label></th>
496
- <td>
497
- <?php if(in_array("status", $read_only_fields) && $order_id > 0) { echo $order->status; } else { ?>
 
 
498
  <?php
499
- $statuses = array();
500
- $default_statuses = array("", "success", "cancelled", "review", "token", "refunded", "pending");
501
- $used_statuses = $wpdb->get_col("SELECT DISTINCT(status) FROM $wpdb->pmpro_membership_orders");
502
- $statuses = array_unique(array_merge($default_statuses, $used_statuses));
503
- asort($statuses);
504
- $statuses = apply_filters("pmpro_order_statuses", $statuses);
 
 
 
 
 
 
 
 
 
505
  ?>
506
  <select id="status" name="status">
507
- <?php foreach($statuses as $status) { ?>
508
- <option value="<?php echo esc_attr($status);?>" <?php selected($order->status, $status);?>><?php echo $status;?></option>
 
509
  <?php } ?>
510
  </select>
511
- <?php } ?>
512
- </td>
513
- </tr>
514
 
515
- <tr>
516
- <th scope="row" valign="top"><label for="gateway"><?php _e('Gateway', 'pmpro');?>:</label></th>
517
- <td>
518
- <?php if(in_array("gateway", $read_only_fields) && $order_id > 0) { echo $order->gateway; } else { ?>
 
 
519
  <select id="gateway" name="gateway" onchange="pmpro_changeGateway(jQuery(this).val());">
520
  <?php
521
- $pmpro_gateways = pmpro_gateways();
522
- foreach($pmpro_gateways as $pmpro_gateway_name => $pmpro_gateway_label)
523
- {
524
  ?>
525
- <option value="<?php echo esc_attr($pmpro_gateway_name);?>" <?php selected($order->gateway, $pmpro_gateway_name);?>><?php echo $pmpro_gateway_label;?></option>
 
526
  <?php
527
- }
528
  ?>
529
  </select>
530
- <?php } ?>
531
- </td>
532
- </tr>
533
- <tr>
534
- <th scope="row" valign="top"><label for="gateway_environment"><?php _e('Gateway Environment', 'pmpro');?>:</label></th>
535
- <td>
536
- <?php if(in_array("gateway_environment", $read_only_fields) && $order_id > 0) { echo $order->gateway_environment; } else { ?>
 
 
 
537
  <select name="gateway_environment">
538
- <option value="sandbox" <?php if($order->gateway_environment == "sandbox") { ?>selected="selected"<?php } ?>><?php _e('Sandbox/Testing', 'pmpro');?></option>
539
- <option value="live" <?php if($order->gateway_environment == "live") { ?>selected="selected"<?php } ?>><?php _e('Live/Production', 'pmpro');?></option>
 
 
540
  </select>
541
- <?php } ?>
542
- </td>
543
- </tr>
544
 
545
- <tr>
546
- <th scope="row" valign="top"><label for="payment_transaction_id"><?php _e('Payment Transaction ID', 'pmpro');?>:</label></th>
547
- <td>
548
- <?php if(in_array("payment_transaction_id", $read_only_fields) && $order_id > 0) { echo $order->payment_transaction_id; } else { ?>
549
- <input id="payment_transaction_id" name="payment_transaction_id" type="text" size="50" value="<?php echo esc_attr($order->payment_transaction_id);?>" />
550
- <?php } ?>
551
- <small class="pmpro_lite"><?php _e('Generated by the gateway. Useful to cross reference orders.', 'pmpro');?></small>
552
- </td>
553
- </tr>
554
- <tr>
555
- <th scope="row" valign="top"><label for="subscription_transaction_id"><?php _e('Subscription Transaction ID', 'pmpro');?>:</label></th>
556
- <td>
557
- <?php if(in_array("subscription_transaction_id", $read_only_fields) && $order_id > 0) { echo $order->subscription_transaction_id; } else { ?>
558
- <input id="subscription_transaction_id" name="subscription_transaction_id" type="text" size="50" value="<?php echo esc_attr($order->subscription_transaction_id);?>" />
559
- <?php } ?>
560
- <small class="pmpro_lite"><?php _e('Generated by the gateway. Useful to cross reference subscriptions.', 'pmpro');?></small>
561
- </td>
562
- </tr>
 
 
 
 
 
 
 
 
 
 
 
563
 
564
- <tr>
565
- <th scope="row" valign="top"><label for="ts_month"><?php _e('Date', 'pmpro');?>:</label></th>
566
- <td>
567
- <?php if(in_array("timestamp", $read_only_fields) && $order_id > 0) { echo date(get_option('date_format') . " " . get_option('time_format'), $order->timestamp); } else { ?>
 
 
568
  <?php
569
- //set up date vars
570
- if(!empty($order->timestamp))
571
- $timestamp = $order->timestamp;
572
- else
573
- $timestamp = current_time('timestamp');
574
- $year = date("Y", $timestamp);
575
- $month = date("n", $timestamp);
576
- $day = date("j", $timestamp);
 
577
  ?>
578
  <select id="ts_month" name="ts_month">
579
- <?php
580
- for($i = 1; $i < 13; $i++)
581
- {
582
- ?>
583
- <option value="<?php echo $i?>" <?php if($i == $month) { ?>selected="selected"<?php } ?>><?php echo date("M", strtotime($i . "/1/" . $year, current_time("timestamp")))?></option>
584
  <?php
 
 
 
 
 
585
  }
586
- ?>
587
  </select>
588
- <input name="ts_day" type="text" size="2" value="<?php echo esc_attr($day);?>" />
589
- <input name="ts_year" type="text" size="4" value="<?php echo esc_attr($year);?>" />
590
- <?php } ?>
591
- </td>
592
- </tr>
593
 
594
- <?php
595
- $affiliates = apply_filters("pmpro_orders_show_affiliate_ids", false);
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);?>" />
 
 
 
603
  <?php } ?>
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);?>" />
 
 
 
611
  <?php } ?>
612
  </td>
613
  </tr>
614
- <?php } ?>
615
 
616
- <tr>
617
- <th scope="row" valign="top"><label for="notes"><?php _e('Notes', 'pmpro');?>:</label></th>
618
- <td>
619
- <?php if(in_array("notes", $read_only_fields) && $order_id > 0) { echo $order->notes; } else { ?>
620
- <textarea id="notes" name="notes" rows="5" cols="80"><?php echo esc_textarea($order->notes);?></textarea>
621
- <?php } ?>
622
- </td>
623
- </tr>
 
 
 
624
 
625
- <?php do_action("pmpro_after_order_settings", $order); ?>
626
 
627
  </tbody>
628
  </table>
629
 
630
  <p class="submit topborder">
631
- <input name="order" type="hidden" value="<?php if(!empty($order->id)) echo $order->id; else echo $order_id;?>" />
632
- <input name="save" type="submit" class="button-primary" value="<?php _e('Save Order', 'pmpro');?>" />
633
- <input name="cancel" type="button" class="cancel button-secondary" value="<?php _e('Cancel', 'pmpro');?>" onclick="location.href='<?php echo get_admin_url(NULL, '/admin.php?page=pmpro-orders')?>';" />
 
 
 
 
 
634
  </p>
635
 
636
  </form>
@@ -645,9 +778,9 @@
645
  ?>
646
  <script>
647
  // Update fields in email modal.
648
- jQuery(document).ready(function($) {
649
  var order, order_id;
650
- $('.email_link').click(function() {
651
  order_id = $(this).data('order');
652
  $('input[name=order]').val(order_id);
653
  // Get email address from order ID
@@ -655,7 +788,7 @@
655
  action: 'pmpro_get_order_json',
656
  order_id: order_id
657
  };
658
- $.post(ajaxurl, data, function(response) {
659
  order = JSON.parse(response);
660
  $('input[name=email]').val(order.Email);
661
  });
@@ -664,397 +797,449 @@
664
  </script>
665
  <?php add_thickbox(); ?>
666
  <div id="email_invoice" style="display:none;">
667
- <h3><?php _e('Email Invoice', 'pmpro'); ?></h3>
668
  <form method="post" action="">
669
- <input type="hidden" name="order" value="" />
670
- <?php _e('Send an invoice for this order to: ', 'pmpro'); ?>
671
- <input type="text" value="" name="email" />
672
- <button class="button button-primary alignright"><?php _e('Send Email', 'pmpro'); ?></button>
673
  </form>
674
  </div>
675
  <form id="posts-filter" method="get" action="">
676
- <h2>
677
- <?php _e('Orders', 'pmpro');?>
678
- <a href="admin.php?page=pmpro-orders&order=-1" class="add-new-h2">+ <?php _e('Add New Order', 'pmpro');?></a>
 
679
 
680
- <?php
681
  //build the export URL
682
- $export_url = admin_url('admin-ajax.php') . "?action=orders_csv";
683
  $url_params = array(
684
- "filter"=>$filter,
685
- "s"=>$s,
686
- "l"=>$l,
687
- "start-month"=>$start_month,
688
- "start-day"=>$start_day,
689
- "start-year"=>$start_year,
690
- "end-month"=>$end_month,
691
- "end-day"=>$end_day,
692
- "end-year"=>$end_year,
693
- "predefined-date"=>$predefined_date,
694
- "status"=>$status
695
  );
696
- $export_url = add_query_arg($url_params, $export_url);
697
- ?>
698
- <a target="_blank" href="<?php echo $export_url;?>" class="add-new-h2"><?php _e('Export to CSV', 'pmpro');?></a>
699
- </h2>
 
700
 
701
 
 
 
 
 
 
 
 
702
 
703
- <?php if(!empty($pmpro_msg)) { ?>
704
- <div id="message" class="<?php if($pmpro_msgt == "success") echo "updated fade"; else echo "error"; ?>"><p><?php echo $pmpro_msg?></p></div>
705
- <?php } ?>
706
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
707
 
708
- <ul class="subsubsub">
709
- <li>
710
- <?php _e('Show', 'pmpro')?>
711
- <select id="filter" name="filter">
712
- <option value="all" <?php selected($filter, "all");?>><?php _e('All', 'pmpro');?></option>
713
- <option value="within-a-date-range" <?php selected($filter, "within-a-date-range");?>><?php _e('Within a Date Range', 'pmpro');?></option>
714
- <option value="predefined-date-range" <?php selected($filter, "predefined-date-range");?>><?php _e('Predefined Date Range', 'pmpro');?></option>
715
- <option value="within-a-level" <?php selected($filter, "within-a-level");?>><?php _e('Within a Level', 'pmpro');?></option>
716
- <option value="within-a-status" <?php selected($filter, "within-a-status");?>><?php _e('Within a Status', 'pmpro');?></option>
717
- </select>
718
 
719
- <span id="from"><?php _e('From', 'pmpro')?></span>
 
 
 
 
 
720
 
721
- <select id="start-month" name="start-month">
722
- <?php for($i = 1; $i < 13; $i++) { ?>
723
- <option value="<?php echo $i;?>" <?php selected($start_month, $i);?>><?php echo date("F", mktime(0, 0, 0, $i, 2));?></option>
724
- <?php } ?>
725
- </select>
726
 
727
- <input id='start-day' name="start-day" type="text" size="2" value="<?php echo esc_attr($start_day);?>" />
728
- <input id='start-year' name="start-year" type="text" size="4" value="<?php echo esc_attr($start_year);?>" />
729
 
 
730
 
731
- <span id="to"><?php _e('To', 'pmpro')?></span>
732
-
733
- <select id="end-month" name="end-month">
734
- <?php for($i = 1; $i < 13; $i++) { ?>
735
- <option value="<?php echo $i;?>" <?php selected($end_month, $i);?>><?php echo date("F", mktime(0, 0, 0, $i,2));?></option>
736
- <?php } ?>
737
- </select>
738
 
739
 
740
- <input id='end-day' name="end-day" type="text" size="2" value="<?php echo esc_attr($end_day);?>" />
741
- <input id='end-year' name="end-year" type="text" size="4" value="<?php echo esc_attr($end_year);?>" />
742
 
743
- <span id="filterby"><?php _e('filter by ', 'pmpro')?></span>
744
 
745
- <select id="predefined-date" name="predefined-date">
746
 
747
- <option value="<?php echo "This Month";?>" <?php selected($predefined_date, "This Month");?>><?php echo "This Month";?></option>
748
- <option value="<?php echo "Last Month";?>" <?php selected($predefined_date, "Last Month");?>><?php echo "Last Month";?></option>
749
- <option value="<?php echo "This Year";?>" <?php selected($predefined_date, "This Year");?>><?php echo "This Year";?></option>
750
- <option value="<?php echo "Last Year";?>" <?php selected($predefined_date, "Last Year");?>><?php echo "Last Year";?></option>
 
 
 
 
751
 
752
- </select>
753
-
754
- <?php
755
- //Note: only orders belonging to current levels can be filtered. There is no option for orders belonging to deleted levels
756
- $levels = pmpro_getAllLevels(true, true);
757
- ?>
758
- <select id="l" name="l">
759
- <?php foreach($levels as $level) { ?>
760
- <option value="<?php echo $level->id;?>" <?php selected($l, $level->id);?>><?php echo $level->name;?></option>
761
- <?php } ?>
762
-
763
- </select>
764
-
765
- <?php
766
- $statuses = array();
767
- $default_statuses = array("", "success", "cancelled", "review", "token", "refunded");
768
- $used_statuses = $wpdb->get_col("SELECT DISTINCT(status) FROM $wpdb->pmpro_membership_orders");
769
- $statuses = array_unique(array_merge($default_statuses, $used_statuses));
770
- asort($statuses);
771
- $statuses = apply_filters("pmpro_order_statuses", $statuses);
772
- ?>
773
- <select id="status" name="status">
774
- <?php foreach($statuses as $the_status) { ?>
775
- <option value="<?php echo esc_attr($the_status);?>" <?php selected($the_status, $status);?>><?php echo $the_status;?></option>
776
- <?php } ?>