Test Failed
Push — master ( 36b0ed...c8da5c )
by Devin
09:29 queued 10s
created

Give_Export_Donations_CSV::set_properties()   C

Complexity

Conditions 9
Paths 256

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
nc 256
nop 1
dl 0
loc 23
rs 6.5222
c 0
b 0
f 0
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'] ) );
0 ignored issues
show
Documentation Bug introduced by
It seems like give_clean(wp_parse_args($_POST['form'])) can also be of type string. However, the property $data is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
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 );
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->get_form_ids($request) can also be of type array or boolean. However, the property $form_id is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
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 View Code Duplication
				case 'address':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
				case 'payment_mode':
220
					$cols['payment_mode'] = __( 'Payment Mode', 'give' );
221
					break;
222
				case 'form_id':
223
					$cols['form_id'] = __( 'Form ID', 'give' );
224
					break;
225
				case 'form_title':
226
					$cols['form_title'] = __( 'Form Title', 'give' );
227
					break;
228
				case 'form_level_id':
229
					$cols['form_level_id'] = __( 'Level ID', 'give' );
230
					break;
231
				case 'form_level_title':
232
					$cols['form_level_title'] = __( 'Level Title', 'give' );
233
					break;
234
				case 'donation_date':
235
					$cols['donation_date'] = __( 'Donation Date', 'give' );
236
					break;
237
				case 'donation_time':
238
					$cols['donation_time'] = __( 'Donation Time', 'give' );
239
					break;
240
				case 'userid':
241
					$cols['userid'] = __( 'User ID', 'give' );
242
					break;
243
				case 'donorid':
244
					$cols['donorid'] = __( 'Donor ID', 'give' );
245
					break;
246
				case 'donor_ip':
247
					$cols['donor_ip'] = __( 'Donor IP Address', 'give' );
248
					break;
249
				default:
250
					$cols[ $key ] = $key;
251
252
			}
253
		}
254
255
		/**
256
		 * Filter to get columns name when exporting donation
257
		 *
258
		 * @since 2.1
259
		 *
260
		 * @param array $cols    columns name for CSV
261
		 * @param array $columns columns select by admin to export
262
		 */
263
		return (array) apply_filters( 'give_export_donation_get_columns_name', $cols, $columns );
264
	}
265
266
	/**
267
	 * Get the donation argument
268
	 *
269
	 * @since 2.1
270
	 *
271
	 * @param array $args donation argument
272
	 *
273
	 * @return array $args donation argument
274
	 */
275
	public function get_donation_argument( $args = array() ) {
276
		$defaults = array(
277
			'number' => 30,
278
			'page'   => $this->step,
279
			'status' => $this->status,
280
		);
281
		// Date query.
282
		if ( ! empty( $this->start ) || ! empty( $this->end ) ) {
283
			if ( ! empty( $this->start ) ) {
284
				$defaults['date_query'][0]['after'] = "{$this->start} 00:00:00";
285
			}
286
			if ( ! empty( $this->end ) ) {
287
				$defaults['date_query'][0]['before'] = "{$this->end} 23:59:59";
288
			}
289
		}
290
291
		if ( ! empty( $this->form_id ) ) {
292
			$defaults['give_forms'] = is_array( $this->form_id ) ? $this->form_id : array( $this->form_id );
293
		}
294
295
		/**
296
		 * Filter to modify Payment Query arguments for exporting
297
		 * donations.
298
		 *
299
		 * @since 2.1.3
300
		 */
301
		return apply_filters( 'give_export_donations_donation_query_args', wp_parse_args( $args, $defaults ) );
302
	}
303
304
	/**
305
	 * Get the Export Data.
306
	 *
307
	 * @access public
308
	 *
309
	 * @since  2.1
310
	 *
311
	 * @global object $wpdb Used to query the database using the WordPress database API.
312
	 *
313
	 * @return array $data The data for the CSV file.
314
	 */
