PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 3.6.1
GiveWP – Donation Plugin and Fundraising Platform v3.6.1
4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / admin / tools / export / give-export-donations-exporter.php
give / includes / admin / tools / export Last commit date
class-batch-export-donors.php 5 years ago class-batch-export.php 4 years ago class-core-settings-export.php 7 years ago class-export-earnings.php 3 years ago class-export.php 3 years ago class-give-export-donations.php 5 years ago export-actions.php 3 years ago export-functions.php 4 years ago give-export-donations-exporter.php 3 years ago give-export-donations-functions.php 5 years ago pdf-reports.php 5 years ago
give-export-donations-exporter.php
691 lines
1 <?php
2 /**
3 * Payments Export Class.
4 *
5 * This class handles payment export in batches.
6 *
7 * @package Give
8 * @subpackage Admin/Reports
9 * @copyright Copyright (c) 2016, GiveWP
10 * @license https://opensource.org/licenses/gpl-license GNU Public License
11 * @since 2.1
12 */
13
14 // Exit if accessed directly.
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 /**
20 * Give_Export_Donations_CSV Class
21 *
22 * @since 2.1
23 */
24 class Give_Export_Donations_CSV extends Give_Batch_Export {
25
26 /**
27 * Our export type. Used for export-type specific filters/actions.
28 *
29 * @since 2.1
30 *
31 * @var string
32 */
33 public $export_type = 'payments';
34
35 /**
36 * Form submission data.
37 *
38 * @since 2.1
39 *
40 * @var array
41 */
42 public $data = array();
43
44 /**
45 * Form submission data.
46 *
47 * @since 2.1
48 *
49 * @var array
50 */
51 public $cols = array();
52
53 /**
54 * Form ID.
55 *
56 * @since 2.1
57 *
58 * @var string
59 */
60 public $form_id = '';
61
62 /**
63 * Form tags ids.
64 *
65 * @since 2.1
66 *
67 * @var array
68 */
69 public $tags = '';
70
71
72 /**
73 * Form categories ids.
74 *
75 * @since 2.1
76 *
77 * @var array
78 */
79 public $categories = '';
80
81 /**
82 * Set the properties specific to the export.
83 *
84 * @since 2.1
85 *
86 * @param array $request The Form Data passed into the batch processing.
87 */
88 public function set_properties( $request ) {
89
90 // Set data from form submission
91 if ( isset( $_POST['form'] ) ) {
92 $this->data = give_clean( wp_parse_args( $_POST['form'] ) );
93 }
94
95 $this->form = $this->data['forms'];
96 $this->categories = ! empty( $request['give_forms_categories'] ) ? (array) $request['give_forms_categories'] : array();
97 $this->tags = ! empty( $request['give_forms_tags'] ) ? (array) $request['give_forms_tags'] : array();
98 $this->form_id = $this->get_form_ids( $request );
99 $this->price_id = isset( $request['give_price_option'] ) && ! in_array( $this->price_id, array( 'all', '' ) ) ? absint( $request['give_price_option'] ) : null;
100 $this->start = ! empty( $request['start'] ) ? date( 'Y-m-d', strtotime( $request['start'] ) ) : '';
101 $this->end = ! empty( $request['end'] ) ? date( 'Y-m-d', strtotime( $request['end'] ) ) : '';
102 $this->status = isset( $request['status'] ) ? sanitize_text_field( $request['status'] ) : 'complete';
103
104 /**
105 * Hook to use after setting properties.
106 *
107 * @since 2.1.3
108 */
109 do_action( 'give_export_donations_form_data', $this->data );
110 }
111
112 /**
113 * Get donation form id list
114 *
115 * @since 2.1
116 *
117 * @param array $request form data that need to be exported
118 *
119 * @return array|boolean|null $form get all the donation id that need to be exported
120 */
121 public function get_form_ids( $request = array() ) {
122 $form = ! empty( $request['forms'] ) && 0 !== $request['forms'] ? absint( $request['forms'] ) : null;
123
124 $form_ids = ! empty( $request['form_ids'] ) ? sanitize_text_field( $request['form_ids'] ) : null;
125
126 if ( empty( $form ) && ! empty( $form_ids ) && ( ! empty( $this->categories ) || ! empty( $this->tags ) ) ) {
127 $form = explode( ',', $form_ids );
128 }
129
130 return $form;
131 }
132
133 /**
134 * Set the CSV columns.
135 *
136 * @access public
137 *
138 * @since 2.1
139 *
140 * @return array|bool $cols All the columns.
141 */
142 public function csv_cols() {
143
144 $columns = isset( $this->data['give_give_donations_export_option'] ) ? $this->data['give_give_donations_export_option'] : array();
145
146 // We need columns.
147 if ( empty( $columns ) ) {
148 return false;
149 }
150
151 $this->cols = $this->get_cols( $columns );
152
153 return $this->cols;
154 }
155
156
157 /**
158 * CSV file columns.
159 *
160 * @since 2.1
161 *
162 * @param array $columns
163 *
164 * @return array
165 */
166 private function get_cols( $columns ) {
167
168 $cols = array();
169
170 foreach ( $columns as $key => $value ) {
171
172 switch ( $key ) {
173 case 'donation_id':
174 $cols['donation_id'] = __( 'Donation ID', 'give' );
175 break;
176 case 'seq_id':
177 $cols['seq_id'] = __( 'Donation Number', 'give' );
178 break;
179 case 'title_prefix':
180 $cols['title_prefix'] = __( 'Title Prefix', 'give' );
181 break;
182 case 'first_name':
183 $cols['first_name'] = __( 'First Name', 'give' );
184 break;
185 case 'last_name':
186 $cols['last_name'] = __( 'Last Name', 'give' );
187 break;
188 case 'email':
189 $cols['email'] = __( 'Email Address', 'give' );
190 break;
191 case 'company':
192 $cols['company'] = __( 'Company Name', 'give' );
193 break;
194 case 'address':
195 $cols['address_line1'] = __( 'Address 1', 'give' );
196 $cols['address_line2'] = __( 'Address 2', 'give' );
197 $cols['address_city'] = __( 'City', 'give' );
198 $cols['address_state'] = __( 'State', 'give' );
199 $cols['address_zip'] = __( 'Zip', 'give' );
200 $cols['address_country'] = __( 'Country', 'give' );
201 break;
202 case 'comment':
203 $cols['comment'] = __( 'Donor Comment', 'give' );
204 break;
205 case 'donation_total':
206 $cols['donation_total'] = __( 'Donation Total', 'give' );
207 break;
208 case 'currency_code':
209 $cols['currency_code'] = __( 'Currency Code', 'give' );
210 break;
211 case 'currency_symbol':
212 $cols['currency_symbol'] = __( 'Currency Symbol', 'give' );
213 break;
214 case 'donation_status':
215 $cols['donation_status'] = __( 'Donation Status', 'give' );
216 break;
217 case 'payment_gateway':
218 $cols['payment_gateway'] = __( 'Payment Gateway', 'give' );
219 break;
220 case 'payment_mode':
221 $cols['payment_mode'] = __( 'Payment Mode', 'give' );
222 break;
223 case 'form_id':
224 $cols['form_id'] = __( 'Form ID', 'give' );
225 break;
226 case 'form_title':
227 $cols['form_title'] = __( 'Form Title', 'give' );
228 break;
229 case 'form_level_id':
230 $cols['form_level_id'] = __( 'Level ID', 'give' );
231 break;
232 case 'form_level_title':
233 $cols['form_level_title'] = __( 'Level Title', 'give' );
234 break;
235 case 'donation_date':
236 $cols['donation_date'] = __( 'Donation Date', 'give' );
237 break;
238 case 'donation_time':
239 $cols['donation_time'] = __( 'Donation Time', 'give' );
240 break;
241 case 'userid':
242 $cols['userid'] = __( 'User ID', 'give' );
243 break;
244 case 'donorid':
245 $cols['donorid'] = __( 'Donor ID', 'give' );
246 break;
247 case 'donor_ip':
248 $cols['donor_ip'] = __( 'Donor IP Address', 'give' );
249 break;
250 case 'donation_note_private':
251 $cols['donation_note_private'] = __( 'Donation Note (private)', 'give' );
252 break;
253 case 'donation_note_to_donor':
254 $cols['donation_note_to_donor'] = __( 'Donation Note (to donor)', 'give' );
255 break;
256 default:
257 $cols[ $key ] = $key;
258
259 }
260 }
261
262 /**
263 * Filter to get columns name when exporting donation
264 *
265 * @since 2.1
266 *
267 * @param array $cols columns name for CSV
268 * @param array $columns columns select by admin to export
269 */
270 return (array) apply_filters( 'give_export_donation_get_columns_name', $cols, $columns );
271 }
272
273 /**
274 * Get the donation argument
275 *
276 * @since 2.1
277 *
278 * @param array $args donation argument
279 *
280 * @return array $args donation argument
281 */
282 public function get_donation_argument( $args = array() ) {
283 $defaults = array(
284 'number' => 30,
285 'page' => $this->step,
286 'status' => $this->status,
287 'order' => 'ASC',
288 );
289 // Date query.
290 if ( ! empty( $this->start ) || ! empty( $this->end ) ) {
291 if ( ! empty( $this->start ) ) {
292 $defaults['date_query'][0]['after'] = "{$this->start} 00:00:00";
293 }
294 if ( ! empty( $this->end ) ) {
295 $defaults['date_query'][0]['before'] = "{$this->end} 23:59:59";
296 }
297 }
298
299 if ( ! empty( $this->form_id ) ) {
300 $defaults['give_forms'] = is_array( $this->form_id ) ? $this->form_id : array( $this->form_id );
301 }
302
303 /**
304 * Filter to modify Payment Query arguments for exporting
305 * donations.
306 *
307 * @since 2.1.3
308 */
309 return apply_filters( 'give_export_donations_donation_query_args', wp_parse_args( $args, $defaults ) );
310 }
311
312 /**
313 * Get the Export Data.
314 *
315 * @access public
316 *
317 * @since 2.1
318 *
319 * @global object $wpdb Used to query the database using the WordPress database API.
320 *
321 * @return array $data The data for the CSV file.
322 */
323 public function get_data() {
324
325 $data = array();
326 $i = 0;
327 // Payment query.
328 $payments = give_get_payments( $this->get_donation_argument() );
329
330 if ( $payments ) {
331
332 foreach ( $payments as $payment ) {
333
334 $columns = $this->csv_cols();
335 $payment = new Give_Payment( $payment->ID );
336 $payment_meta = $payment->payment_meta;
337 $address = $payment->address;
338
339 // Set columns.
340 if ( ! empty( $columns['donation_id'] ) ) {
341 $data[ $i ]['donation_id'] = $payment->ID;
342 }
343
344 if ( ! empty( $columns['seq_id'] ) ) {
345 $data[ $i ]['seq_id'] = Give()->seq_donation_number->get_serial_code( $payment->ID );
346 }
347
348 if ( ! empty( $columns['title_prefix'] ) ) {
349 $data[ $i ]['title_prefix'] = ! empty( $payment->title_prefix ) ? $payment->title_prefix : '';
350 }
351
352 if ( ! empty( $columns['first_name'] ) ) {
353 $data[ $i ]['first_name'] = isset( $payment->first_name ) ? $payment->first_name : '';
354 }
355
356 if ( ! empty( $columns['last_name'] ) ) {
357 $data[ $i ]['last_name'] = isset( $payment->last_name ) ? $payment->last_name : '';
358 }
359
360 if ( ! empty( $columns['email'] ) ) {
361 $data[ $i ]['email'] = $payment->email;
362 }
363
364 if ( ! empty( $columns['company'] ) ) {
365 $data[ $i ]['company'] = empty( $payment_meta['_give_donation_company'] ) ? '' : str_replace( "\'", "'", $payment_meta['_give_donation_company'] );
366 }
367
368 if ( ! empty( $columns['address_line1'] ) ) {
369 $data[ $i ]['address_line1'] = isset( $address['line1'] ) ? $address['line1'] : '';
370 $data[ $i ]['address_line2'] = isset( $address['line2'] ) ? $address['line2'] : '';
371 $data[ $i ]['address_city'] = isset( $address['city'] ) ? $address['city'] : '';
372 $data[ $i ]['address_state'] = isset( $address['state'] ) ? $address['state'] : '';
373 $data[ $i ]['address_zip'] = isset( $address['zip'] ) ? $address['zip'] : '';
374 $data[ $i ]['address_country'] = isset( $address['country'] ) ? $address['country'] : '';
375 }
376
377 if ( ! empty( $columns['comment'] ) ) {
378 $comment = give_get_donor_donation_comment( $payment->ID, $payment->donor_id );
379 $data[ $i ]['comment'] = ! empty( $comment ) ? $comment->comment_content : '';
380 }
381
382 if ( ! empty( $columns['donation_total'] ) ) {
383 $data[ $i ]['donation_total'] = give_format_amount( give_donation_amount( $payment->ID ) );
384 }
385
386 if ( ! empty( $columns['currency_code'] ) ) {
387 $data[ $i ]['currency_code'] = empty( $payment_meta['_give_payment_currency'] ) ? give_get_currency() : $payment_meta['_give_payment_currency'];
388 }
389
390 if ( ! empty( $columns['currency_symbol'] ) ) {
391 $currency_code = $data[ $i ]['currency_code'];
392 $data[ $i ]['currency_symbol'] = give_currency_symbol( $currency_code, true );
393 }
394
395 if ( ! empty( $columns['donation_status'] ) ) {
396 $data[ $i ]['donation_status'] = give_get_payment_status( $payment, true );
397 }
398
399 if ( ! empty( $columns['payment_gateway'] ) ) {
400 $data[ $i ]['payment_gateway'] = $payment->gateway;
401 }
402
403 if ( ! empty( $columns['payment_mode'] ) ) {
404 $data[ $i ]['payment_mode'] = $payment->mode;
405 }
406
407 if ( ! empty( $columns['form_id'] ) ) {
408 $data[ $i ]['form_id'] = $payment->form_id;
409 }
410
411 if ( ! empty( $columns['form_title'] ) ) {
412 $data[ $i ]['form_title'] = get_the_title( $payment->form_id );
413 }
414
415 if ( ! empty( $columns['form_level_id'] ) ) {
416 $data[ $i ]['form_level_id'] = $payment->price_id;
417 }
418
419 if ( ! empty( $columns['form_level_title'] ) ) {
420 $var_prices = give_has_variable_prices( $payment->form_id );
421 if ( empty( $var_prices ) ) {
422 $data[ $i ]['form_level_title'] = '';
423 } else {
424 if ( 'custom' === $payment->price_id ) {
425 $custom_amount_text = give_get_meta( $payment->form_id, '_give_custom_amount_text', true );
426
427 if ( empty( $custom_amount_text ) ) {
428 $custom_amount_text = esc_html__( 'Custom Amount', 'give' );
429 }
430 $data[ $i ]['form_level_title'] = $custom_amount_text;
431 } else {
432 $data[ $i ]['form_level_title'] = give_get_price_option_name( $payment->form_id, $payment->price_id );
433 }
434 }
435 }
436
437 if ( ! empty( $columns['donation_date'] ) ) {
438 $payment_date = strtotime( $payment->date );
439 $data[ $i ]['donation_date'] = date( give_date_format(), $payment_date );
440 }
441
442 if ( ! empty( $columns['donation_time'] ) ) {
443 $payment_date = strtotime( $payment->date );
444 $data[ $i ]['donation_time'] = date_i18n( 'H', $payment_date ) . ':' . date( 'i', $payment_date );
445 }
446
447 if ( ! empty( $columns['userid'] ) ) {
448 $data[ $i ]['userid'] = $payment->user_id;
449 }
450
451 if ( ! empty( $columns['donorid'] ) ) {
452 $data[ $i ]['donorid'] = $payment->customer_id;
453 }
454
455 if ( ! empty( $columns['donor_ip'] ) ) {
456 $data[ $i ]['donor_ip'] = give_get_payment_user_ip( $payment->ID );
457 }
458
459 if ( ! empty( $columns['donation_note_private'] ) ) {
460 $comments = Give()->comment->db->get_comments(
461 array(
462 'comment_parent' => $payment->ID,
463 'comment_type' => 'donation',
464 'meta_query' => array(
465 'relation' => 'OR',
466 array(
467 'key' => 'note_type',
468 'compare' => 'NOT EXISTS',
469 ),
470 array(
471 'key' => 'note_type',
472 'value' => 'donor',
473 'compare' => '!=',
474 ),
475 ),
476 )
477 );
478
479 $comment_html = array();
480
481 if ( ! empty( $comments ) ) {
482 foreach ( $comments as $comment ) {
483 $comment_html[] = sprintf(
484 '%s - %s',
485 date( 'Y-m-d', strtotime( $comment->comment_date ) ),
486 $comment->comment_content
487 );
488 }
489 }
490
491 $data[ $i ]['donation_note_private'] = implode( "\n", $comment_html );
492 }
493
494 if ( ! empty( $columns['donation_note_to_donor'] ) ) {
495 $comments = Give()->comment->db->get_comments(
496 array(
497 'comment_parent' => $payment->ID,
498 'comment_type' => 'donation',
499 'meta_query' => array(
500 array(
501 'key' => 'note_type',
502 'value' => 'donor',
503 ),
504 ),
505 )
506 );
507
508 $comment_html = array();
509
510 if ( ! empty( $comments ) ) {
511 foreach ( $comments as $comment ) {
512 $comment_html[] = sprintf(
513 '%s - %s',
514 date( 'Y-m-d', strtotime( $comment->comment_date ) ),
515 $comment->comment_content
516 );
517 }
518 }
519 $data[ $i ]['donation_note_to_donor'] = implode( "\n", $comment_html );
520 }
521
522 // Add custom field data.
523 // First we remove the standard included keys from above.
524 $remove_keys = array(
525 'donation_id',
526 'seq_id',
527 'first_name',
528 'last_name',
529 'email',
530 'address_line1',
531 'address_line2',
532 'address_city',
533 'address_state',
534 'address_zip',
535 'address_country',
536 'donation_total',
537 'payment_gateway',
538 'payment_mode',
539 'form_id',
540 'form_title',
541 'form_level_id',
542 'form_level_title',
543 'donation_date',
544 'donation_time',
545 'userid',
546 'donorid',
547 'donor_ip',
548 );
549
550 // Removing above keys...
551 foreach ( $remove_keys as $key ) {
552 unset( $columns[ $key ] );
553 }
554
555 // Now loop through remaining meta fields.
556 foreach ( $columns as $col ) {
557 $field_data = get_post_meta( $payment->ID, $col, true );
558 $data[ $i ][ $col ] = $field_data;
559 unset( $columns[ $col ] );
560 }
561
562 /**
563 * Filter to modify Donation CSV data when exporting donation
564 *
565 * @since 2.1
566 *
567 * @param array Donation data
568 * @param Give_Payment $payment Instance of Give_Payment
569 * @param array $columns Donation data $columns that are not being merge
570 * @param Give_Export_Donations_CSV $this Instance of Give_Export_Donations_CSV
571 *
572 * @return array Donation data
573 */
574 $data[ $i ] = apply_filters( 'give_export_donation_data', $data[ $i ], $payment, $columns, $this );
575
576 $new_data = array();
577 $old_data = $data[ $i ];
578
579 // sorting the columns bas on row
580 foreach ( $this->csv_cols() as $key => $value ) {
581 if ( array_key_exists( $key, $old_data ) ) {
582 $new_data[ $key ] = $old_data[ $key ];
583 }
584 }
585
586 $data[ $i ] = $new_data;
587
588 // Increment iterator.
589 $i ++;
590
591 }
592
593 $data = apply_filters( 'give_export_get_data', $data );
594 $data = apply_filters( "give_export_get_data_{$this->export_type}", $data );
595
596 return $data;
597
598 }
599
600 return array();
601
602 }
603
604 /**
605 * Return the calculated completion percentage.
606 *
607 * @since 2.1
608 *
609 * @return int
610 */
611 public function get_percentage_complete() {
612 $args = $this->get_donation_argument(
613 array(
614 'number' => - 1,
615 'output' => '',
616 )
617 );
618 if ( isset( $args['page'] ) ) {
619 unset( $args['page'] );
620 }
621 $query = give_get_payments( $args );
622 $total = count( $query );
623 $percentage = 100;
624 if ( $total > 0 ) {
625 $percentage = ( ( 30 * $this->step ) / $total ) * 100;
626 }
627 if ( $percentage > 100 ) {
628 $percentage = 100;
629 }
630
631 return $percentage;
632 }
633
634 /**
635 * Print the CSV rows for the current step.
636 *
637 * @access public
638 *
639 * @since 2.1
640 *
641 * @return string|false
642 */
643 public function print_csv_rows() {
644
645 $row_data = '';
646 $data = $this->get_data();
647 $cols = $this->get_csv_cols();
648
649 if ( $data ) {
650
651 // Output each row
652 foreach ( $data as $row ) {
653 $i = 1;
654 foreach ( $row as $col_id => $column ) {
655 // Make sure the column is valid
656 if ( array_key_exists( $col_id, $cols ) ) {
657 $row_data .= '"' . $this->escape_csv_cell_data(preg_replace( '/"/', "'", $column )) . '"';
658 $row_data .= $i == count( $cols ) ? '' : ',';
659 $i ++;
660 }
661 }
662 $row_data .= "\r\n";
663 }
664
665 $this->stash_step_data( $row_data );
666
667 return $row_data;
668 }
669
670 return false;
671 }
672
673 /**
674 * Escapes CSV cell data to protect against CSV injection.
675 * @link https://owasp.org/www-community/attacks/CSV_Injection
676 *
677 * @since 2.25.2
678 *
679 * @param mixed|string $cellData
680 *
681 * @return mixed|string
682 */
683 protected function escape_csv_cell_data($cellData) {
684 $firstCharacter = substr($cellData, 0, 1);
685 if( in_array($firstCharacter, array('=', '+', '-', '@')) ) {
686 $cellData = "'" . $cellData;
687 }
688 return $cellData;
689 }
690 }
691