PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.0.3
GiveWP – Donation Plugin and Fundraising Platform v2.0.3
4.16.3 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 / import / class-give-import-donations.php
give / includes / admin / tools / import Last commit date
class-give-import-core-settings.php 8 years ago class-give-import-donations.php 8 years ago
class-give-import-donations.php
952 lines
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 * Singleton pattern.
55 *
56 * @since
57 * @access private
58 */
59 private function __construct() {
60 self::$per_page = ! empty( $_GET['per_page'] ) ? absint( $_GET['per_page'] ) : self::$per_page;
61 }
62
63 /**
64 * Get instance.
65 *
66 * @since
67 * @access public
68 *
69 * @return static
70 */
71 public static function get_instance() {
72 if ( null === static::$instance ) {
73 self::$instance = new static();
74 }
75
76 return self::$instance;
77 }
78
79 /**
80 * Setup
81 *
82 * @since 1.8.14
83 *
84 * @return void
85 */
86 public function setup() {
87 $this->setup_hooks();
88 }
89
90
91 /**
92 * Setup Hooks.
93 *
94 * @since 1.8.14
95 *
96 * @return void
97 */
98 private function setup_hooks() {
99 if ( ! $this->is_donations_import_page() ) {
100 return;
101 }
102
103 // Do not render main import tools page.
104 remove_action( 'give_admin_field_tools_import', array( 'Give_Settings_Import', 'render_import_field', ) );
105
106
107 // Render donation import page
108 add_action( 'give_admin_field_tools_import', array( $this, 'render_page' ) );
109
110 // Print the HTML.
111 add_action( 'give_tools_import_donations_form_start', array( $this, 'html' ), 10 );
112
113 // Run when form submit.
114 add_action( 'give-tools_save_import', array( $this, 'save' ) );
115
116 add_action( 'give-tools_update_notices', array( $this, 'update_notices' ), 11, 1 );
117
118 // Used to add submit button.
119 add_action( 'give_tools_import_donations_form_end', array( $this, 'submit' ), 10 );
120 }
121
122 /**
123 * Update notice
124 *
125 * @since 1.8.14
126 *
127 * @param $messages
128 *
129 * @return mixed
130 */
131 public function update_notices( $messages ) {
132 if ( ! empty( $_GET['tab'] ) && 'import' === give_clean( $_GET['tab'] ) ) {
133 unset( $messages['give-setting-updated'] );
134 }
135
136 return $messages;
137 }
138
139 /**
140 * Print submit and nonce button.
141 *
142 * @since 1.8.14
143 */
144 public function submit() {
145 wp_nonce_field( 'give-save-settings', '_give-save-settings' );
146 ?>
147 <input type="hidden" class="import-step" id="import-step" name="step" value="<?php echo $this->get_step(); ?>"/>
148 <input type="hidden" class="importer-type" value="<?php echo $this->importer_type; ?>"/>
149 <?php
150 }
151
152 /**
153 * Print the HTML for importer.
154 *
155 * @since 1.8.14
156 */
157 public function html() {
158 $step = $this->get_step();
159
160 // Show progress.
161 $this->render_progress();
162 ?>
163 <section>
164 <table class="widefat export-options-table give-table <?php echo "step-{$step}"; ?>" id="<?php echo "step-{$step}"; ?>">
165 <tbody>
166 <?php
167 switch ( $this->get_step() ) {
168 case 1:
169 $this->render_media_csv();
170 break;
171
172 case 2:
173 $this->render_dropdown();
174 break;
175
176 case 3:
177 $this->start_import();
178 break;
179
180 case 4:
181 $this->import_success();
182 }
183
184 if ( false === $this->check_for_dropdown_or_import() ) {
185 ?>
186 <tr valign="top">
187 <th></th>
188 <th>
189 <input type="submit"
190 class=" button button-primary button-large button-secondary <?php echo "step-{$step}"; ?>"
191 id="recount-stats-submit"
192 <?php echo ( 2 === $step ) ? 'disabled' : ''; ?>
193 value="<?php esc_attr_e( 'Submit', 'give' ); ?>"/>
194 </th>
195 </tr>
196 <?php
197 }
198 ?>
199 </tbody>
200 </table>
201 </section>
202 <?php
203 }
204
205 /**
206 * Show success notice
207 *
208 * @since 1.8.14
209 */
210 public function import_success() {
211
212 $delete_csv = ( ! empty( $_GET['delete_csv'] ) ? absint( $_GET['delete_csv'] ) : false );
213 $csv = ( ! empty( $_GET['csv'] ) ? absint( $_GET['csv'] ) : false );
214 if ( ! empty( $delete_csv ) && ! empty( $csv ) ) {
215 wp_delete_attachment( $csv, true );
216 }
217
218 $report = give_import_donation_report();
219
220 $report_html = array(
221 'duplicate_donor' => array(
222 __( '%s duplicate %s detected', 'give' ),
223 __( 'donor', 'give' ),
224 __( 'donors', 'give' ),
225 ),
226 'create_donor' => array(
227 __( '%s %s created', 'give' ),
228 __( 'donor', 'give' ),
229 __( 'donors', 'give' ),
230 ),
231 'create_form' => array(
232 __( '%s donation %s created', 'give' ),
233 __( 'form', 'give' ),
234 __( 'forms', 'give' ),
235 ),
236 'duplicate_donation' => array(
237 __( '%s duplicate %s detected', 'give' ),
238 __( 'donation', 'give' ),
239 __( 'donations', 'give' ),
240 ),
241 'create_donation' => array(
242 __( '%s %s imported', 'give' ),
243 __( 'donation', 'give' ),
244 __( 'donations', 'give' ),
245 ),
246 );
247 $total = (int) $_GET['total'];
248 -- $total;
249 $success = (bool) $_GET['success'];
250 ?>
251 <tr valign="top" class="give-import-dropdown">
252 <th colspan="2">
253 <h2>
254 <?php
255 if ( $success ) {
256 printf(
257 _n( 'Import complete! %s donation processed', 'Import complete! %s donations processed', $total, 'give' ),
258 "<strong>{$total}</strong>"
259 );
260 } else {
261 printf(
262 _n( 'Failed to import %s donation', 'Failed to import %s donations', $total, 'give' ),
263 "<strong>{$total}</strong>"
264 );
265 }
266 ?>
267 </h2>
268
269 <?php
270 $text = __( 'Import Donation', 'give' );
271 $query_arg = array(
272 'post_type' => 'give_forms',
273 'page' => 'give-tools',
274 'tab' => 'import',
275 );
276 if ( $success ) {
277 $query_arg = array(
278 'post_type' => 'give_forms',
279 'page' => 'give-payment-history',
280 );
281 $text = __( 'View Donations', 'give' );
282 }
283
284 foreach ( $report as $key => $value ) {
285 if ( array_key_exists( $key, $report_html ) && ! empty( $value ) ) {
286 ?>
287 <p>
288 <?php echo esc_html( wp_sprintf( $report_html[ $key ][0], $value, _n( $report_html[ $key ][1], $report_html[ $key ][2], $value, 'give' ) ) ); ?>
289 </p>
290 <?php
291 }
292 }
293 ?>
294
295 <p>
296 <a class="button button-large button-secondary" href="<?php echo add_query_arg( $query_arg, admin_url( 'edit.php' ) ); ?>"><?php echo $text; ?></a>
297 </p>
298 </th>
299 </tr>
300 <?php
301 }
302
303 /**
304 * Will start Import
305 *
306 * @since 1.8.14
307 */
308 public function start_import() {
309 // Reset the donation form report.
310 give_import_donation_report_reset();
311
312 $csv = (int) $_REQUEST['csv'];
313 $delimiter = ( ! empty( $_REQUEST['delimiter'] ) ? give_clean( $_REQUEST['delimiter'] ) : 'csv' );
314 $index_start = 1;
315 $index_end = 1;
316 $next = true;
317 $total = self::get_csv_total( $csv );
318 if ( self::$per_page < $total ) {
319 $total_ajax = ceil( $total / self::$per_page );
320 $index_end = self::$per_page;
321 } else {
322 $total_ajax = 1;
323 $index_end = $total;
324 $next = false;
325 }
326 $current_percentage = 100 / ( $total_ajax + 1 );
327
328 ?>
329 <tr valign="top" class="give-import-dropdown">
330 <th colspan="2">
331 <h2 id="give-import-title"><?php esc_html_e( 'Importing', 'give' ) ?></h2>
332 <p class="give-field-description"><?php esc_html_e( 'Your donations are now being imported...', 'give' ) ?></p>
333 </th>
334 </tr>
335
336 <tr valign="top" class="give-import-dropdown">
337 <th colspan="2">
338 <span class="spinner is-active"></span>
339 <div class="give-progress"
340 data-current="1"
341 data-total_ajax="<?php echo $total_ajax; ?>"
342 data-start="<?php echo $index_start; ?>"
343 data-end="<?php echo $index_end; ?>"
344 data-next="<?php echo $next; ?>"
345 data-total="<?php echo $total; ?>"
346 data-per_page="<?php echo self::$per_page; ?>">
347
348 <div style="width: <?php echo $current_percentage; ?>%"></div>
349 </div>
350 <input type="hidden" value="3" name="step">
351 <input type="hidden" value='<?php echo maybe_serialize( $_REQUEST['mapto'] ); ?>' name="mapto"
352 class="mapto">
353 <input type="hidden" value="<?php echo $_REQUEST['csv']; ?>" name="csv" class="csv">
354 <input type="hidden" value="<?php echo $_REQUEST['mode']; ?>" name="mode" class="mode">
355 <input type="hidden" value="<?php echo $_REQUEST['create_user']; ?>" name="create_user"
356 class="create_user">
357 <input type="hidden" value="<?php echo $_REQUEST['delete_csv']; ?>" name="delete_csv"
358 class="delete_csv">
359 <input type="hidden" value="<?php echo $delimiter; ?>" name="delimiter">
360 <input type="hidden" value='<?php echo maybe_serialize( self::get_importer( $csv, 0, $delimiter ) ); ?>'
361 name="main_key"
362 class="main_key">
363 </th>
364 </tr>
365
366 <script type="text/javascript">
367 jQuery(document).ready(function () {
368 give_on_donation_import_start();
369 });
370 </script>
371 <?php
372 }
373
374 /**
375 * Will return true if importing can be started or not else false.
376 *
377 * @since 1.8.14
378 */
379 public function check_for_dropdown_or_import() {
380 $return = true;
381 if ( isset( $_REQUEST['mapto'] ) ) {
382 $mapto = (array) $_REQUEST['mapto'];
383 if ( false === in_array( 'form_title', $mapto ) && false === in_array( 'form_id', $mapto ) ) {
384 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' ) );
385 $return = false;
386 }
387
388 if ( false === in_array( 'amount', $mapto ) ) {
389 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' ) );
390 $return = false;
391 }
392
393 if ( false === in_array( 'email', $mapto ) && false === in_array( 'donor_id', $mapto ) ) {
394 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' ) );
395 $return = false;
396 }
397 } else {
398 $return = false;
399 }
400
401 return $return;
402 }
403
404 /**
405 * Print the Dropdown option for CSV.
406 *
407 * @since 1.8.14
408 */
409 public function render_dropdown() {
410 $csv = (int) $_GET['csv'];
411 $delimiter = ( ! empty( $_GET['delimiter'] ) ? give_clean( $_GET['delimiter'] ) : 'csv' );
412
413 // TO check if the CSV files that is being add is valid or not if not then redirect to first step again
414 if ( ! $this->is_valid_csv( $csv ) ) {
415 $url = give_import_page_url();
416 ?>
417 <script type="text/javascript">
418 window.location = "<?php echo $url; ?>"
419 </script>
420 <?php
421 } else {
422 ?>
423 <tr valign="top" class="give-import-dropdown">
424 <th colspan="2">
425 <h2 id="give-import-title"><?php esc_html_e( 'Map CSV fields to donations', 'give' ) ?></h2>
426
427 <p class="give-import-donation-required-fields-title"><?php _e( 'Required Fields' ); ?></p>
428
429 <p class="give-field-description"><?php _e( 'These fields are required for the import to submitted' ); ?></p>
430
431 <ul class="give-import-donation-required-fields">
432 <li class="give-import-donation-required-email" title="Please configure all required fields to start the import process.">
433 <span class="give-import-donation-required-symbol dashicons dashicons-no-alt"></span>
434 <span class="give-import-donation-required-text">
435 <?php
436 _e( 'Email Access', 'give' );
437 ?>
438 </span>
439 </li>
440
441 <li class="give-import-donation-required-first" title="Please configure all required fields to start the import process.">
442 <span class="give-import-donation-required-symbol dashicons dashicons-no-alt"></span>
443 <span class="give-import-donation-required-text">
444 <?php
445 _e( 'First Name', 'give' );
446 ?>
447 </span>
448 </li>
449
450 <li class="give-import-donation-required-amount" title="Please configure all required fields to start the import process.">
451 <span class="give-import-donation-required-symbol dashicons dashicons-no-alt"></span>
452 <span class="give-import-donation-required-text">
453 <?php
454 _e( 'Donation Amount', 'give' );
455 ?>
456 </span>
457 </li>
458
459 <li class="give-import-donation-required-form" title="Please configure all required fields to start the import process.">
460 <span class="give-import-donation-required-symbol dashicons dashicons-no-alt"></span>
461 <span class="give-import-donation-required-text">
462 <?php
463 _e( 'Form Title or ID', 'give' );
464 ?>
465 </span>
466 </li>
467 </ul>
468
469 <p class="give-field-description"><?php esc_html_e( 'Select fields from your CSV file to map against donations fields or to ignore during import.', 'give' ) ?></p>
470 </th>
471 </tr>
472
473 <tr valign="top" class="give-import-dropdown">
474 <th><b><?php esc_html_e( 'Column name', 'give' ); ?></b></th>
475 <th><b><?php esc_html_e( 'Map to field', 'give' ); ?></b></th>
476 </tr>
477
478 <?php
479 $raw_key = $this->get_importer( $csv, 0, $delimiter );
480 $mapto = (array) ( isset( $_REQUEST['mapto'] ) ? $_REQUEST['mapto'] : array() );
481
482 foreach ( $raw_key as $index => $value ) {
483 ?>
484 <tr valign="top" class="give-import-option">
485 <th><?php echo $value; ?></th>
486 <th>
487 <?php
488 $this->get_columns( $index, $value, $mapto );
489 ?>
490 </th>
491 </tr>
492 <?php
493 }
494 }
495 }
496
497 /**
498 * @param $option_value
499 * @param $value
500 *
501 * @return string
502 */
503 public function selected( $option_value, $value ) {
504 $option_value = strtolower( $option_value );
505 $value = strtolower( $value );
506
507 $selected = '';
508 if ( stristr( $value, $option_value ) ) {
509 $selected = 'selected';
510 } elseif ( strrpos( $value, '_' ) && stristr( $option_value, __( 'Import as Meta', 'give' ) ) ) {
511 $selected = 'selected';
512 }
513
514 return $selected;
515 }
516
517 /**
518 * Print the columns from the CSV.
519 *
520 * @since 1.8.14
521 * @access private
522 *
523 * @param string $index
524 * @param bool $value
525 * @param array $mapto
526 *
527 * @return void
528 */
529 private function get_columns( $index, $value = false, $mapto = array() ) {
530 $default = give_import_default_options();
531 $current_mapto = (string) ( ! empty( $mapto[ $index ] ) ? $mapto[ $index ] : '' );
532 ?>
533 <select name="mapto[<?php echo $index; ?>]">
534 <?php $this->get_dropdown_option_html( $default, $current_mapto, $value ); ?>
535
536 <optgroup label="<?php _e( 'Donations', 'give' ); ?>">
537 <?php
538 $this->get_dropdown_option_html( give_import_donations_options(), $current_mapto, $value );
539 ?>
540 </optgroup>
541
542 <optgroup label="<?php _e( 'Donors', 'give' ); ?>">
543 <?php
544 $this->get_dropdown_option_html( give_import_donor_options(), $current_mapto, $value );
545 ?>
546 </optgroup>
547
548 <optgroup label="<?php _e( 'Forms', 'give' ); ?>">
549 <?php
550 $this->get_dropdown_option_html( give_import_donation_form_options(), $current_mapto, $value );
551 ?>
552 </optgroup>
553
554 <?php
555 /**
556 * Fire the action
557 * You can use this filter to add new options.
558 *
559 * @since 1.8.15
560 */
561 do_action( 'give_import_dropdown_option', $index, $value, $mapto, $current_mapto );
562 ?>
563 </select>
564 <?php
565 }
566
567 /**
568 * Print the option html for select in importer
569 *
570 * @since 1.8.15
571 * @access public
572 *
573 * @param array $options
574 * @param string $current_mapto
575 * @param bool $value
576 *
577 * @return void
578 */
579 public function get_dropdown_option_html( $options, $current_mapto, $value = false ) {
580 foreach ( $options as $option => $option_value ) {
581 $option_value_texts = (array) $option_value;
582 $option_text = $option_value_texts[0];
583
584 $checked = ( ( $current_mapto === $option ) ? 'selected' : false );
585 if ( empty( $checked ) ) {
586 foreach ( $option_value_texts as $option_value_text ) {
587 $checked = $this->selected( $option_value_text, $value );
588 if ( $checked ) {
589 break;
590 }
591 }
592 }
593
594 echo sprintf(
595 '<option value="%1$s" %2$s >%3$s</option>',
596 $option,
597 $checked,
598 $option_text
599 );
600 }
601 }
602
603 /**
604 * Get column count of csv file.
605 *
606 * @since 1.8.14
607 *
608 * @param $file_id
609 *
610 * @return bool|int
611 */
612 public function get_csv_total( $file_id ) {
613 $total = false;
614 if ( $file_id ) {
615 $file_dir = get_attached_file( $file_id );
616 if ( $file_dir ) {
617 $file = new SplFileObject( $file_dir, 'r' );
618 $file->seek( PHP_INT_MAX );
619 $total = $file->key() + 1;
620 }
621 }
622
623 return $total;
624 }
625
626 /**
627 * Get the CSV fields title from the CSV.
628 *
629 * @since 1.8.14
630 *
631 * @param (int) $file_id
632 * @param int $index
633 * @param string $delimiter
634 *
635 * @return array|bool $raw_data title of the CSV file fields
636 */
637 public function get_importer( $file_id, $index = 0, $delimiter = 'csv' ) {
638 /**
639 * Filter to modify delimiter of Import.
640 *
641 * @since 1.8.14
642 *
643 * Return string $delimiter.
644 */
645 $delimiter = (string) apply_filters( 'give_import_delimiter_set', $delimiter );
646
647 $raw_data = false;
648 $file_dir = get_attached_file( $file_id );
649 if ( $file_dir ) {
650 if ( false !== ( $handle = fopen( $file_dir, 'r' ) ) ) {
651 $raw_data = fgetcsv( $handle, $index, $delimiter );
652 // Remove BOM signature from the first item.
653 if ( isset( $raw_data[0] ) ) {
654 $raw_data[0] = $this->remove_utf8_bom( $raw_data[0] );
655 }
656 }
657 }
658
659 return $raw_data;
660 }
661
662 /**
663 * Remove UTF-8 BOM signature.
664 *
665 * @since 1.8.14
666 *
667 * @param string $string String to handle.
668 *
669 * @return string
670 */
671 public function remove_utf8_bom( $string ) {
672 if ( 'efbbbf' === substr( bin2hex( $string ), 0, 6 ) ) {
673 $string = substr( $string, 3 );
674 }
675
676 return $string;
677 }
678
679
680 /**
681 * Is used to show the process when user upload the donor form.
682 *
683 * @since 1.8.14
684 */
685 public function render_progress() {
686 $step = $this->get_step();
687 ?>
688 <ol class="give-progress-steps">
689 <li class="<?php echo( 1 === $step ? 'active' : '' ); ?>">
690 <?php esc_html_e( 'Upload CSV file', 'give' ); ?>
691 </li>
692 <li class="<?php echo( 2 === $step ? 'active' : '' ); ?>">
693 <?php esc_html_e( 'Column mapping', 'give' ); ?>
694 </li>
695 <li class="<?php echo( 3 === $step ? 'active' : '' ); ?>">
696 <?php esc_html_e( 'Import', 'give' ); ?>
697 </li>
698 <li class="<?php echo( 4 === $step ? 'active' : '' ); ?>">
699 <?php esc_html_e( 'Done!', 'give' ); ?>
700 </li>
701 </ol>
702 <?php
703 }
704
705 /**
706 * Will return the import step.
707 *
708 * @since 1.8.14
709 *
710 * @return int $step on which step doest the import is on.
711 */
712 public function get_step() {
713 $step = (int) ( isset( $_REQUEST['step'] ) ? give_clean( $_REQUEST['step'] ) : 0 );
714 $on_step = 1;
715
716 if ( empty( $step ) || 1 === $step ) {
717 $on_step = 1;
718 } elseif ( $this->check_for_dropdown_or_import() ) {
719 $on_step = 3;
720 } elseif ( 2 === $step ) {
721 $on_step = 2;
722 } elseif ( 4 === $step ) {
723 $on_step = 4;
724 }
725
726 return $on_step;
727 }
728
729 /**
730 * Render donations import page
731 *
732 * @since 1.8.14
733 */
734 public function render_page() {
735 include_once GIVE_PLUGIN_DIR . 'includes/admin/tools/views/html-admin-page-import-donations.php';
736 }
737
738 /**
739 * Add CSV upload HTMl
740 *
741 * Print the html of the file upload from which CSV will be uploaded.
742 *
743 * @since 1.8.14
744 * @return void
745 */
746 public function render_media_csv() {
747 ?>
748 <tr valign="top">
749 <th colspan="2">
750 <h2 id="give-import-title"><?php esc_html_e( 'Import donations from a CSV file', 'give' ) ?></h2>
751 <p class="give-field-description"><?php esc_html_e( 'This tool allows you to import or add donation data to your give form(s) via a CSV file.', 'give' ) ?></p>
752 </th>
753 </tr>
754 <?php
755 $csv = ( isset( $_POST['csv'] ) ? give_clean( $_POST['csv'] ) : '' );
756 $csv_id = ( isset( $_POST['csv_id'] ) ? give_clean( $_POST['csv_id'] ) : '' );
757 $delimiter = ( isset( $_POST['delimiter'] ) ? give_clean( $_POST['delimiter'] ) : 'csv' );
758 $mode = empty( $_POST['mode'] ) ?
759 'disabled' :
760 ( give_is_setting_enabled( give_clean( $_POST['mode'] ) ) ? 'enabled' : 'disabled' );
761 $create_user = empty( $_POST['create_user'] ) ?
762 'enabled' :
763 ( give_is_setting_enabled( give_clean( $_POST['create_user'] ) ) ? 'enabled' : 'disabled' );
764 $delete_csv = empty( $_POST['delete_csv'] ) ?
765 'enabled' :
766 ( give_is_setting_enabled( give_clean( $_POST['delete_csv'] ) ) ? 'enabled' : 'disabled' );
767
768 // Reset csv and csv_id if csv
769 if ( empty( $csv_id ) || ! $this->is_valid_csv( $csv_id, $csv ) ) {
770 $csv_id = $csv = '';
771 }
772 $per_page = isset( $_POST['per_page'] ) ? absint( $_POST['per_page'] ) : self::$per_page;
773
774 $settings = array(
775 array(
776 'id' => 'csv',
777 'name' => __( 'Choose a CSV file:', 'give' ),
778 'type' => 'file',
779 'attributes' => array( 'editing' => 'false', 'library' => 'text' ),
780 'description' => __( 'The file must be a Comma Seperated Version (CSV) file type only.', 'give' ),
781 'fvalue' => 'url',
782 'default' => $csv,
783 ),
784 array(
785 'id' => 'csv_id',
786 'type' => 'hidden',
787 'value' => $csv_id,
788 ),
789 array(
790 'id' => 'delimiter',
791 'name' => __( 'CSV Delimiter:', 'give' ),
792 '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' ),
793 'default' => $delimiter,
794 'type' => 'select',
795 'options' => array(
796 'csv' => esc_html__( 'Comma', 'give' ),
797 'tab-separated-values' => esc_html__( 'Tab', 'give' ),
798 ),
799 ),
800 array(
801 'id' => 'mode',
802 'name' => __( 'Test Mode:', 'give' ),
803 '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' ),
804 'default' => $mode,
805 'type' => 'radio_inline',
806 'options' => array(
807 'enabled' => __( 'Enabled', 'give' ),
808 'disabled' => __( 'Disabled', 'give' ),
809 ),
810 ),
811 array(
812 'id' => 'create_user',
813 'name' => __( 'Create WP users for new donors:', 'give' ),
814 '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' ),
815 'default' => $create_user,
816 'type' => 'radio_inline',
817 'options' => array(
818 'enabled' => __( 'Enabled', 'give' ),
819 'disabled' => __( 'Disabled', 'give' ),
820 ),
821 ),
822 array(
823 'id' => 'delete_csv',
824 'name' => __( 'Delete CSV after import:', 'give' ),
825 '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' ),
826 'default' => $delete_csv,
827 'type' => 'radio_inline',
828 'options' => array(
829 'enabled' => __( 'Enabled', 'give' ),
830 'disabled' => __( 'Disabled', 'give' ),
831 ),
832 ),
833 array(
834 'id' => 'per_page',
835 'name' => __( 'Process Rows Per Batch:', 'give' ),
836 'type' => 'number',
837 'description' => __( 'Determine how many rows you would like to import per cycle.', 'give' ),
838 'default' => $per_page,
839 'class' => 'give-text-small',
840 ),
841 );
842
843 $settings = apply_filters( 'give_import_file_upload_html', $settings );
844
845 Give_Admin_Settings::output_fields( $settings, 'give_settings' );
846 }
847
848 /**
849 * Run when user click on the submit button.
850 *
851 * @since 1.8.14
852 */
853 public function save() {
854 // Get the current step.
855 $step = $this->get_step();
856
857 // Validation for first step.
858 if ( 1 === $step ) {
859 $csv_id = absint( $_POST['csv_id'] );
860
861 if ( $this->is_valid_csv( $csv_id, esc_url( $_POST['csv'] ) ) ) {
862
863 $url = give_import_page_url( (array) apply_filters( 'give_import_step_two_url', array(
864 'step' => '2',
865 'importer-type' => $this->importer_type,
866 'csv' => $csv_id,
867 'delimiter' => isset( $_REQUEST['delimiter'] ) ? give_clean( $_REQUEST['delimiter'] ) : 'csv',
868 'mode' => empty( $_POST['mode'] ) ?
869 '0' :
870 ( give_is_setting_enabled( give_clean( $_POST['mode'] ) ) ? '1' : '0' ),
871 'create_user' => empty( $_POST['create_user'] ) ?
872 '0' :
873 ( give_is_setting_enabled( give_clean( $_POST['create_user'] ) ) ? '1' : '0' ),
874 'delete_csv' => empty( $_POST['delete_csv'] ) ?
875 '1' :
876 ( give_is_setting_enabled( give_clean( $_POST['delete_csv'] ) ) ? '1' : '0' ),
877 'per_page' => isset( $_POST['per_page'] ) ? absint( $_POST['per_page'] ) : self::$per_page,
878 ) ) );
879 ?>
880 <script type="text/javascript">
881 window.location = "<?php echo $url; ?>"
882 </script>
883 <?php
884 }
885 }
886 }
887
888 /**
889 * Check if user uploaded csv is valid or not.
890 *
891 * @since 1.8.14
892 * @access public
893 *
894 * @param mixed $csv ID of the CSV files.
895 * @param string $match_url ID of the CSV files.
896 *
897 * @return bool $has_error CSV is valid or not.
898 */
899 private function is_valid_csv( $csv = false, $match_url = '' ) {
900 $is_valid_csv = true;
901
902 if ( $csv ) {
903 $csv_url = wp_get_attachment_url( $csv );
904
905 $delimiter = ( ! empty( $_REQUEST['delimiter'] ) ? give_clean( $_REQUEST['delimiter'] ) : 'csv' );
906
907 if (
908 ! $csv_url ||
909 ( ! empty( $match_url ) && ( $csv_url !== $match_url ) ) ||
910 ( ( $mime_type = get_post_mime_type( $csv ) ) && ! strpos( $mime_type, $delimiter ) )
911 ) {
912 $is_valid_csv = false;
913 Give_Admin_Settings::add_error( 'give-import-csv', __( 'Please upload or provide a valid CSV file.', 'give' ) );
914 }
915 } else {
916 $is_valid_csv = false;
917 Give_Admin_Settings::add_error( 'give-import-csv', __( 'Please upload or provide a valid CSV file.', 'give' ) );
918 }
919
920 return $is_valid_csv;
921 }
922
923
924 /**
925 * Render report import field
926 *
927 * @since 1.8.14
928 * @access public
929 *
930 * @param $field
931 * @param $option_value
932 */
933 public function render_import_field( $field, $option_value ) {
934 include_once GIVE_PLUGIN_DIR . 'includes/admin/tools/views/html-admin-page-imports.php';
935 }
936
937 /**
938 * Get if current page import donations page or not
939 *
940 * @since 1.8.14
941 * @return bool
942 */
943 private function is_donations_import_page() {
944 return 'import' === give_get_current_setting_tab() &&
945 isset( $_GET['importer-type'] ) &&
946 $this->importer_type === give_clean( $_GET['importer-type'] );
947 }
948 }
949
950 Give_Import_Donations::get_instance()->setup();
951 }
952