315
	public function get_data() {
316
317
		$data = array();
318
		$i    = 0;
319
		// Payment query.
320
		$payments = give_get_payments( $this->get_donation_argument() );
321
322
		if ( $payments ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payments of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
323
324
			foreach ( $payments as $payment ) {
325
326
				$columns      = $this->csv_cols();
327
				$payment      = new Give_Payment( $payment->ID );
328
				$payment_meta = $payment->payment_meta;
329
				$address      = $payment->address;
330
331
				// Set columns.
332
				if ( ! empty( $columns['donation_id'] ) ) {
333
					$data[ $i ]['donation_id'] = $payment->ID;
334
				}
335
336
				if ( ! empty( $columns['seq_id'] ) ) {
337
					$data[ $i ]['seq_id'] = Give()->seq_donation_number->get_serial_code( $payment->ID );
338
				}
339
340
				if ( ! empty( $columns['title_prefix'] ) ) {
341
					$data[ $i ]['title_prefix'] = ! empty( $payment->title_prefix ) ? $payment->title_prefix : '';
342
				}
343
344 View Code Duplication
				if ( ! empty( $columns['first_name'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
345
					$data[ $i ]['first_name'] = isset( $payment->first_name ) ? $payment->first_name : '';
346
				}
347
348 View Code Duplication
				if ( ! empty( $columns['last_name'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
349
					$data[ $i ]['last_name'] = isset( $payment->last_name ) ? $payment->last_name : '';
350
				}
351
352
				if ( ! empty( $columns['email'] ) ) {
353
					$data[ $i ]['email'] = $payment->email;
354
				}
355
356
				if ( ! empty( $columns['company'] ) ) {
357
					$data[ $i ]['company'] = empty( $payment_meta['_give_donation_company'] ) ? '' : str_replace( "\'", "'", $payment_meta['_give_donation_company'] );
358
				}
359
360 View Code Duplication
				if ( ! empty( $columns['address_line1'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
361
					$data[ $i ]['address_line1']   = isset( $address['line1'] ) ? $address['line1'] : '';
362
					$data[ $i ]['address_line2']   = isset( $address['line2'] ) ? $address['line2'] : '';
363
					$data[ $i ]['address_city']    = isset( $address['city'] ) ? $address['city'] : '';
364
					$data[ $i ]['address_state']   = isset( $address['state'] ) ? $address['state'] : '';
365
					$data[ $i ]['address_zip']     = isset( $address['zip'] ) ? $address['zip'] : '';
366
					$data[ $i ]['address_country'] = isset( $address['country'] ) ? $address['country'] : '';
367
				}
368
369
				if ( ! empty( $columns['comment'] ) ) {
370
					$comment               = give_get_donor_donation_comment( $payment->ID, $payment->donor_id );
371
					$data[ $i ]['comment'] = ! empty( $comment ) ? $comment->comment_content : '';
372
				}
373
374
				if ( ! empty( $columns['donation_total'] ) ) {
375
					$data[ $i ]['donation_total'] = give_format_amount( give_donation_amount( $payment->ID ) );
376
				}
377
378
				if ( ! empty( $columns['currency_code'] ) ) {
379
					$data[ $i ]['currency_code'] = empty( $payment_meta['_give_payment_currency'] ) ? give_get_currency() : $payment_meta['_give_payment_currency'];
380
				}
381
382
				if ( ! empty( $columns['currency_symbol'] ) ) {
383
					$currency_code                 = $data[ $i ]['currency_code'];
384
					$data[ $i ]['currency_symbol'] = give_currency_symbol( $currency_code, true );
385
				}
386
387
				if ( ! empty( $columns['donation_status'] ) ) {
388
					$data[ $i ]['donation_status'] = give_get_payment_status( $payment, true );
389
				}
390
391
				if ( ! empty( $columns['payment_gateway'] ) ) {
392
					$data[ $i ]['payment_gateway'] = $payment->gateway;
393
				}
394
395
				if ( ! empty( $columns['payment_mode'] ) ) {
396
					$data[ $i ]['payment_mode'] = $payment->mode;
397
				}
398
399
				if ( ! empty( $columns['form_id'] ) ) {
400
					$data[ $i ]['form_id'] = $payment->form_id;
401
				}
402
403
				if ( ! empty( $columns['form_title'] ) ) {
404
					$data[ $i ]['form_title'] = get_the_title( $payment->form_id );
405
				}
406
407
				if ( ! empty( $columns['form_level_id'] ) ) {
408
					$data[ $i ]['form_level_id'] = $payment->price_id;
409
				}
410
411
				if ( ! empty( $columns['form_level_title'] ) ) {
412
					$var_prices = give_has_variable_prices( $payment->form_id );
413
					if ( empty( $var_prices ) ) {
414
						$data[ $i ]['form_level_title'] = '';
415
					} else {
416
						if ( 'custom' === $payment->price_id ) {
417
							$custom_amount_text = give_get_meta( $payment->form_id, '_give_custom_amount_text', true );
418
419
							if ( empty( $custom_amount_text ) ) {
420
								$custom_amount_text = esc_html__( 'Custom', 'give' );
421
							}
422
							$data[ $i ]['form_level_title'] = $custom_amount_text;
423
						} else {
424
							$data[ $i ]['form_level_title'] = give_get_price_option_name( $payment->form_id, $payment->price_id );
425
						}
426
					}
427
				}
428
429
				if ( ! empty( $columns['donation_date'] ) ) {
430
					$payment_date                = strtotime( $payment->date );
431
					$data[ $i ]['donation_date'] = date( give_date_format(), $payment_date );
432
				}
433
434
				if ( ! empty( $columns['donation_time'] ) ) {
435
					$payment_date                = strtotime( $payment->date );
436
					$data[ $i ]['donation_time'] = date_i18n( 'H', $payment_date ) . ':' . date( 'i', $payment_date );
437
				}
438
439
				if ( ! empty( $columns['userid'] ) ) {
440
					$data[ $i ]['userid'] = $payment->user_id;
441
				}
442
443
				if ( ! empty( $columns['donorid'] ) ) {
444
					$data[ $i ]['donorid'] = $payment->customer_id;
445
				}
446
447
				if ( ! empty( $columns['donor_ip'] ) ) {
448
					$data[ $i ]['donor_ip'] = give_get_payment_user_ip( $payment->ID );
449
				}
450
451
				// Add custom field data.
452
				// First we remove the standard included keys from above.
453
				$remove_keys = array(
454
					'donation_id',
455
					'seq_id',
456
					'first_name',
457
					'last_name',
458
					'email',
459
					'address_line1',
460
					'address_line2',
461
					'address_city',
462
					'address_state',
463
					'address_zip',
464
					'address_country',
465
					'donation_total',
466
					'payment_gateway',
467
					'payment_mode',
468
					'form_id',
469
					'form_title',
470
					'form_level_id',
471
					'form_level_title',
472
					'donation_date',
473
					'donation_time',
474
					'userid',
475
					'donorid',
476
					'donor_ip',
477
				);
478
479
				// Removing above keys...
480
				foreach ( $remove_keys as $key ) {
481
					unset( $columns[ $key ] );
482
				}
483
484
				// Now loop through remaining meta fields.
485
				foreach ( $columns as $col ) {
0 ignored issues
show
Bug introduced by
The expression $columns of type false|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
486
					$field_data         = get_post_meta( $payment->ID, $col, true );
487
					$data[ $i ][ $col ] = $field_data;
488
					unset( $columns[ $col ] );
489
				}
490
491
				/**
492
				 * Filter to modify Donation CSV data when exporting donation
493
				 *
494
				 * @since 2.1
495
				 *
496
				 * @param array Donation data
497
				 * @param Give_Payment              $payment Instance of Give_Payment
498
				 * @param array                     $columns Donation data $columns that are not being merge
499
				 * @param Give_Export_Donations_CSV $this    Instance of Give_Export_Donations_CSV
500
				 *
501
				 * @return array Donation data
502
				 */
503
				$data[ $i ] = apply_filters( 'give_export_donation_data', $data[ $i ], $payment, $columns, $this );
504
505
				$new_data = array();
506
				$old_data = $data[ $i ];
507
508
				// sorting the columns bas on row
509
				foreach ( $this->csv_cols() as $key => $value ) {
0 ignored issues
show
Bug introduced by
The expression $this->csv_cols() of type false|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
510
					if ( array_key_exists( $key, $old_data ) ) {
511
						$new_data[ $key ] = $old_data[ $key ];
512
					}
513
				}
514
515
				$data[ $i ] = $new_data;
516
517
				// Increment iterator.
518
				$i ++;
519
520
			}
521
522
			$data = apply_filters( 'give_export_get_data', $data );
523
			$data = apply_filters( "give_export_get_data_{$this->export_type}", $data );
524
525
			return $data;
526
527
		}
528
529
		return array();
530
531
	}
532
533
	/**
534
	 * Return the calculated completion percentage.
535
	 *
536
	 * @since 2.1
537
	 *
538
	 * @return int
539
	 */
540
	public function get_percentage_complete() {
541
		$args = $this->get_donation_argument( array( 'number' => - 1 ) );
542
		if ( isset( $args['page'] ) ) {
543
			unset( $args['page'] );
544
		}
545
		$query      = give_get_payments( $args );
546
		$total      = count( $query );
547
		$percentage = 100;
548
		if ( $total > 0 ) {
549
			$percentage = ( ( 30 * $this->step ) / $total ) * 100;
550
		}
551
		if ( $percentage > 100 ) {
552
			$percentage = 100;
553
		}
554
555
		return $percentage;
556
	}
557
558
	/**
559
	 * Print the CSV rows for the current step.
560
	 *
561
	 * @access public
562
	 *
563
	 * @since  2.1
564
	 *
565
	 * @return string|false
566
	 */
567 View Code Duplication
	public function print_csv_rows() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
568
569
		$row_data = '';
570
		$data     = $this->get_data();
571
		$cols     = $this->get_csv_cols();
572
573
		if ( $data ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
574
575
			// Output each row
576
			foreach ( $data as $row ) {
577
				$i = 1;
578
				foreach ( $row as $col_id => $column ) {
579
					// Make sure the column is valid
580
					if ( array_key_exists( $col_id, $cols ) ) {
581
						$row_data .= '"' . preg_replace( '/"/', "'", $column ) . '"';
582
						$row_data .= $i == count( $cols ) ? '' : ',';
583
						$i ++;
584
					}
585
				}
586
				$row_data .= "\r\n";
587
			}
588
589
			$this->stash_step_data( $row_data );
590
591
			return $row_data;
592
		}
593
594
		return false;
595
	}
596
}
597