Completed
Push — issue/3029 ( b03a10 )
by Ravinder
733:46 queued 726:39
created

Give_Import_Donations   F

Complexity

Total Complexity 122

Size/Duplication

Total Lines 1034
Duplicated Lines 4.45 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 0
Metric Value
dl 46
loc 1034
rs 1.464
c 0
b 0
f 0
wmc 122
lcom 2
cbo 1

27 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 2
A get_instance() 0 7 2
A setup() 0 3 1
A setup_hooks() 23 23 2
A update_notices() 7 7 3
A submit() 0 8 1
B html() 0 65 8
F import_success() 0 119 13
B start_import() 0 61 3
B check_for_dropdown_or_import() 0 24 7
B render_dropdown() 0 89 5
A selected() 0 13 4
A get_columns() 0 37 2
B get_dropdown_option_html() 0 23 6
A get_csv_total() 0 13 3
A get_importer() 0 24 4
A remove_utf8_bom() 0 7 2
A render_progress() 0 19 5
B get_step() 16 16 7
A render_page() 0 3 1
A give_import_donation_submit_button_render_media_csv() 0 18 2
A give_import_donation_submit_text_render_media_csv() 0 3 1
F render_media_csv() 0 124 14
C save() 0 32 12
B is_valid_csv() 0 23 8
A render_import_field() 0 3 1
A is_donations_import_page() 0 5 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Give_Import_Donations often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Give_Import_Donations, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Donations Import Class
4
 *
5
 * This class handles donations import.
6
 *
7
 * @package     Give
8
 * @subpackage  Classes/Give_Import_Donations
9
 * @copyright   Copyright (c) 2017, WordImpress
10
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
11
 * @since       1.8.14
12
 */
