PluginProbe
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More / 2.4.1
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More v2.4.1
2.4.1 2.4.0 2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.2 2.2.1 2.2.0 2.1.2 2.1.1 trunk 0.0.1 0.0.2 0.0.3 0.0.4 0.0.5 0.0.6 0.0.7 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 All 68 releases
better-payment / includes / Classes / Export.php

Export.php in Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More 2.4.1, at includes/Classes/Export.php

244 lines 9.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Better_Payment\Lite\Classes;
4
5 use Better_Payment\Lite\Classes\Helper as ClassesHelper;
6 use Better_Payment\Lite\Controller;
7 use Better_Payment\Lite\Models\TransactionModel;
8 use Better_Payment\Lite\Traits\Helper;
9
10 /**
11 * Exit if accessed directly
12 */
13 if (!defined('ABSPATH')) {
14 exit;
15 }
16
17 /**
18 * Export handler class
19 *
20 * @since 0.0.4
21 */
22 class Export extends Controller{
23
24 use Helper;
25
26 /**
27 * CSV escape character, passed to fputcsv() explicitly on every call.
28 *
29 * PHP 8.4 deprecates relying on fputcsv()'s default $escape, because that
30 * default will change in a later release. Passing the current default (a
31 * backslash) keeps the output byte-identical on PHP 7.4 through 8.5.
32 */
33 const CSV_ESCAPE = "\\";
34
35 /**
36 * Class constructor
37 *
38 * @since 0.0.4
39 */
40 public function __construct() {
41
42 }
43
44 public function export_transactions() {
45 $response = [];
46
47 if (!wp_verify_nonce($_REQUEST['nonce'], 'wp_rest')) {
48 $response['message'] = __("Access Denied!", 'better-payment');
49 wp_send_json_error($response);
50 }
51
52 if (!current_user_can('manage_options')) {
53 $response['message'] = __("Access Denied!", 'better-payment');
54 wp_send_json_error($response);
55 }
56
57 $transaction_model = new TransactionModel();
58
59 // Check if this is a filtered export
60 $is_filtered = isset($_REQUEST['filtered']) && $_REQUEST['filtered'] === '1';
61
62 if ($is_filtered) {
63 // Build filter arguments
64 $filter_args = [];
65
66 if (!empty($_REQUEST['search_text'])) {
67 $filter_args['search_text'] = sanitize_text_field($_REQUEST['search_text']);
68 }
69
70 if (!empty($_REQUEST['payment_date_from'])) {
71 $filter_args['payment_date_from'] = sanitize_text_field($_REQUEST['payment_date_from']);
72 }
73
74 if (!empty($_REQUEST['payment_date_to'])) {
75 $filter_args['payment_date_to'] = sanitize_text_field($_REQUEST['payment_date_to']);
76 }
77
78 if (!empty($_REQUEST['source'])) {
79 $filter_args['source'] = sanitize_text_field($_REQUEST['source']);
80 }
81
82 if (!empty($_REQUEST['currency'])) {
83 $filter_args['currency'] = sanitize_text_field($_REQUEST['currency']);
84 }
85
86 if (!empty($_REQUEST['status'])) {
87 $filter_args['status'] = sanitize_text_field($_REQUEST['status']);
88 }
89
90 $filter_args['per_page'] = '999999999';
91 // The admin list's v2 tab buckets, so an export of a tab holds exactly the rows that tab
92 // lists. The v1 path matched `completed` against the raw status `completed` only.
93 $all_transactions = $transaction_model->get_transactions($filter_args, 'v2');
94 $filename = 'better-payment-transactions-filtered-' . date('Y-m-d') . '.csv';
95 } else {
96 $all_transactions = $transaction_model->get_transactions();
97 $filename = 'better-payment-transactions-' . date('Y-m-d') . '.csv';
98 }
99
100 return $this->transactions_array_to_csv_download($all_transactions, $filename);
101 }
102
103 /**
104 * Write one CSV row. All CSV writes go through here so none can rely on the
105 * deprecated default $escape.
106 *
107 * @param resource $handle Open, writable stream.
108 * @param array $fields Row values.
109 * @param string $delimiter Field delimiter.
110 * @return int|false Bytes written, or false on failure.
111 */
112 public static function put_csv_row($handle, array $fields, $delimiter = ";") {
113 return fputcsv($handle, $fields, $delimiter, "\"", self::CSV_ESCAPE);
114 }
115
116 public function transactions_array_to_csv_download($array, $filename = "export.csv", $delimiter=";") {
117 $wp_date_format = get_option('date_format');
118 $wp_time_format = get_option('time_format');
119
120 $f = fopen('php://memory', 'w');
121
122 self::put_csv_row($f, $this->export_transactions_heading(), $delimiter);
123
124 foreach ($array as $line) {
125 $line = (array)$line;
126 unset($line['id']);
127 unset($line['order_id']);
128 unset($line['obj_id']);
129 unset($line['refund_info']);
130 unset($line['customer_info']);
131 // unset($line['form_fields_info']);
132 unset($line['referer']);
133
134
135 // From the stored row (form_fields_info still serialized): an unconfirmed pre-2.4.0 free
136 // checkout exports as Incomplete (Helper::transaction_status_type()).
137 $line['status'] = esc_html( ClassesHelper::transaction_status_label( $line ) );
138 $line['source'] = esc_html( ucfirst( $line['source'] ) );
139 $line['payment_date'] = wp_date($wp_date_format.' '.$wp_time_format, strtotime($line['payment_date']));;
140
141 // 'One Time' unless Pro labels the row (better_payment/transaction/payment_type).
142 $line['payment_type'] = ClassesHelper::payment_type_label( maybe_unserialize( $line['form_fields_info'] ) );
143
144 $line['form_fields_info'] = $this->form_fields_info_formatted($line['form_fields_info']);
145
146 $line['form_fields_info_name'] = isset($line['form_fields_info']['customer_name']) ? $line['form_fields_info']['customer_name'] : '';
147 $line['form_fields_info_email'] = isset($line['form_fields_info']['customer_email']) ? $line['form_fields_info']['customer_email'] : '';
148
149 unset($line['form_fields_info']['customer_name']);
150 unset($line['form_fields_info']['customer_email']);
151
152 $line['form_fields_info'] = array_filter($line['form_fields_info'], function($value) {
153 return !empty($value);
154 });
155
156 $line_formatted = array(
157 $line['form_fields_info_name'],
158 $line['form_fields_info_email'],
159 $line['currency'] . ' ' . $line['amount'],
160 $line['payment_type'],
161 $line['transaction_id'],
162 $line['source'],
163 $line['status'],
164 $line['payment_date'],
165 ! empty( $line['form_fields_info'] ) ? maybe_serialize( $line['form_fields_info'] ) : '',
166 );
167
168 self::put_csv_row($f, $line_formatted, $delimiter);
169 }
170
171 // reset the file pointer to the start of the file
172 fseek($f, 0);
173 // tell the browser it's going to be a csv file
174 header('Content-Type: text/csv');
175 // tell the browser we want to save it instead of displaying it
176 header('Content-Disposition: attachment; filename="'.$filename.'";');
177 // make php send the generated csv lines to the browser
178
179 fpassthru($f);
180 exit;
181 }
182
183 public function export_transactions_heading(){
184 return array(
185 esc_html('name'),
186 esc_html('email'),
187 esc_html('amount'),
188 esc_html('payment_type'),
189 esc_html('transaction_id'),
190 esc_html('source'),
191 esc_html('status'),
192 esc_html('payment_date'),
193 esc_html('form_fields_info'),
194 // 'Order ID',
195 // 'Customer Info',
196 // 'Form Fields Info',
197 // 'Currency',
198 // 'Referer'
199 );
200 }
201
202 /**
203 * The fields a transaction contributes to the CSV: customer name and email, plus
204 * whatever `better_payment/export/form_fields_info` adds.
205 *
206 * Pro adds the subscription keys its recurring and split checkouts store; a free
207 * install exports name and email.
208 *
209 * @param mixed $form_fields_info Serialized or unserialized form_fields_info.
210 * @return array
211 */
212 public function form_fields_info_formatted($form_fields_info){
213 $bp_form_fields_info = maybe_unserialize($form_fields_info);
214
215 $bp_transaction_customer_name = isset($bp_form_fields_info['primary_first_name']) ? sanitize_text_field($bp_form_fields_info['primary_first_name']) : '';
216 $bp_transaction_customer_name .= ' ';
217 $bp_transaction_customer_name .= isset($bp_form_fields_info['primary_last_name']) ? sanitize_text_field($bp_form_fields_info['primary_last_name']) : '';
218
219 //legacy
220 if( empty($bp_transaction_customer_name) || $bp_transaction_customer_name == ' ' ){
221 $bp_transaction_customer_name = isset($bp_form_fields_info['first_name']) ? sanitize_text_field($bp_form_fields_info['first_name']) : '';
222 $bp_transaction_customer_name .= ' ';
223 $bp_transaction_customer_name .= isset($bp_form_fields_info['last_name']) ? sanitize_text_field($bp_form_fields_info['last_name']) : '';
224 }
225
226 $bp_transaction_customer_email = isset($bp_form_fields_info['primary_email']) ? sanitize_text_field($bp_form_fields_info['primary_email']) : '';
227 //legacy
228 if( empty($bp_transaction_customer_email) ){
229 $bp_transaction_customer_email = isset($bp_form_fields_info['email']) ? sanitize_text_field($bp_form_fields_info['email']) : '';
230 }
231
232 $formatted = [
233 'customer_name' => $bp_transaction_customer_name,
234 'customer_email' => $bp_transaction_customer_email,
235 ];
236
237 $raw_fields = is_array( $bp_form_fields_info ) ? $bp_form_fields_info : [];
238
239 $filtered = apply_filters( 'better_payment/export/form_fields_info', $formatted, $raw_fields );
240
241 return is_array( $filtered ) ? $filtered : $formatted;
242 }
243
244 }