13
14
if ( ! defined( 'ABSPATH' ) ) {
15
	exit; // Exit if accessed directly
16
}
17
18
if ( ! class_exists( 'Give_Import_Donations' ) ) {
19
20
	/**
21
	 * Give_Import_Donations.
22
	 *
23
	 * @since 1.8.14
24
	 */
25
	final class Give_Import_Donations {
26
27
		/**
28
		 * Importer type
29
		 *
30
		 * @since 1.8.13
31
		 * @var string
32
		 */
33
		private $importer_type = 'import_donations';
34
35
		/**
36
		 * Instance.
37
		 *
38
		 * @since
39
		 * @access private
40
		 * @var
41
		 */
42
		static private $instance;
43
44
		/**
45
		 * Importing donation per page.
46
		 *
47
		 * @since 1.8.14
48
		 *
49
		 * @var   int
50
		 */
51
		public static $per_page = 25;
52
53
		/**
54
		 * Importing donation per page.
55
		 *
56
		 * @since 2.1
57
		 *
58
		 * @var   int
59
		 */
60
		public $is_csv_valid = false;
61
62
		/**
63
		 * Singleton pattern.
64
		 *
65
		 * @since
66
		 * @access private
67
		 */
68
		private function __construct() {
69
			self::$per_page = ! empty( $_GET['per_page'] ) ? absint( $_GET['per_page'] ) : self::$per_page;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
70
		}
71
72
		/**
73
		 * Get instance.
74
		 *
75
		 * @since
76
		 * @access public
77
		 *
78
		 * @return static
79
		 */
80
		public static function get_instance() {
81
			if ( null === static::$instance ) {
82
				self::$instance = new static();
83
			}
84
85
			return self::$instance;
86
		}
87
88
		/**
89
		 * Setup
90
		 *
91
		 * @since 1.8.14
92
		 *
93
		 * @return void
94
		 */
95
		public function setup() {
96
			$this->setup_hooks();
97
		}
98
99
100
		/**
101
		 * Setup Hooks.
102
		 *
103
		 * @since 1.8.14
104
		 *
105
		 * @return void
106
		 */
107 View Code Duplication
		private function setup_hooks() {
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...
108
			if ( ! $this->is_donations_import_page() ) {
109
				return;
110
			}
111
112
			// Do not render main import tools page.
113
			remove_action( 'give_admin_field_tools_import', array( 'Give_Settings_Import', 'render_import_field', ) );
114
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
115
116
			// Render donation import page
117
			add_action( 'give_admin_field_tools_import', array( $this, 'render_page' ) );
118
119
			// Print the HTML.
120
			add_action( 'give_tools_import_donations_form_start', array( $this, 'html' ), 10 );
121
122
			// Run when form submit.
123
			add_action( 'give-tools_save_import', array( $this, 'save' ) );
124
125
			add_action( 'give-tools_update_notices', array( $this, 'update_notices' ), 11, 1 );
126
127
			// Used to add submit button.
128
			add_action( 'give_tools_import_donations_form_end', array( $this, 'submit' ), 10 );
129
		}
130
131
		/**
132
		 * Update notice
133
		 *
134
		 * @since 1.8.14
135
		 *
136
		 * @param $messages
137
		 *
138
		 * @return mixed
139
		 */
140 View Code Duplication
		public function update_notices( $messages ) {
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...
141
			if ( ! empty( $_GET['tab'] ) && 'import' === give_clean( $_GET['tab'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
142
				unset( $messages['give-setting-updated'] );
143
			}
144
145
			return $messages;
146
		}
147
148
		/**
149
		 * Print submit and nonce button.
150
		 *
151
		 * @since 1.8.14
152
		 */
153
		public function submit() {
154
			wp_nonce_field( 'give-save-settings', '_give-save-settings' );
155
			?>
156
			<input type="hidden" class="import-step" id="import-step" name="step"
157
			       value="<?php echo $this->get_step(); ?>"/>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
158
			<input type="hidden" class="importer-type" value="<?php echo $this->importer_type; ?>"/>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
159
			<?php
160
		}
161
162
		/**
163
		 * Print the HTML for importer.
164
		 *
165
		 * @since 1.8.14
166
		 */
167
		public function html() {
168
			$step = $this->get_step();
169
170
			// Show progress.
171
			$this->render_progress();
172
			?>
173
			<section>
174
				<table
175
					class="widefat export-options-table give-table <?php echo "step-{$step}"; ?> <?php echo( 1 === $step && ! empty( $this->is_csv_valid ) ? 'give-hidden' : '' ); ?>  "
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '"step-{$step}"'
Loading history...
introduced by
Expected next thing to be a escaping function, not '('
Loading history...
176
					id="<?php echo "step-{$step}"; ?>">
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '"step-{$step}"'
Loading history...
177
					<tbody>
178
					<?php
179
					switch ( $step ) {
180
						case 1:
181
							$this->render_media_csv();
182
							break;
183
184
						case 2:
185
							$this->render_dropdown();
186
							break;
187
188
						case 3:
189
							$this->start_import();
190
							break;
191
192
						case 4:
193
							$this->import_success();
194
					}
195
					if ( false === $this->check_for_dropdown_or_import() ) {
196
						?>
197
						<tr valign="top">
198
							<th>
199
								<input type="submit"
200
								       class="button button-primary button-large button-secondary <?php echo "step-{$step}"; ?>"
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '"step-{$step}"'
Loading history...
201
								       id="recount-stats-submit"
202
								       value="
203
									       <?php
204
								       /**
205
								        * Filter to modify donation importer submit button text.
206
								        *
207
								        * @since 2.1
208
								        */
209
								       echo apply_filters( 'give_import_donation_submit_button_text', __( 'Submit', 'give' ) );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'apply_filters'
Loading history...
210
								       ?>
211
											"/>
212
							</th>
213
							<th>
214
								<?php
215
								/**
216
								 * Action to add submit button description.
217
								 *
218
								 * @since 2.1
219
								 */
220
								do_action( 'give_import_donation_submit_button' );
221
								?>
222
							</th>
223
						</tr>
224
						<?php
225
					}
226
					?>
227
					</tbody>
228
				</table>
229
			</section>
230
			<?php
231
		}
232
233
		/**
234
		 * Show success notice
235
		 *
236
		 * @since 1.8.14
237
		 */
238
		public function import_success() {
239
240
			$delete_csv = ( ! empty( $_GET['delete_csv'] ) ? absint( $_GET['delete_csv'] ) : false );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
241
			$csv        = ( ! empty( $_GET['csv'] ) ? absint( $_GET['csv'] ) : false );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
242
			if ( ! empty( $delete_csv ) && ! empty( $csv ) ) {
243
				wp_delete_attachment( $csv, true );
244
			}
245
246
			$report = give_import_donation_report();
247
248
			$report_html = array(
249
				'duplicate_donor'    => array(
250
					__( '%s duplicate %s detected', 'give' ),
251
					__( '%s duplicate %s will be detected', 'give' ),
252
					__( 'donor', 'give' ),
253
					__( 'donors', 'give' ),
254
				),
255
				'create_donor'       => array(
256
					__( '%s %s created', 'give' ),
257
					__( '%s %s will be going to get created', 'give' ),
258
					__( 'donor', 'give' ),
259
					__( 'donors', 'give' ),
260
				),
261
				'create_form'        => array(
262
					__( '%s donation %s created', 'give' ),
263
					__( '%s donation %s will be going to get created', 'give' ),
264
					__( 'form', 'give' ),
265
					__( 'forms', 'give' ),
266
				),
267
				'duplicate_donation' => array(
268
					__( '%s duplicate %s detected', 'give' ),
269
					__( '%s duplicate %s will be detected', 'give' ),
270
					__( 'donation', 'give' ),
271
					__( 'donations', 'give' ),
272
				),
273
				'create_donation'    => array(
274
					__( '%s %s imported', 'give' ),
275
					__( '%s %s will going to get imported', 'give' ),
276
					__( 'donation', 'give' ),
277
					__( 'donations', 'give' ),
278
				),
279
			);
280
			$total       = (int) $_GET['total'];
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_GET
Loading history...
281
			-- $total;
282
			$success = (bool) $_GET['success'];
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_GET
Loading history...
283
			$dry_run = empty( $_GET['dry_run'] ) ? 0 : absint( $_GET['dry_run'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
284
			?>
285
			<tr valign="top" class="give-import-dropdown">
286
				<th colspan="2">
287
					<h2>
288
						<?php
289
						if ( $success ) {
290
							if ( $dry_run ) {
291
								printf(
292
									_n( 'Dry run import complete! %s donation processed', 'Dry run import complete! %s donations processed', $total, 'give' ),
293
									"<strong>{$total}</strong>"
294
								);
295
							} else {
296
								printf(
297
									_n( 'Import complete! %s donation processed', 'Import complete! %s donations processed', $total, 'give' ),
298
									"<strong>{$total}</strong>"
299
								);
300
							}
301
						} else {
302
							printf(
303
								_n( 'Failed to import %s donation', 'Failed to import %s donations', $total, 'give' ),
304
								"<strong>{$total}</strong>"
305
							);
306
						}
307
						?>
308
					</h2>
309
310
					<?php
311
					$text      = __( 'Import Donation', 'give' );
312
					$query_arg = array(
313
						'post_type' => 'give_forms',
314
						'page'      => 'give-tools',
315
						'tab'       => 'import',
316
					);
317
					if ( $success ) {
318
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
319
320
						if ( $dry_run ) {
321
							$query_arg = array(
322
								'post_type'     => 'give_forms',
323
								'page'          => 'give-tools',
324
								'tab'           => 'import',
325
								'importer-type' => 'import_donations',
326
							);
327
328
							$text      = __( 'Start Import', 'give' );
329
						} else {
330
							$query_arg = array(
331
								'post_type' => 'give_forms',
332
								'page'      => 'give-payment-history',
333
							);
334
							$text      = __( 'View Donations', 'give' );
335
						}
336
					}
337
338
					foreach ( $report as $key => $value ) {
339
						if ( array_key_exists( $key, $report_html ) && ! empty( $value ) ) {
340
							?>
341
							<p>
342
								<?php printf( $report_html[ $key ][$dry_run], $value, _n( $report_html[ $key ][2], $report_html[ $key ][3], $value, 'give' ) ); ?>
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
introduced by
Expected next thing to be a escaping function, not '$report_html'
Loading history...
343
							</p>
344
							<?php
345
						}
346
					}
347
					?>
348
349
					<p>
350
						<a class="button button-large button-secondary"
351
						   href="<?php echo add_query_arg( $query_arg, admin_url( 'edit.php' ) ); ?>"><?php echo $text; ?></a>
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'add_query_arg'
Loading history...
introduced by
Expected next thing to be a escaping function, not '$text'
Loading history...
352
					</p>
353
				</th>
354
			</tr>
355
			<?php
356
		}
357
358
		/**
359
		 * Will start Import
360
		 *
361
		 * @since 1.8.14
362
		 */
363
		public function start_import() {
364
			// Reset the donation form report.
365
			give_import_donation_report_reset();
366
367
			$csv         = (int) $_REQUEST['csv'];
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_REQUEST
Loading history...
368
			$delimiter   = ( ! empty( $_REQUEST['delimiter'] ) ? give_clean( $_REQUEST['delimiter'] ) : 'csv' );
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
369
			$index_start = 1;
370
			$index_end   = 1;
0 ignored issues
show
Unused Code introduced by
$index_end is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
371
			$next        = true;
372
			$total       = self::get_csv_total( $csv );
373
			if ( self::$per_page < $total ) {
374
				$total_ajax = ceil( $total / self::$per_page );
375
				$index_end  = self::$per_page;
376
			} else {
377
				$total_ajax = 1;
378
				$index_end  = $total;
379
				$next       = false;
380
			}
381
			$current_percentage = 100 / ( $total_ajax + 1 );
382
383
			?>
384
			<tr valign="top" class="give-import-dropdown">
385
				<th colspan="2">
386
					<h2 id="give-import-title"><?php _e( 'Importing', 'give' ) ?></h2>
387
					<p class="give-field-description"><?php _e( 'Your donations are now being imported...', 'give' ) ?></p>
388
				</th>
389
			</tr>
390
391
			<tr valign="top" class="give-import-dropdown">
392
				<th colspan="2">
393
					<span class="spinner is-active"></span>
394
					<div class="give-progress"
395
					     data-current="1"
396
					     data-total_ajax="<?php echo $total_ajax; ?>"
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$total_ajax'
Loading history...
397
					     data-start="<?php echo $index_start; ?>"
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$index_start'
Loading history...
398
					     data-end="<?php echo $index_end; ?>"
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$index_end'
Loading history...
399
					     data-next="<?php echo $next; ?>"
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$next'
Loading history...
400
					     data-total="<?php echo $total; ?>"
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$total'
Loading history...
401
					     data-per_page="<?php echo self::$per_page; ?>">
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not 'self'
Loading history...
402
403
						<div style="width: <?php echo $current_percentage; ?>%"></div>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$current_percentage'
Loading history...
404
					</div>
405
					<input type="hidden" value="3" name="step">
406
					<input type="hidden" value='<?php echo maybe_serialize( $_REQUEST['mapto'] ); ?>' name="mapto"
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'maybe_serialize'
Loading history...
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_REQUEST
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
407
					       class="mapto">
408
					<input type="hidden" value="<?php echo $_REQUEST['csv']; ?>" name="csv" class="csv">
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Expected next thing to be a escaping function, not '$_REQUEST'
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
409
					<input type="hidden" value="<?php echo $_REQUEST['mode']; ?>" name="mode" class="mode">
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Expected next thing to be a escaping function, not '$_REQUEST'
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
410
					<input type="hidden" value="<?php echo $_REQUEST['create_user']; ?>" name="create_user"
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Expected next thing to be a escaping function, not '$_REQUEST'
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
411
					       class="create_user">
412
					<input type="hidden" value="<?php echo $_REQUEST['delete_csv']; ?>" name="delete_csv"
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Expected next thing to be a escaping function, not '$_REQUEST'
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
413
					       class="delete_csv">
414
					<input type="hidden" value="<?php echo $delimiter; ?>" name="delimiter">
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$delimiter'
Loading history...
415
					<input type="hidden" value="<?php echo absint( $_REQUEST['dry_run'] ); ?>" name="dry_run">
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_REQUEST
Loading history...
416
					<input type="hidden"
417
					       value='<?php echo maybe_serialize( self::get_importer( $csv, 0, $delimiter ) ); ?>'
0 ignored issues
show
Bug introduced by
It seems like $delimiter defined by !empty($_REQUEST['delimi...T['delimiter']) : 'csv' on line 368 can also be of type array; however, Give_Import_Donations::get_importer() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'maybe_serialize'
Loading history...
418
					       name="main_key"
419
					       class="main_key">
420
				</th>
421
			</tr>
422
			<?php
423
		}
424
425
		/**
426
		 * Will return true if importing can be started or not else false.
427
		 *
428
		 * @since 1.8.14
429
		 */
430
		public function check_for_dropdown_or_import() {
431
			$return = true;
432
			if ( isset( $_REQUEST['mapto'] ) ) {
433
				$mapto = (array) $_REQUEST['mapto'];
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
434
				if ( false === in_array( 'form_title', $mapto ) && false === in_array( 'form_id', $mapto ) ) {
435
					Give_Admin_Settings::add_error( 'give-import-csv-form', __( 'In order to import donations, a column must be mapped to either the "Donation Form Title" or "Donation Form ID" field. Please map a column to one of those fields.', 'give' ) );
436
					$return = false;
437
				}
438
439
				if ( false === in_array( 'amount', $mapto ) ) {
440
					Give_Admin_Settings::add_error( 'give-import-csv-amount', __( 'In order to import donations, a column must be mapped to the "Amount" field. Please map a column to that field.', 'give' ) );
441
					$return = false;
442
				}
443
444
				if ( false === in_array( 'email', $mapto ) && false === in_array( 'donor_id', $mapto ) ) {
445
					Give_Admin_Settings::add_error( 'give-import-csv-donor', __( 'In order to import donations, a column must be mapped to either the "Donor Email" or "Donor ID" field. Please map a column to that field.', 'give' ) );
446
					$return = false;
447
				}
448
			} else {
449
				$return = false;
450
			}
451
452
			return $return;
453
		}
454
455
		/**
456
		 * Print the Dropdown option for CSV.
457
		 *
458
		 * @since 1.8.14
459
		 */
460
		public function render_dropdown() {
461
			$csv       = (int) $_GET['csv'];
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_GET
Loading history...
462
			$delimiter = ( ! empty( $_GET['delimiter'] ) ? give_clean( $_GET['delimiter'] ) : 'csv' );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
463
464
			// TO check if the CSV files that is being add is valid or not if not then redirect to first step again
465
			if ( ! $this->is_valid_csv( $csv ) ) {
466
				$url = give_import_page_url();
467
				?>
468
				<input type="hidden" name="csv_not_valid" class="csv_not_valid" value="<?php echo $url; ?>"/>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$url'
Loading history...
469
				<?php
470
			} else {
471
				?>
472
				<tr valign="top" class="give-import-dropdown">
473
					<th colspan="2">
474
						<h2 id="give-import-title"><?php _e( 'Map CSV fields to donations', 'give' ) ?></h2>
475
476
						<p class="give-import-donation-required-fields-title"><?php _e( 'Required Fields' ); ?></p>
477
478
						<p class="give-field-description"><?php _e( 'These fields are required for the import to submitted' ); ?></p>
479
480
						<ul class="give-import-donation-required-fields">
481
							<li class="give-import-donation-required-email"
482
							    title="Please configure all required fields to start the import process.">
483
								<span class="give-import-donation-required-symbol dashicons dashicons-no-alt"></span>
484
								<span class="give-import-donation-required-text">
485
									<?php
486
									_e( 'Email Address', 'give' );
487
									?>
488
								</span>
489
							</li>
490
491
							<li class="give-import-donation-required-first"
492
							    title="Please configure all required fields to start the import process.">
493
								<span class="give-import-donation-required-symbol dashicons dashicons-no-alt"></span>
494
								<span class="give-import-donation-required-text">
495
									<?php
496
									_e( 'First Name', 'give' );
497
									?>
498
								</span>
499
							</li>
500
501
							<li class="give-import-donation-required-amount"
502
							    title="Please configure all required fields to start the import process.">
503
								<span class="give-import-donation-required-symbol dashicons dashicons-no-alt"></span>
504
								<span class="give-import-donation-required-text">
505
									<?php
506
									_e( 'Donation Amount', 'give' );
507
									?>
508
								</span>
509
							</li>
510
511
							<li class="give-import-donation-required-form"
512
							    title="Please configure all required fields to start the import process.">
513
								<span class="give-import-donation-required-symbol dashicons dashicons-no-alt"></span>
514
								<span class="give-import-donation-required-text">
515
									<?php
516
									_e( 'Form Title or ID', 'give' );
517
									?>
518
								</span>
519
							</li>
520
						</ul>
521
522
						<p class="give-field-description"><?php _e( 'Select fields from your CSV file to map against donations fields or to ignore during import.', 'give' ) ?></p>
523
					</th>
524
				</tr>
525
526
				<tr valign="top" class="give-import-dropdown">
527
					<th><b><?php _e( 'Column name', 'give' ); ?></b></th>
528
					<th><b><?php _e( 'Map to field', 'give' ); ?></b></th>
529
				</tr>
530
531
				<?php
532
				$raw_key = $this->get_importer( $csv, 0, $delimiter );
0 ignored issues
show
Bug introduced by
It seems like $delimiter defined by !empty($_GET['delimiter'...T['delimiter']) : 'csv' on line 462 can also be of type array; however, Give_Import_Donations::get_importer() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
533
				$mapto   = (array) ( isset( $_REQUEST['mapto'] ) ? $_REQUEST['mapto'] : array() );
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
534
535
				foreach ( $raw_key as $index => $value ) {
0 ignored issues
show
Bug introduced by
The expression $raw_key of type array<integer,string|nul...":"string|null"}>|false 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...
536
					?>
537
					<tr valign="top" class="give-import-option">
538
						<th><?php echo $value; ?></th>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$value'
Loading history...
539
						<th>
540
							<?php
541
							$this->get_columns( $index, $value, $mapto );
542
							?>
543
						</th>
544
					</tr>
545
					<?php
546
				}
547
			}
548
		}
549
550
		/**
551
		 * @param $option_value
552
		 * @param $value
553
		 *
554
		 * @return string
555
		 */
556
		public function selected( $option_value, $value ) {
557
			$option_value = strtolower( $option_value );
558
			$value        = strtolower( $value );
559
560
			$selected = '';
561
			if ( stristr( $value, $option_value ) ) {
562
				$selected = 'selected';
563
			} elseif ( strrpos( $value, 'give_' ) && stristr( $option_value, __( 'Import as Meta', 'give' ) ) ) {
564
				$selected = 'selected';
565
			}
566
567
			return $selected;
568
		}
569
570
		/**
571
		 * Print the columns from the CSV.
572
		 *
573
		 * @since  1.8.14
574
		 * @access private
575
		 *
576
		 * @param string $index
577
		 * @param bool   $value
578
		 * @param array  $mapto
579
		 *
580
		 * @return void
581
		 */
582
		private function get_columns( $index, $value = false, $mapto = array() ) {
583
			$default       = give_import_default_options();
584
			$current_mapto = (string) ( ! empty( $mapto[ $index ] ) ? $mapto[ $index ] : '' );
585
			?>
586
			<select name="mapto[<?php echo $index; ?>]">
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$index'
Loading history...
587
				<?php $this->get_dropdown_option_html( $default, $current_mapto, $value ); ?>
588
589
				<optgroup label="<?php _e( 'Donations', 'give' ); ?>">
590
					<?php
591
					$this->get_dropdown_option_html( give_import_donations_options(), $current_mapto, $value );
592
					?>
593
				</optgroup>
594
595
				<optgroup label="<?php _e( 'Donors', 'give' ); ?>">
596
					<?php
597
					$this->get_dropdown_option_html( give_import_donor_options(), $current_mapto, $value );
598
					?>
599
				</optgroup>
600
601
				<optgroup label="<?php _e( 'Forms', 'give' ); ?>">
602
					<?php
603
					$this->get_dropdown_option_html( give_import_donation_form_options(), $current_mapto, $value );
604
					?>
605
				</optgroup>
606
607
				<?php
608
				/**
609
				 * Fire the action
610
				 * You can use this filter to add new options.
611
				 *
612
				 * @since 1.8.15
613
				 */
614
				do_action( 'give_import_dropdown_option', $index, $value, $mapto, $current_mapto );
615
				?>
616
			</select>
617
			<?php
618
		}
619
620
		/**
621
		 * Print the option html for select in importer
622
		 *
623
		 * @since  1.8.15
624
		 * @access public
625
		 *
626
		 * @param  array  $options
627
		 * @param  string $current_mapto
628
		 * @param bool    $value
629
		 *
630
		 * @return void
631
		 */
632
		public function get_dropdown_option_html( $options, $current_mapto, $value = false ) {
633
			foreach ( $options as $option => $option_value ) {
634
				$option_value_texts = (array) $option_value;
635
				$option_text        = $option_value_texts[0];
636
637
				$checked = ( ( $current_mapto === $option ) ? 'selected' : false );
638
				if ( empty( $checked ) ) {
639
					foreach ( $option_value_texts as $option_value_text ) {
640
						$checked = $this->selected( $option_value_text, $value );
641
						if ( $checked ) {
642
							break;
643
						}
644
					}
645
				}
646
647
				echo sprintf(
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
648
					'<option value="%1$s" %2$s >%3$s</option>',
649
					$option,
650
					$checked,
651
					$option_text
652
				);
653
			}
654
		}
655
656
		/**
657
		 * Get column count of csv file.
658
		 *
659
		 * @since 1.8.14
660
		 *
661
		 * @param $file_id
662
		 *
663
		 * @return bool|int
664
		 */
665
		public function get_csv_total( $file_id ) {
666
			$total = false;
667
			if ( $file_id ) {
668
				$file_dir = get_attached_file( $file_id );
669
				if ( $file_dir ) {
670
					$file = new SplFileObject( $file_dir, 'r' );
671
					$file->seek( PHP_INT_MAX );
672
					$total = $file->key() + 1;
673
				}
674
			}
675
676
			return $total;
677
		}
678
679
		/**
680
		 * Get the CSV fields title from the CSV.
681
		 *
682
		 * @since 1.8.14
683
		 *
684
		 * @param (int) $file_id
685
		 * @param int    $index
686
		 * @param string $delimiter
687
		 *
688
		 * @return array|bool $raw_data title of the CSV file fields
689
		 */
690
		public function get_importer( $file_id, $index = 0, $delimiter = 'csv' ) {
691
			/**
692
			 * Filter to modify delimiter of Import.
693
			 *
694
			 * @since 1.8.14
695
			 *
696
			 * Return string $delimiter.
697
			 */
698
			$delimiter = (string) apply_filters( 'give_import_delimiter_set', $delimiter );
699
700
			$raw_data = false;
701
			$file_dir = get_attached_file( $file_id );
702
			if ( $file_dir ) {
703
				if ( false !== ( $handle = fopen( $file_dir, 'r' ) ) ) {
704
					$raw_data = fgetcsv( $handle, $index, $delimiter );
705
					// Remove BOM signature from the first item.
706
					if ( isset( $raw_data[0] ) ) {
707
						$raw_data[0] = $this->remove_utf8_bom( $raw_data[0] );
708
					}
709
				}
710
			}
711
712
			return $raw_data;
713
		}
714
715
		/**
716
		 * Remove UTF-8 BOM signature.
717
		 *
718
		 * @since 1.8.14
719
		 *
720
		 * @param  string $string String to handle.
721
		 *
722
		 * @return string
723
		 */
724
		public function remove_utf8_bom( $string ) {
725
			if ( 'efbbbf' === substr( bin2hex( $string ), 0, 6 ) ) {
726
				$string = substr( $string, 3 );
727
			}
728
729
			return $string;
730
		}
731
732
		/**
733
		 * Is used to show the process when user upload the donor form.
734
		 *
735
		 * @since 1.8.14
736
		 */
737
		public function render_progress() {
738
			$step = $this->get_step();
739
			?>
740
			<ol class="give-progress-steps">
741
				<li class="<?php echo( 1 === $step ? 'active' : '' ); ?>">
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '('
Loading history...
742
					<?php _e( 'Upload CSV file', 'give' ); ?>
743
				</li>
744
				<li class="<?php echo( 2 === $step ? 'active' : '' ); ?>">
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '('
Loading history...
745
					<?php _e( 'Column mapping', 'give' ); ?>
746
				</li>
747
				<li class="<?php echo( 3 === $step ? 'active' : '' ); ?>">
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '('
Loading history...
748
					<?php _e( 'Import', 'give' ); ?>
749
				</li>
750
				<li class="<?php echo( 4 === $step ? 'active' : '' ); ?>">
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '('
Loading history...
751
					<?php _e( 'Done!', 'give' ); ?>
752
				</li>
753
			</ol>
754
			<?php
755
		}
756
757
		/**
758
		 * Will return the import step.
759
		 *
760
		 * @since 1.8.14
761
		 *
762
		 * @return int $step on which step doest the import is on.
763
		 */
764 View Code Duplication
		public function get_step() {
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...
765
			$step    = (int) ( isset( $_REQUEST['step'] ) ? give_clean( $_REQUEST['step'] ) : 0 );
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
766
			$on_step = 1;
767
768
			if ( empty( $step ) || 1 === $step ) {
769
				$on_step = 1;
770
			} elseif ( $this->check_for_dropdown_or_import() ) {
771
				$on_step = 3;
772
			} elseif ( 2 === $step ) {
773
				$on_step = 2;
774
			} elseif ( 4 === $step ) {
775
				$on_step = 4;
776
			}
777
778
			return $on_step;
779
		}
780
781
		/**
782
		 * Render donations import page
783
		 *
784
		 * @since 1.8.14
785
		 */
786
		public function render_page() {
787
			include_once GIVE_PLUGIN_DIR . 'includes/admin/tools/views/html-admin-page-import-donations.php';
788
		}
789
790
		/**
791
		 * Print Dry Run HTML on donation import page
792
		 *
793
		 * @since 2.1
794
		 */
795
		public function give_import_donation_submit_button_render_media_csv() {
796
			$dry_run = isset( $_POST['dry_run'] ) ? absint( $_POST['dry_run'] ) : 1;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
797
			?>
798
			<div>
799
				<label for="dry_run">
800
					<input type="hidden" name="dry_run" value="0"/>
801
					<input type="checkbox" name="dry_run" id="dry_run" class="dry_run"
802
					       value="1" <?php checked( 1, $dry_run ); ?> >
803
					<strong><?php _e( 'Dry Run', 'give' ); ?></strong>
804
				</label>
805
				<p class="give-field-description">
806
					<?php
807
					_e( 'Preview what the import would look like without making any defalut changes to your site or your database.', 'give' );
808
					?>
809
				</p>
810
			</div>
811
			<?php
812
		}
813
814
		/**
815
		 * Change submit button text on first step of importing donation.
816
		 *
817
		 * @since 2.1
818
		 *
819
		 * @param $text
820
		 *
821
		 * @return string
822
		 */
823
		function give_import_donation_submit_text_render_media_csv( $text ) {
0 ignored issues
show
Unused Code introduced by
The parameter $text is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
824
			return __( 'Being Import', 'give' );
825
		}
826
827
		/**
828
		 * Add CSV upload HTMl
829
		 *
830
		 * Print the html of the file upload from which CSV will be uploaded.
831
		 *
832
		 * @since 1.8.14
833
		 * @return void
834
		 */
835
		public function render_media_csv() {
836
			add_filter( 'give_import_donation_submit_button_text', array(
837
				$this,
838
				'give_import_donation_submit_text_render_media_csv'
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
839
			) );
840
			add_action( 'give_import_donation_submit_button', array(
841
				$this,
842
				'give_import_donation_submit_button_render_media_csv'
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
843
			) );
844
			?>
845
			<tr valign="top">
846
				<th colspan="2">
847
					<h2 id="give-import-title"><?php _e( 'Import donations from a CSV file', 'give' ) ?></h2>
848
					<p class="give-field-description"><?php _e( 'This tool allows you to import or add donation data to your give form(s) via a CSV file.', 'give' ) ?></p>
849
				</th>
850
			</tr>
851
			<?php
852
			$csv         = ( isset( $_POST['csv'] ) ? give_clean( $_POST['csv'] ) : '' );
0 ignored issues
show
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...
853
			$csv_id      = ( isset( $_POST['csv_id'] ) ? give_clean( $_POST['csv_id'] ) : '' );
0 ignored issues
show
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...
854
			$delimiter   = ( isset( $_POST['delimiter'] ) ? give_clean( $_POST['delimiter'] ) : 'csv' );
0 ignored issues
show
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...
855
			$mode        = empty( $_POST['mode'] ) ?
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
856
				'disabled' :
857
				( give_is_setting_enabled( give_clean( $_POST['mode'] ) ) ? 'enabled' : 'disabled' );
0 ignored issues
show
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...
858
			$create_user = empty( $_POST['create_user'] ) ?
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
859
				'enabled' :
860
				( give_is_setting_enabled( give_clean( $_POST['create_user'] ) ) ? 'enabled' : 'disabled' );
0 ignored issues
show
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...
861
			$delete_csv  = empty( $_POST['delete_csv'] ) ?
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
862
				'enabled' :
863
				( give_is_setting_enabled( give_clean( $_POST['delete_csv'] ) ) ? 'enabled' : 'disabled' );
0 ignored issues
show
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...
864
865
			// Reset csv and csv_id if csv
866
			if ( empty( $csv_id ) || ! $this->is_valid_csv( $csv_id, $csv ) ) {
0 ignored issues
show
Bug introduced by
It seems like $csv defined by isset($_POST['csv']) ? g...ean($_POST['csv']) : '' on line 852 can also be of type array; however, Give_Import_Donations::is_valid_csv() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
867
				$csv_id = $csv = '';
868
			}
869
			$per_page = isset( $_POST['per_page'] ) ? absint( $_POST['per_page'] ) : self::$per_page;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
870
871
			$sample_file_text = sprintf( 'Download the sample file <a href="%s">here</a>.', esc_url( GIVE_PLUGIN_URL . 'sample-data/sample-data.csv' ) );
872
873
			$csv_description = sprintf(
874
				'%1$s %2$s',
875
				__( 'The file must be a Comma Seperated Version (CSV) file type only.', 'give' ),
876
				$sample_file_text
877
			);
878
879
			$settings = array(
880
				array(
881
					'id'          => 'csv',
882
					'name'        => __( 'Choose a CSV file:', 'give' ),
883
					'type'        => 'file',
884
					'attributes'  => array( 'editing' => 'false', 'library' => 'text' ),
885
					'description' => $csv_description,
886
					'fvalue'      => 'url',
887
					'default'     => $csv,
888
				),
889
				array(
890
					'id'    => 'csv_id',
891
					'type'  => 'hidden',
892
					'value' => $csv_id,
893
				),
894
				array(
895
					'id'          => 'delimiter',
896
					'name'        => __( 'CSV Delimiter:', 'give' ),
897
					'description' => __( 'In case your CSV file supports a different type of separator (or delimiter) -- like a tab or space -- you can set that here.', 'give' ),
898
					'default'     => $delimiter,
899
					'type'        => 'select',
900
					'options'     => array(
901
						'csv'                  => __( 'Comma', 'give' ),
902
						'tab-separated-values' => __( 'Tab', 'give' ),
903
					),
904
				),
905
				array(
906
					'id'          => 'mode',
907
					'name'        => __( 'Test Mode:', 'give' ),
908
					'description' => __( 'Test mode allows you to preview what this import would look like without making any actual changes to your site or your database.', 'give' ),
909
					'default'     => $mode,
910
					'type'        => 'radio_inline',
911
					'options'     => array(
912
						'enabled'  => __( 'Enabled', 'give' ),
913
						'disabled' => __( 'Disabled', 'give' ),
914
					),
915
				),
916
				array(
917
					'id'          => 'create_user',
918
					'name'        => __( 'Create WP users for new donors:', 'give' ),
919
					'description' => __( 'The importer can create WordPress user accounts based on the names and email addresses of the donations in your CSV file. Enable this option if you\'d like the importer to do that.', 'give' ),
920
					'default'     => $create_user,
921
					'type'        => 'radio_inline',
922
					'options'     => array(
923
						'enabled'  => __( 'Enabled', 'give' ),
924
						'disabled' => __( 'Disabled', 'give' ),
925
					),
926
				),
927
				array(
928
					'id'          => 'delete_csv',
929
					'name'        => __( 'Delete CSV after import:', 'give' ),
930
					'description' => __( 'Your CSV file will be uploaded via the WordPress Media Library. It\'s a good idea to delete it after the import is finished so that your sensitive data is not accessible on the web. Disable this only if you plan to delete the file manually later.', 'give' ),
931
					'default'     => $delete_csv,
932
					'type'        => 'radio_inline',
933
					'options'     => array(
934
						'enabled'  => __( 'Enabled', 'give' ),
935
						'disabled' => __( 'Disabled', 'give' ),
936
					),
937
				),
938
				array(
939
					'id'          => 'per_page',
940
					'name'        => __( 'Process Rows Per Batch:', 'give' ),
941
					'type'        => 'number',
942
					'description' => __( 'Determine how many rows you would like to import per cycle.', 'give' ),
943
					'default'     => $per_page,
944
					'class'       => 'give-text-small',
945
				),
946
			);
947
948
			$settings = apply_filters( 'give_import_file_upload_html', $settings );
949
950
			if ( empty( $this->is_csv_valid ) ) {
951
				Give_Admin_Settings::output_fields( $settings, 'give_settings' );
952
			} else {
953
				?>
954
				<input type="hidden" name="is_csv_valid" class="is_csv_valid"
955
				       value="<?php echo $this->is_csv_valid; ?>">
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
956
				<?php
957
			}
958
		}
959
960
		/**
961
		 * Run when user click on the submit button.
962
		 *
963
		 * @since 1.8.14
964
		 */
965
		public function save() {
966
			// Get the current step.
967
			$step = $this->get_step();
968
969
			// Validation for first step.
970
			if ( 1 === $step ) {
971
				$csv_id = absint( $_POST['csv_id'] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_POST
Loading history...
972
973
				if ( $this->is_valid_csv( $csv_id, esc_url( $_POST['csv'] ) ) ) {
974
975
					$url = give_import_page_url( (array) apply_filters( 'give_import_step_two_url', array(
976
						'step'          => '2',
977
						'importer-type' => $this->importer_type,
978
						'csv'           => $csv_id,
979
						'delimiter'     => isset( $_REQUEST['delimiter'] ) ? give_clean( $_REQUEST['delimiter'] ) : 'csv',
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
980
						'mode'          => empty( $_POST['mode'] ) ?
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
981
							'0' :
982
							( give_is_setting_enabled( give_clean( $_POST['mode'] ) ) ? '1' : '0' ),
0 ignored issues
show
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...
983
						'create_user'   => empty( $_POST['create_user'] ) ?
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
984
							'0' :
985
							( give_is_setting_enabled( give_clean( $_POST['create_user'] ) ) ? '1' : '0' ),
0 ignored issues
show
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...
986
						'delete_csv'    => empty( $_POST['delete_csv'] ) ?
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
987
							'1' :
988
							( give_is_setting_enabled( give_clean( $_POST['delete_csv'] ) ) ? '1' : '0' ),
0 ignored issues
show
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...
989
						'per_page'      => isset( $_POST['per_page'] ) ? absint( $_POST['per_page'] ) : self::$per_page,
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
990
						'dry_run'        => isset( $_POST['dry_run'] ) ? absint( $_POST['dry_run'] ) : 0,
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
991
					) ) );
992
993
					$this->is_csv_valid = $url;
0 ignored issues
show
Documentation Bug introduced by
The property $is_csv_valid was declared of type integer, but $url is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
994
				}
995
			}
996
		}
997
998
		/**
999
		 * Check if user uploaded csv is valid or not.
1000
		 *
1001
		 * @since  1.8.14
1002
		 * @access public
1003
		 *
1004
		 * @param mixed  $csv       ID of the CSV files.
1005
		 * @param string $match_url ID of the CSV files.
1006
		 *
1007
		 * @return bool $has_error CSV is valid or not.
1008
		 */
1009
		private function is_valid_csv( $csv = false, $match_url = '' ) {
1010
			$is_valid_csv = true;
1011
1012
			if ( $csv ) {
1013
				$csv_url = wp_get_attachment_url( $csv );
1014
1015
				$delimiter = ( ! empty( $_REQUEST['delimiter'] ) ? give_clean( $_REQUEST['delimiter'] ) : 'csv' );
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
1016
1017
				if (
1018
					! $csv_url ||
1019
					( ! empty( $match_url ) && ( $csv_url !== $match_url ) ) ||
1020
					( ( $mime_type = get_post_mime_type( $csv ) ) && ! strpos( $mime_type, $delimiter ) )
1021
				) {
1022
					$is_valid_csv = false;
1023
					Give_Admin_Settings::add_error( 'give-import-csv', __( 'Please upload or provide a valid CSV file.', 'give' ) );
1024
				}
1025
			} else {
1026
				$is_valid_csv = false;
1027
				Give_Admin_Settings::add_error( 'give-import-csv', __( 'Please upload or provide a valid CSV file.', 'give' ) );
1028
			}
1029
1030
			return $is_valid_csv;
1031
		}
1032
1033
1034
		/**
1035
		 * Render report import field
1036
		 *
1037
		 * @since  1.8.14
1038
		 * @access public
1039
		 *
1040
		 * @param $field
1041
		 * @param $option_value
1042
		 */
1043
		public function render_import_field( $field, $option_value ) {
1044
			include_once GIVE_PLUGIN_DIR . 'includes/admin/tools/views/html-admin-page-imports.php';
1045
		}
1046
1047
		/**
1048
		 * Get if current page import donations page or not
1049
		 *
1050
		 * @since 1.8.14
1051
		 * @return bool
1052
		 */
1053
		private function is_donations_import_page() {
1054
			return 'import' === give_get_current_setting_tab() &&
1055
			       isset( $_GET['importer-type'] ) &&
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
1056
			       $this->importer_type === give_clean( $_GET['importer-type'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
1057
		}
1058
	}
1059
1060
	Give_Import_Donations::get_instance()->setup();
1061
}
1062