PluginProbe
Welcart e-Commerce / 2.12.3
Welcart e-Commerce v2.12.3
2.12.4 2.12.3 2.11.35 2.12.2 2.12.1 2.11.34 2.11.33 2.11.32 2.11.31 2.11.30 1.3.16 1.3.17 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 All 292 releases
usc-e-shop / includes / importer / csv-importer-class.php

csv-importer-class.php in Welcart e-Commerce 2.12.3, at includes/importer/csv-importer-class.php

1,208 lines 42.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Welcart CSV Importer
4 *
5 * @package Welcart
6 */
7
8 // phpcs:disable WordPress.WP.AlternativeFunctions
9 // phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter
10 // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit;
14 }
15
16 /**
17 * Welcart CSV Importer class
18 */
19 class Welcart_CSV_Importer {
20
21 /**
22 * Instance
23 *
24 * @var Welcart_CSV_Importer
25 */
26 private static $instance = null;
27
28 /**
29 * Import session prefix
30 *
31 * @var string
32 */
33 private $import_transient_prefix = 'welcart_csv_import_';
34
35 /**
36 * Page title
37 *
38 * @var string
39 */
40 private $page_title;
41
42 /**
43 * Data columns
44 *
45 * @var array
46 */
47 private $table_columns = array();
48
49 /**
50 * Meta fields
51 *
52 * @var array
53 */
54 private $meta_fields = array();
55
56 /**
57 * Import type
58 *
59 * @var array
60 */
61 private $type;
62
63 /**
64 * Importer construct
65 *
66 * @param string $type Import type.
67 */
68 public function __construct( $type ) {
69
70 $this->type = $type;
71 if ( empty( $this->type ) ) {
72 add_action( 'admin_post_welcart_csv_upload', array( $this, 'handle_error' ) );
73 add_action( 'admin_post_welcart_csv_mapping', array( $this, 'handle_error' ) );
74 } else {
75 add_action( 'admin_post_welcart_csv_upload', array( $this, 'handle_csv_upload' ) );
76 add_action( 'admin_post_welcart_csv_mapping', array( $this, 'handle_csv_mapping' ) );
77 add_action( 'admin_post_download_csv_error_log', array( $this, 'download_error_log' ) );
78 add_action( 'wp_ajax_process_csv_chunk', array( $this, 'process_csv_chunk' ) );
79
80 $this->register_csv_import_handling_page();
81
82 }
83 }
84
85 /**
86 * Get instance
87 *
88 * @param string $type Import type.
89 * @return Welcart_CSV_Importer
90 */
91 public static function get_instance( $type ) {
92 if ( null === self::$instance ) {
93 self::$instance = new Welcart_CSV_Importer( $type );
94 }
95 return self::$instance;
96 }
97
98 /**
99 * Set condition data
100 *
101 * @param array $condition Condition data.
102 */
103 public function set_condition( $condition ) {
104 $this->page_title = isset( $condition['page_title'] ) ? $condition['page_title'] : __( 'Data Import', 'usces' );
105 $this->table_columns = isset( $condition['columns'] ) ? $condition['columns'] : array();
106 $this->meta_fields = isset( $condition['meta_fields'] ) ? $condition['meta_fields'] : array();
107 }
108
109 /**
110 * Add handling page
111 */
112 public function register_csv_import_handling_page() {
113 add_submenu_page(
114 'wel-hidden-page', // Specify a fake parent page to hide from the menu.
115 __( 'Welcart CSV Import', 'usces' ),
116 __( 'Welcart CSV Import', 'usces' ),
117 'manage_options',
118 'welcart-csv-importer',
119 array( $this, 'handle_import_page_action' )
120 );
121 }
122
123 /**
124 * Switch page
125 */
126 public function handle_import_page_action() {
127
128 if ( ! current_user_can( 'manage_options' ) ) {
129 $this->go_to_error_page( __( 'Permission error.', 'usces' ) . ' (#073)' );
130 }
131 check_admin_referer( 'welcart_csv_import', 'wc_nonce' );
132
133 $type = isset( $_GET['type'] ) ? sanitize_text_field( wp_unslash( $_GET['type'] ) ) : '';
134 if ( $this->type !== $type ) {
135 $this->render_error_page( __( 'Type does not match.', 'usces' ) . ' (#001)' );
136 }
137
138 $step = isset( $_GET['step'] ) ? sanitize_text_field( wp_unslash( $_GET['step'] ) ) : 'upload';
139
140 $import_id = isset( $_GET['import_id'] ) ? sanitize_text_field( wp_unslash( $_GET['import_id'] ) ) : '';
141 if ( ! $import_id && 'upload' !== $step ) {
142 $this->render_error_page( __( 'Invalid access.', 'usces' ) . ' (#050)' );
143 }
144
145 switch ( $step ) {
146 case 'upload':
147 $this->render_upload_form( $type );
148 break;
149 case 'preview':
150 $encoding = isset( $_GET['encoding'] ) ? sanitize_text_field( wp_unslash( $_GET['encoding'] ) ) : 'UTF-8';
151 $this->render_preview_and_mapping( $type, $import_id, $encoding );
152 break;
153 case 'import':
154 $this->render_import_progress( $type, $import_id );
155 break;
156 case 'result':
157 $this->render_result_page( $type, $import_id );
158 break;
159 case 'error':
160 $this->render_error_page();
161 break;
162 default:
163 $this->render_error_page( __( 'Invalid step. (#002)', 'usces' ) );
164 }
165 }
166
167 /**
168 * Upload form
169 *
170 * @param string $type Import type.
171 */
172 private function render_upload_form( $type ) {
173
174 if ( $this->type !== $type ) {
175 $this->render_error_page( __( 'Type does not match.', 'usces' ) . ' (#005)' );
176 }
177 ?>
178 <div class="wrap">
179 <h1><?php echo esc_html( $this->page_title ); ?></h1>
180 <p><?php echo esc_html__( 'Welcart CSV Importer', 'usces' ); ?></p>
181 <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" enctype="multipart/form-data">
182 <?php wp_nonce_field( 'welcart_csv_import', 'wc_nonce' ); ?>
183 <input type="hidden" name="action" value="welcart_csv_upload">
184 <input type="hidden" name="type" value="<?php echo esc_attr( $this->type ); ?>">
185 <table class="form-table">
186 <tr>
187 <th><label for="csv_file"><?php echo esc_html__( 'CSV or ZIP File', 'usces' ); ?></label></th>
188 <td>
189 <input type="file" name="csv_file" id="csv_file" accept=".csv,.zip" required>
190 </td>
191 </tr>
192 </table>
193 <?php submit_button( __( 'Upload', 'usces' ) ); ?>
194 </form>
195 </div>
196 <?php
197 }
198
199 /**
200 * File upload process
201 */
202 public function handle_csv_upload() {
203
204 if ( ! current_user_can( 'manage_options' ) ) {
205 $this->go_to_error_page( __( 'Permission error.', 'usces' ) . ' (#072)' );
206 }
207 check_admin_referer( 'welcart_csv_import', 'wc_nonce' );
208
209 $type = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : '';
210 if ( $this->type !== $type ) {
211 $this->go_to_error_page( __( 'Type does not match.', 'usces' ) . ' (#007)' );
212 }
213
214 if ( false !== $this->file_upload_error() ) {
215 $message = $this->file_upload_error();
216 $this->go_to_error_page( $message . __( ' (#008)', 'usces' ) );
217 }
218
219 $file_name_org = isset( $_FILES['csv_file']['name'] ) ? sanitize_text_field( wp_unslash( $_FILES['csv_file']['name'] ) ) : '';
220 if ( empty( $file_name_org ) ) {
221 $this->go_to_error_page( __( 'Failed to get file name.', 'usces' ) . ' (#009)' );
222 }
223 $file_name_org = sanitize_file_name( basename( urldecode( $file_name_org ) ) );
224 $temp_file_name = wp_unique_filename( WEL_IMPORT_UPLOADS_DIR, $file_name_org );
225 $uploaded_file = WEL_IMPORT_UPLOADS_DIR . '/' . $temp_file_name;
226
227 $allowed_types = array( 'text/csv', 'application/zip' );
228 $file_type = wp_check_filetype_and_ext( $uploaded_file, $file_name_org );
229 if ( ! in_array( $file_type['type'], $allowed_types, true ) ) {
230 $this->go_to_error_page( __( 'Please specify a CSV or ZIP file.', 'usces' ) . ' (#009)' );
231 }
232
233 // Delete all CSV files.
234 $files = glob( WEL_IMPORT_UPLOADS_DIR . '/*.csv' );
235 if ( is_array( $files ) ) {
236 foreach ( $files as $file ) {
237 if ( is_file( $file ) ) {
238 wp_delete_file( $file );
239 }
240 }
241 }
242
243 $tmp_name_org = isset( $_FILES['csv_file']['tmp_name'] ) ? sanitize_text_field( wp_unslash( $_FILES['csv_file']['tmp_name'] ) ) : '';
244 if ( empty( $tmp_name_org ) || ! move_uploaded_file( $tmp_name_org, $uploaded_file ) ) {
245 $this->go_to_error_page( __( 'Failed to save file.', 'usces' ) . ' (#009)' );
246 }
247
248 $ext = strtolower( pathinfo( $file_name_org, PATHINFO_EXTENSION ) );
249
250 if ( 'zip' === $ext ) {
251
252 // Extract CSV from ZIP.
253 $zip = new ZipArchive();
254
255 if ( true === $zip->open( $uploaded_file ) ) {
256
257 if ( $zip->numFiles > 2 ) {
258 $this->go_to_error_page( __( 'Too many files in ZIP.', 'usces' ) . ' (#030)' );
259 }
260
261 $csv_found = false;
262
263 for ( $i = 0; $i < $zip->numFiles; $i++ ) {
264
265 $entry = $zip->getNameIndex( $i );
266 if ( 'csv' === strtolower( pathinfo( $entry, PATHINFO_EXTENSION ) ) ) {
267
268 $csv_file_name = basename( $entry );
269 $temp_file_name = wp_unique_filename( WEL_IMPORT_UPLOADS_DIR, $csv_file_name );
270 $temp_file = WEL_IMPORT_UPLOADS_DIR . '/' . $temp_file_name;
271 if ( ! copy( "zip://{$uploaded_file}#{$entry}", $temp_file ) ) {
272 $this->go_to_error_page( __( 'Failed to extract CSV file from ZIP.', 'usces' ) . ' (#015)' );
273 }
274 $csv_found = true;
275 break;
276
277 } else {
278 $this->go_to_error_page( __( 'CSV file not found in ZIP.', 'usces' ) . ' (#031)' );
279 }
280 }
281 $zip->close();
282 wp_delete_file( $uploaded_file );
283
284 if ( ! $csv_found ) {
285 $this->go_to_error_page( __( 'CSV file not found in ZIP.', 'usces' ) . ' (#012)' );
286 }
287
288 $csv_name = $csv_file_name;
289
290 } else {
291 $this->go_to_error_page( __( 'Unable to open ZIP file.', 'usces' ) . ' (#013)' );
292 }
293 } else {
294
295 $temp_file = $uploaded_file;
296 $csv_name = $file_name_org;
297 }
298
299 $import_id = uniqid();
300
301 $data = array(
302 'temp_file' => $temp_file_name,
303 'csv_name' => $csv_name,
304 );
305 set_transient( $this->import_transient_prefix . $import_id, $data, 30 * MINUTE_IN_SECONDS );
306
307 $redirect_url = add_query_arg(
308 array(
309 'page' => 'welcart-csv-importer',
310 'step' => 'preview',
311 'type' => $this->type,
312 'import_id' => $import_id,
313 'wc_nonce' => wp_create_nonce( 'welcart_csv_import' ),
314 ),
315 admin_url( 'admin.php' )
316 );
317 wp_safe_redirect( $redirect_url );
318 exit;
319 }
320
321 /**
322 * Preview & Mapping page
323 *
324 * @param string $type Import type.
325 * @param string $import_id Import ID.
326 * @param string $encoding Character encoding.
327 */
328 private function render_preview_and_mapping( $type, $import_id, $encoding ) {
329
330 $data = get_transient( $this->import_transient_prefix . $import_id );
331 if ( ! $data ) {
332 $this->render_error_page( __( 'Import session not found.', 'usces' ) . ' (#051)' );
333 }
334
335 $temp_file_name = sanitize_file_name( basename( sanitize_text_field( wp_unslash( $data['temp_file'] ) ) ) );
336 $temp_file = WEL_IMPORT_UPLOADS_DIR . '/' . $temp_file_name;
337 $csv_name = sanitize_text_field( wp_unslash( $data['csv_name'] ) );
338
339 if ( ! file_exists( $temp_file ) ) {
340 $this->render_error_page( __( 'Temporary file not found.', 'usces' ) . ' ' . __( 'Please start over from the beginning.', 'usces' ) . ' (#017)' );
341 }
342
343 // To handle large files with low memory, do not use WP_Filesystem.
344 $handle = fopen( $temp_file, 'r' );
345 if ( false === $handle ) {
346 $this->render_error_page( __( 'Failed to read file.', 'usces' ) . ' ' . __( 'Please start over from the beginning.', 'usces' ) . ' (#018)' );
347 }
348
349 $sample = fread( $handle, 1000 );
350 $enc_type = mb_detect_encoding( $sample, array( 'SJIS-win', 'SJIS', 'UTF-8', 'EUC-JP' ), true );
351 rewind( $handle );
352
353 if ( 'SJIS' === $encoding && 'UTF-8' !== $enc_type ) {
354 stream_filter_append( $handle, 'convert.iconv.sjis-win/utf-8' );
355 }
356
357 $rows = array();
358 $max_rows = 6; // Retrieve maximum 6 rows for preview.
359 $i = 0;
360
361 while ( $i < $max_rows ) {
362 $data = fgetcsv( $handle );
363 if ( false === $data ) {
364 // End of file reached.
365 break;
366 }
367 // Exclude empty rows (allowing '0').
368 if ( ! empty( array_filter( $data, 'strlen' ) ) ) {
369 // Remove BOM from first field in first row.
370 if ( 0 === $i && isset( $data[0] ) && 0 === strncmp( $data[0], "\xEF\xBB\xBF", 3 ) ) {
371 $data[0] = substr( $data[0], 3 );
372 }
373 $rows[] = $data;
374 ++$i;
375 }
376 }
377 fclose( $handle );
378
379 if ( 'SJIS' === $encoding && 'UTF-8' === $enc_type ) {
380 $rows = array();
381 }
382 $num_columns = ! empty( $rows ) ? count( $rows[0] ) : 0;
383 $num_all_rows = $this->count_csv_lines( $temp_file, $encoding );
384 ?>
385 <div class="wrap">
386 <h1><?php echo esc_html( $this->page_title ); ?></h1>
387 <p><?php echo esc_html__( 'CSV Preview & Mapping', 'usces' ); ?></p>
388
389 <div class="guide-area">
390 <p><?php echo esc_html__( 'Preview the CSV file and perform data mapping.', 'usces' ); ?></p>
391 <p><?php echo esc_html__( 'If you wish to re-upload the CSV file, you can do so using the "Re-upload" option.', 'usces' ); ?></p>
392 <?php do_action( 'welcart_csv_preview_top_guide' ); ?>
393 </div>
394
395 <div id="toggle-upload-container">
396 <button type="button" id="toggle-upload"><?php echo esc_html__( 'Re-upload', 'usces' ); ?></button>
397 </div>
398
399 <div id="upload-container" style="display:none;">
400 <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" enctype="multipart/form-data" style="margin-bottom:20px;padding:10px;border:1px solid #ccc;background:#f1f1f1;">
401 <?php wp_nonce_field( 'welcart_csv_import', 'wc_nonce' ); ?>
402 <input type="hidden" name="action" value="welcart_csv_upload">
403 <input type="hidden" name="type" value="<?php echo esc_attr( $this->type ); ?>">
404 <input type="hidden" name="import_id" value="<?php echo esc_attr( $import_id ); ?>">
405 <div class="form-area" id="reupload-container" >
406 <p><?php echo esc_html__( 'CSV or ZIP File', 'usces' ); ?>(<?php echo esc_html__( 'Re-upload', 'usces' ); ?>)</p>
407 <p><input type="file" name="csv_file" id="csv_file" accept=".csv,.zip" required></p>
408 <?php submit_button( __( 'Upload', 'usces' ) ); ?>
409 </div>
410 </form>
411 </div>
412
413 <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
414 <?php wp_nonce_field( 'welcart_csv_import', 'wc_nonce' ); ?>
415 <input type="hidden" name="action" value="welcart_csv_mapping">
416 <input type="hidden" name="csv_encoding" value="<?php echo esc_attr( $encoding ); ?>">
417 <input type="hidden" name="type" value="<?php echo esc_attr( $this->type ); ?>">
418 <input type="hidden" name="import_id" value="<?php echo esc_attr( $import_id ); ?>">
419
420 <div class="form-area" id="setting-container">
421 <div class="field-area">
422 <p><span><?php echo esc_html__( 'Character Encoding', 'usces' ); ?></span>
423
424 <select id="csv_encoding_select" name="csv_encoding_select">
425 <option value="UTF-8" <?php selected( $encoding, 'UTF-8' ); ?>>UTF-8</option>
426 <option value="SJIS" <?php selected( $encoding, 'SJIS' ); ?>>Shift-JIS</option>
427 </select>
428 </p>
429 <p class="field-exp"><?php echo esc_html__( '* If characters are garbled, please select the appropriate encoding.', 'usces' ); ?></p>
430 </div>
431 <div class="field-area">
432 <p><span><?php echo esc_html__( 'Header Row', 'usces' ); ?></span>
433
434 <label><input type="radio" name="has_header" value="1" checked><?php echo esc_html__( 'Field Names', 'usces' ); ?></label>
435 <label><input type="radio" name="has_header" value="0"><?php echo esc_html__( 'Data', 'usces' ); ?></label>
436 </p>
437 <p class="field-exp"><?php echo esc_html__( '* If the first row contains field names, it will not be processed.', 'usces' ); ?></p>
438 </div>
439
440 <?php do_action( 'welcart_csv_preview_option' ); ?>
441
442 </div>
443
444 <h2><?php echo esc_html__( 'CSV Preview', 'usces' ); ?></h2>
445 <div id="csv-preview-container" style="overflow-x:auto;">
446 <p class="csvfile-name"><?php echo esc_html__( 'File Name: ', 'usces' ) . esc_html( $csv_name ); ?></p>
447 <p class="csvfile-name"><?php echo esc_html__( 'Valid Data Count: ', 'usces' ); ?><span id="all_data_num"></span></p>
448 <table class="widefat">
449 <thead id="csv-preview-thead"></thead>
450 <tbody id="csv-preview-tbody"></tbody>
451 </table>
452 </div>
453
454 <h2><?php echo esc_html__( 'Data Mapping', 'usces' ); ?></h2>
455 <div class="guide-area">
456 <p><?php echo esc_html__( 'The first column is required. At least one additional column must be selected.', 'usces' ); ?></p>
457 <?php do_action( 'welcart_csv_mapping_top_guide' ); ?>
458 </div>
459
460 <div class="form-area" id="setting-container">
461 <?php do_action( 'welcart_csv_mapping_option' ); ?>
462 </div>
463
464 <div id="mapping-container">
465 <table class="form-table" id="main-column-mapping">
466 <?php foreach ( $this->table_columns as $col_key => $col_label ) : ?>
467 <tr>
468 <th><label for="mapping_<?php echo esc_attr( $col_key ); ?>"><?php echo esc_html( $col_label ); ?></label></th>
469 <td>
470 <select name="mapping[<?php echo esc_attr( $col_key ); ?>]" id="mapping_<?php echo esc_attr( $col_key ); ?>" data-default="<?php echo esc_attr( $col_label ); ?>">
471 <!-- Generated by JS -->
472 </select>
473 </td>
474 </tr>
475 <?php endforeach; ?>
476 </table>
477 <?php if ( ! empty( $this->meta_fields ) ) : ?>
478 <?php echo esc_html__( 'Meta Fields', 'usces' ); ?>
479 <table class="form-table" id="meta-column-mapping">
480 <?php foreach ( $this->meta_fields as $col_key => $col_label ) : ?>
481 <tr>
482 <th><label for="mapping_<?php echo esc_attr( $col_key ); ?>"><?php echo esc_html( $col_label ); ?></label></th>
483 <td>
484 <select name="mapping[<?php echo esc_attr( $col_key ); ?>]" id="mapping_<?php echo esc_attr( $col_key ); ?>" data-default="<?php echo esc_attr( $col_label ); ?>">
485 <!-- Generated by JS -->
486 </select>
487 </td>
488 </tr>
489 <?php endforeach; ?>
490 </table>
491 <?php endif; ?>
492
493 <?php do_action( 'welcart_csv_after_mapping_table' ); ?>
494
495 <div id="submit-container">
496 <p class="submit"><input type="submit" name="submit" id="import_submit" class="button button-primary" value="<?php echo esc_attr__( 'Start Update', 'usces' ); ?>" ></p>
497 </div>
498 </form>
499 </div>
500 <script>
501 (function($){
502 var previewData = <?php echo wp_json_encode( $rows ); ?>;
503 var numColumns = <?php echo absint( $num_columns ); ?>;
504 var numAllData = <?php echo absint( $num_all_rows ); ?>;
505
506 <?php do_action( 'welcart_csv_preview_pre_js' ); ?>
507
508 function escapeHtml(txt){
509 return $('<div/>').text(txt).html();
510 }
511
512 function updatePreview(){
513
514 if(previewData.length===0){
515 $('#csv-preview-container').html('<?php echo esc_js( __( 'Unable to load data', 'usces' ) ); ?>');
516 $('#mapping-container').html('');
517 $('#import_submit').prop('disabled', true);
518 return;
519 }
520 var hasHeader = $('input[name="has_header"]:checked').val();
521 var headerHTML = '';
522 var startIndex = 0;
523 if( hasHeader==='1' && previewData.length>0 ) {
524 $.each(previewData[0], function(i, cell){
525 var txt = cell ? cell : '<?php echo esc_js( __( 'Column', 'usces' ) ); ?>'+(i+1);
526 headerHTML += '<th>' + escapeHtml(txt) + '</th>';
527 });
528 startIndex = 1;
529 $('#all_data_num').html(numAllData-1);
530 } else {
531 for(var i = 0; i < numColumns; i++){
532 headerHTML += '<th><?php echo esc_js( __( 'Column', 'usces' ) ); ?>'+(i+1)+'</th>';
533 }
534 $('#all_data_num').html(numAllData);
535 }
536 $('#csv-preview-thead').html('<tr>' + headerHTML + '</tr>');
537
538 var bodyHTML = '';
539 for(var r = startIndex; r < Math.min(previewData.length, startIndex + 5); r++){
540 bodyHTML += '<tr>';
541 $.each(previewData[r], function(j, cell){
542 bodyHTML += '<td>' + escapeHtml(cell) + '</td>';
543 });
544 bodyHTML += '</tr>';
545 }
546 $('#csv-preview-tbody').html(bodyHTML);
547
548 $('#mapping-container select').each(function(){
549 var defaultColLabel = $(this).data('default');
550 var opts = '<option value=""><?php echo esc_js( __( '(Not Set)', 'usces' ) ); ?></option>';
551 for(var c = 0; c < numColumns; c++){
552 var cellText = '';
553 if(hasHeader==='1' && previewData.length > 0){
554 cellText = previewData[0][c] ? previewData[0][c] : '<?php echo esc_js( __( 'Column', 'usces' ) ); ?>' + (c+1);
555 } else {
556 cellText = '<?php echo esc_js( __( 'Column', 'usces' ) ); ?>' + (c+1);
557 }
558 var selected = (defaultColLabel === cellText) ? ' selected="selected"' : '';
559 opts += '<option value="' + c + '"' + selected + '">'+escapeHtml(cellText) + '</option>';
560 }
561 $(this).html(opts);
562 });
563 }
564
565 function updateSubmitButton(){
566 var selects = $('#mapping-container select');
567 if(selects.length === 0){
568 $('#import_submit').prop('disabled', true);
569 return;
570 }
571
572 // If the first select is empty, disable submit.
573 var firstVal = selects.first().val();
574 if(firstVal === ''){
575 $('#import_submit').prop('disabled', true);
576 return;
577 }
578
579 // If all selects (except the first) are empty, disable submit.
580 var othersAllEmpty = true;
581 selects.slice(1).each(function(){
582 if($(this).val() !== ''){
583 othersAllEmpty = false;
584 return false;
585 }
586 });
587 if(othersAllEmpty){
588 $('#import_submit').prop('disabled', true);
589 } else {
590 $('#import_submit').prop('disabled', false);
591 }
592 }
593
594 $('input[name="has_header"]').on('change', updatePreview);
595 $('#csv_encoding_select').on('change', function(){
596 var enc = $(this).val();
597 var type = $('input[name="type"]').val();
598 var import_id = $('input[name="import_id"]').val();
599 var wc_nonce = $('#wc_nonce').val();
600 var url = new URL(window.location.href);
601 url.searchParams.set('encoding', enc);
602 url.searchParams.set('type', type);
603 url.searchParams.set('import_id', import_id);
604 url.searchParams.set('wc_nonce', wc_nonce);
605 window.location.href = url.href;
606 });
607 $('#mapping-container').on('change', 'select', updateSubmitButton);
608 $('#toggle-upload').on('click', function(){
609 if ($('#upload-container').is(':visible')) {
610 // If form is visible, hide it and change button text back to "Re-upload"
611 $('#upload-container').hide();
612 $(this).text('<?php echo esc_js( __( 'Re-upload', 'usces' ) ); ?>');
613 } else {
614 // If form is hidden, show it and change button text to "Close"
615 $('#upload-container').show();
616 $(this).text('<?php echo esc_js( __( 'Close', 'usces' ) ); ?>');
617 }
618 });
619
620 // Function to highlight mapped columns
621 function updateMappingHighlights(){
622 // Remove highlight class from all headers and cells.
623 $('#csv-preview-thead th, #csv-preview-tbody td').removeClass('mapped-column');
624
625 // Process each select within mapping-container.
626 $('#mapping-container select').each(function(){
627 var colIndex = $(this).val();
628 if(colIndex !== ''){
629 // Add class to corresponding header.
630 $('#csv-preview-thead th').eq(colIndex).addClass('mapped-column');
631 // Add class to corresponding cell in each row.
632 $('#csv-preview-tbody tr').each(function(){
633 $(this).find('td').eq(colIndex).addClass('mapped-column');
634 });
635 }
636 });
637 }
638
639 // Call updateMappingHighlights after updateSubmitButton.
640 $('#mapping-container').on('change', 'select', function(){
641 updateSubmitButton();
642 updateMappingHighlights();
643 });
644
645 updatePreview();
646 updateSubmitButton();
647 updateMappingHighlights();
648
649 <?php do_action( 'welcart_csv_preview_post_js' ); ?>
650
651 })(jQuery);
652 </script>
653 <?php
654 }
655
656 /**
657 * Save mapping info => Start import
658 */
659 public function handle_csv_mapping() {
660
661 if ( ! current_user_can( 'manage_options' ) ) {
662 $this->go_to_error_page( __( 'Permission error.', 'usces' ) . ' (#071)' );
663 }
664 check_admin_referer( 'welcart_csv_import', 'wc_nonce' );
665
666 $type = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : '';
667 if ( $this->type !== $type ) {
668 $this->go_to_error_page( __( 'Type does not match.', 'usces' ) . ' (#020)' );
669 }
670
671 $import_id = isset( $_POST['import_id'] ) ? sanitize_text_field( wp_unslash( $_POST['import_id'] ) ) : '';
672 if ( ! $import_id ) {
673 $this->go_to_error_page( __( 'Invalid access.', 'usces' ) . ' (#053)' );
674 }
675 $data = get_transient( $this->import_transient_prefix . $import_id );
676 if ( ! $data ) {
677 $this->go_to_error_page( __( 'Import session not found.', 'usces' ) . ' (#054)' );
678 }
679
680 $temp_file_name = sanitize_file_name( basename( sanitize_text_field( wp_unslash( $data['temp_file'] ) ) ) );
681 $temp_file = WEL_IMPORT_UPLOADS_DIR . '/' . $temp_file_name;
682 $csv_name = sanitize_text_field( wp_unslash( $data['csv_name'] ) );
683
684 $csv_encoding = isset( $_POST['csv_encoding'] ) ? sanitize_text_field( wp_unslash( $_POST['csv_encoding'] ) ) : 'UTF-8';
685 $has_header = isset( $_POST['has_header'] ) ? (bool) sanitize_text_field( wp_unslash( $_POST['has_header'] ) ) : false;
686
687 if ( isset( $_POST['mapping'] ) && is_array( $_POST['mapping'] ) && ! empty( $_POST['mapping'] ) ) {
688 $mapping = array_map( 'sanitize_text_field', wp_unslash( $_POST['mapping'] ) );
689 } else {
690 $this->go_to_error_page( __( 'Required fields have not been selected. (#033)', 'usces' ) );
691 }
692
693 if ( empty( $temp_file ) || ! file_exists( $temp_file ) ) {
694 $this->go_to_error_page( __( 'Temporary file not found.', 'usces' ) . ' ' . __( 'Please re-upload the CSV.', 'usces' ) . ' (#021)' );
695 }
696 $total_lines = $this->count_csv_lines( $temp_file, $csv_encoding );
697 if ( $total_lines <= 0 ) {
698 $this->go_to_error_page( __( 'CSV file is empty. Please check the content.', 'usces' ) . ' (#034)' );
699 }
700
701 $data = array(
702 'temp_file' => $temp_file,
703 'csv_name' => $csv_name,
704 'csv_encoding' => $csv_encoding,
705 'has_header' => $has_header,
706 'mapping' => $mapping,
707 'total_lines' => $total_lines,
708 'offset' => $has_header ? 1 : 0,
709 'imported' => 0,
710 'start_time' => time(),
711 'inserted_count' => 0,
712 'updated_count' => 0,
713 'memory_limit' => ini_get( 'memory_limit' ),
714 );
715 $data = apply_filters( 'welcart_csv_import_transient_data', $data, $import_id );
716 set_transient( $this->import_transient_prefix . $import_id, $data, 30 * MINUTE_IN_SECONDS );
717
718 // Initialize error log.
719 $error_log_path = $this->get_error_log_path();
720 file_put_contents( $error_log_path, '' );
721
722 $redirect_url = add_query_arg(
723 array(
724 'page' => 'welcart-csv-importer',
725 'step' => 'import',
726 'type' => $this->type,
727 'import_id' => $import_id,
728 'wc_nonce' => wp_create_nonce( 'welcart_csv_import' ),
729 ),
730 admin_url( 'admin.php' )
731 );
732 wp_safe_redirect( $redirect_url );
733 exit;
734 }
735
736 /**
737 * Import progress page
738 *
739 * @param string $type Import type.
740 * @param string $import_id Import ID.
741 */
742 private function render_import_progress( $type, $import_id ) {
743
744 $data = get_transient( $this->import_transient_prefix . $import_id );
745 if ( ! $data ) {
746 $this->render_error_page( __( 'Import session not found.', 'usces' ) . ' (#024)' );
747 }
748
749 $memory_limit = isset( $data['memory_limit'] ) ? $data['memory_limit'] : '';
750 $memory_usage = isset( $data['memory_usage'] ) ? $data['memory_usage'] : '';
751
752 $has_header = isset( $data['has_header'] ) ? $data['has_header'] : false;
753 if ( $has_header ) {
754 $total_lines = (int) $data['total_lines'] - 1;
755 } else {
756 $total_lines = (int) $data['total_lines'];
757 }
758 ?>
759 <div class="wrap">
760 <h1><?php echo esc_html( $this->page_title ); ?></h1>
761 <p><?php echo esc_html__( 'Import Progress', 'usces' ); ?></p>
762 <div class="guide-area">
763 <p><?php echo esc_html__( 'Please keep this page open until the import process is complete. Do not refresh, change pages, or close your browser.', 'usces' ); ?></p>
764 <p><?php echo esc_html__( 'If the sum of added and updated records does not equal the total count, some data was not imported. Please check the error log after processing.', 'usces' ); ?></p>
765 <?php do_action( 'welcart_csv_import_top_guide' ); ?>
766 </div>
767 <div>
768 <p><strong><?php echo esc_html__( 'CSV File Name', 'usces' ); ?>:</strong> <?php echo esc_html( $data['csv_name'] ); ?></p>
769 <p><strong><?php echo esc_html__( 'Total Count', 'usces' ); ?>:</strong> <?php echo esc_html( $total_lines ); ?></p>
770 <p><strong><?php echo esc_html__( 'Processed Count', 'usces' ); ?>:</strong> <span id="processed-rows"><?php echo esc_html( $data['offset'] ); ?></span></p>
771 <p><strong><?php echo esc_html__( 'Added Count', 'usces' ); ?>:</strong> <span id="inserted-count"><?php echo esc_html( $data['inserted_count'] ); ?></span></p>
772 <p><strong><?php echo esc_html__( 'Updated Count', 'usces' ); ?>:</strong> <span id="updated-count"><?php echo esc_html( $data['updated_count'] ); ?></span></p>
773 <p><strong><?php echo esc_html__( 'Memory Usage', 'usces' ); ?>:</strong> <span id="memory_usage"></span> / <?php echo esc_html( $memory_limit ); ?></p>
774 <p><strong><?php echo esc_html__( 'Estimated Remaining Time', 'usces' ); ?>:</strong> <span id="estimated-time">--</span></p>
775 </div>
776 <div id="progress-container" style="border:1px solid #ccc;width:100%;background:#f7f7f7;margin:10px 0;">
777 <div id="progress-bar" style="width:0%;height:30px;background:#0073aa;"></div>
778 </div>
779 <p id="progress-text">0%</p>
780 <div id="import-result"></div>
781 </div>
782 <script>
783 window.wel_csv_importer_data = window.wel_csv_importer_data || {};
784 window.wel_csv_importer_data.initial_offset = <?php echo intval( $data['offset'] ); ?>;
785 window.wel_csv_importer_importId = "<?php echo esc_js( $import_id ); ?>";
786 window.wel_csv_importer_nonce = "<?php echo esc_html( wp_create_nonce( 'process_csv_chunk_nonce' ) ); ?>";
787 window.wel_csv_complete_nonce = "<?php echo esc_html( wp_create_nonce( 'welcart_csv_import' ) ); ?>";
788 window.wel_csv_importer_csvName = "<?php echo esc_js( $data['csv_name'] ); ?>";
789 window.wel_csv_importer_type = "<?php echo esc_js( $this->type ); ?>";
790 window.onbeforeunload = function(){
791 return "<?php echo esc_js( __( 'Import is in progress. Leaving this page will interrupt the process.', 'usces' ) ); ?>";
792 };
793 </script>
794 <?php
795 }
796
797 /**
798 * Process CSV chunk
799 */
800 public function process_csv_chunk() {
801 if ( ! current_user_can( 'manage_options' ) ) {
802 wp_send_json_error( array( 'message' => __( 'Permission error.', 'usces' ) . ' (#070)' ) );
803 }
804
805 if ( ! check_ajax_referer( 'process_csv_chunk_nonce', '_wpnonce', false ) ) {
806 wp_send_json_error( array( 'message' => __( 'Security check failed. Please reload the page.', 'usces' ) ) );
807 }
808
809 $type = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : '';
810 if ( $this->type !== $type ) {
811 wp_send_json_error( array( 'message' => __( 'Type is invalid.', 'usces' ) ) );
812 }
813
814 $import_id = isset( $_POST['import_id'] ) ? sanitize_text_field( wp_unslash( $_POST['import_id'] ) ) : '';
815 $offset = isset( $_POST['offset'] ) ? intval( $_POST['offset'] ) : 0;
816 if ( empty( $import_id ) ) {
817 wp_send_json_error( array( 'message' => __( 'Invalid import ID. Please re-upload the CSV.', 'usces' ) ) );
818 }
819
820 // Get session.
821 $data = get_transient( $this->import_transient_prefix . $import_id );
822 if ( ! $data ) {
823 wp_send_json_error( array( 'message' => __( 'Import session has expired. Please re-upload the CSV.', 'usces' ) ) );
824 }
825
826 $temp_file = $data['temp_file'];
827 $csv_encoding = $data['csv_encoding'];
828 $has_header = $data['has_header'];
829 $mapping = $data['mapping'];
830 $total_lines = $data['total_lines'];
831 $imported = isset( $data['imported'] ) ? intval( $data['imported'] ) : 0;
832 $start_time = isset( $data['start_time'] ) ? intval( $data['start_time'] ) : time();
833
834 $inserted_count = isset( $data['inserted_count'] ) ? intval( $data['inserted_count'] ) : 0;
835 $updated_count = isset( $data['updated_count'] ) ? intval( $data['updated_count'] ) : 0;
836
837 if ( ! file_exists( $temp_file ) ) {
838 wp_send_json_error( array( 'message' => __( 'CSV file not found. Please re-upload the CSV.', 'usces' ) ) );
839 }
840
841 $handle = fopen( $temp_file, 'r' );
842 if ( 'SJIS' === $csv_encoding ) {
843 stream_filter_append( $handle, 'convert.iconv.sjis-win/utf-8' );
844 }
845
846 if ( ! $handle ) {
847 wp_send_json_error( array( 'message' => __( 'Unable to open CSV file. Please re-upload the CSV.', 'usces' ) ) );
848 }
849
850 // Move pointer according to offset.
851 for ( $i = 0; $i < $offset; $i++ ) {
852 fgetcsv( $handle );
853 }
854
855 $process_info = array(
856 'inserted_count' => 0,
857 'updated_count' => 0,
858 'imported' => 0,
859 'processed' => 0,
860 );
861 // Process each chunk via hook.
862 $process_info = apply_filters( 'wel_csv_importer_chunk_process', $process_info, $handle, $data );
863
864 fclose( $handle );
865
866 $new_offset = $offset + $process_info['processed'];
867 $data['offset'] = $new_offset;
868 $data['imported'] += $process_info['imported'];
869 $data['inserted_count'] += $process_info['inserted_count'];
870 $data['updated_count'] += $process_info['updated_count'];
871 set_transient( $this->import_transient_prefix . $import_id, $data, 30 * MINUTE_IN_SECONDS );
872
873 $percent = min( 100, intval( ( $new_offset / $total_lines ) * 100 ) );
874 $complete = ( $new_offset >= $total_lines );
875 $elapsed = time() - $start_time;
876 $avg_time_per_row = $offset > 0 ? ( $elapsed / $offset ) : 0;
877 $remaining_rows = $total_lines - $new_offset;
878 $estimated_time = round( $avg_time_per_row * $remaining_rows );
879 $formatted_time = $this->format_seconds( $estimated_time );
880 $memory_usage = number_format( memory_get_peak_usage() / 1024 / 1024, 1 ) . ' M';
881
882 wp_send_json_success(
883 array(
884 'next_offset' => $new_offset,
885 'percent' => $percent,
886 'complete' => $complete,
887 'total' => $total_lines,
888 'imported' => $data['imported'],
889 'added' => $data['inserted_count'],
890 'updated' => $data['updated_count'],
891 'estimated_time' => $formatted_time,
892 'memory_usage' => $memory_usage,
893 )
894 );
895 }
896
897 /**
898 * Import completion page
899 *
900 * @param string $type Import type.
901 * @param string $import_id Import ID.
902 */
903 private function render_result_page( $type, $import_id ) {
904
905 $data = get_transient( $this->import_transient_prefix . $import_id );
906 if ( ! $data ) {
907 $this->render_error_page( __( 'Import session not found.', 'usces' ) . ' (#024)' );
908 }
909
910 if ( file_exists( WEL_IMPORT_UPLOADS_DIR ) ) {
911 // Delete all existing CSV files.
912 $files = glob( WEL_IMPORT_UPLOADS_DIR . '/*.csv' );
913 if ( is_array( $files ) ) {
914 foreach ( $files as $file ) {
915 if ( is_file( $file ) ) {
916 wp_delete_file( $file );
917 }
918 }
919 }
920 }
921
922 $total = isset( $data['total_lines'] ) ? $data['total_lines'] : 0;
923 $updated = isset( $data['updated_count'] ) ? $data['updated_count'] : '';
924 $added = isset( $data['inserted_count'] ) ? $data['inserted_count'] : '';
925 $imported = isset( $data['imported'] ) ? $data['imported'] : '';
926 $csv_name = isset( $data['csv_name'] ) ? $data['csv_name'] : '';
927 $has_header = isset( $data['has_header'] ) ? $data['has_header'] : false;
928 if ( $has_header ) {
929 $total_lines = (int) $total - 1;
930 } else {
931 $total_lines = (int) $total;
932 }
933
934 ?>
935 <div class="wrap">
936 <h1><?php echo esc_html( $this->page_title ); ?></h1>
937 <p><?php echo esc_html__( 'Import Completed', 'usces' ); ?></p>
938 <div class="guide-area">
939 <p><?php echo esc_html__( 'If the sum of added and updated records does not equal the total count, some data was not imported. Please check the error log after processing.', 'usces' ); ?></p>
940 <?php do_action( 'welcart_csv_result_top_guide' ); ?>
941 </div>
942 <table class="widefat">
943 <tbody>
944 <tr>
945 <th><?php echo esc_html__( 'CSV File Name', 'usces' ); ?></th>
946 <td><?php echo esc_html( $csv_name ); ?></td>
947 </tr>
948 <tr>
949 <th><?php echo esc_html__( 'Total Count', 'usces' ); ?></th>
950 <td><?php echo intval( $total_lines ); ?></td>
951 </tr>
952 <tr>
953 <th><?php echo esc_html__( 'Processed Count', 'usces' ); ?></th>
954 <td><?php echo intval( $imported ); ?></td>
955 </tr>
956 <tr>
957 <th><?php echo esc_html__( 'Added Count', 'usces' ); ?></th>
958 <td><?php echo intval( $added ); ?></td>
959 </tr>
960 <tr>
961 <th><?php echo esc_html__( 'Updated Count', 'usces' ); ?></th>
962 <td><?php echo intval( $updated ); ?></td>
963 </tr>
964 </tbody>
965 </table>
966 <?php
967 $error_log_path = $this->get_error_log_path();
968 if ( file_exists( $error_log_path ) ) {
969 if ( 0 === filesize( $error_log_path ) ) {
970
971 // No error.
972 file_put_contents( $error_log_path, __( "No error.\n", 'usces' ) );
973 $first50 = __( "No error.\n", 'usces' );
974 echo '<p>' . esc_html__( 'No Error', 'usces' ) . '</p>';
975
976 } else {
977
978 $lines = file( $error_log_path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
979 $first50 = array_slice( $lines, 0, 50 );
980 $error_log = implode( "\n", $first50 );
981 $num_log = count( $lines );
982 if ( $num_log > 50 ) {
983 $error_log .= "\n" . __( 'More...', 'usces' );
984 }
985 $args = array(
986 'action' => 'download_csv_error_log',
987 'type' => $this->type,
988 'wc_nonce' => wp_create_nonce( 'download_csv_error_log' ),
989 );
990 $admin_url = add_query_arg( $args, admin_url( 'admin-post.php' ) );
991 ?>
992 <h2><?php echo esc_html__( 'Error Log', 'usces' ); ?></h2>
993 <p>
994 <a href="<?php echo esc_url( $admin_url ); ?>" class="button">
995 <?php echo esc_html__( 'Download Error Log', 'usces' ); ?>
996 </a>
997 </p>
998 <pre style="background:#f7f7f7;padding:10px;"><?php echo esc_html( $error_log ); ?></pre>
999 <?php
1000
1001 }
1002 } else {
1003 echo '<p>' . esc_html__( 'No log file found.', 'usces' ) . '</p>';
1004 }
1005 ?>
1006 </div>
1007 <?php
1008 }
1009
1010 /**
1011 * Error page
1012 *
1013 * @param string $message Error message.
1014 */
1015 private function render_error_page( $message = '' ) {
1016
1017 if ( empty( $message ) ) {
1018 $message = get_transient( 'welcart_csv_import_error' );
1019 }
1020 if ( ! $message ) {
1021 $message = __( 'No message provided.', 'usces' );
1022 }
1023 ?>
1024 <div class="wrap">
1025 <h1><?php echo esc_html( $this->page_title ); ?></h1>
1026 <p><?php echo esc_html__( 'An error occurred', 'usces' ); ?></p>
1027 <div class="guide-area">
1028 <p><?php echo esc_html( $message ); ?></p>
1029 </div>
1030 </div>
1031 <?php
1032 do_action( 'admin_print_footer_scripts' );
1033 do_action( 'admin_footer' );
1034 do_action( 'admin_print_scripts' );
1035 do_action( 'admin_print_styles' );
1036
1037 exit;
1038 }
1039
1040 /**
1041 * Redirect to error page
1042 *
1043 * @param string $message Error message.
1044 */
1045 private function go_to_error_page( $message ) {
1046 set_transient( 'welcart_csv_import_error', $message, 5 * MINUTE_IN_SECONDS );
1047 $redirect_url = add_query_arg(
1048 array(
1049 'page' => 'welcart-csv-importer',
1050 'step' => 'error',
1051 'type' => $this->type,
1052 'wc_nonce' => wp_create_nonce( 'welcart_csv_import' ),
1053 ),
1054 admin_url( 'admin.php' )
1055 );
1056 wp_safe_redirect( $redirect_url );
1057 exit;
1058 }
1059
1060 /**
1061 * Download error log
1062 */
1063 public function download_error_log() {
1064 if ( ! current_user_can( 'manage_options' ) ) {
1065 $this->go_to_error_page( __( 'Permission error.', 'usces' ) . ' (#060)' );
1066 }
1067 check_admin_referer( 'download_csv_error_log', 'wc_nonce' );
1068
1069 $error_log_path = $this->get_error_log_path();
1070 if ( ! file_exists( $error_log_path ) ) {
1071 $this->render_error_page( __( 'Error log file not found.', 'usces' ) . ' (#028)' );
1072 }
1073 header( 'Content-Description: File Transfer' );
1074 header( 'Content-Type: text/plain; charset=UTF-8' );
1075 header( 'Content-Disposition: attachment; filename="csv_error_log.txt"' );
1076 header( 'Content-Length: ' . filesize( $error_log_path ) );
1077 readfile( $error_log_path );
1078 exit;
1079 }
1080
1081 /**
1082 * Count CSV lines
1083 *
1084 * @param string $file File path.
1085 * @param string $encoding Character encoding.
1086 * @return int Line count.
1087 */
1088 private function count_csv_lines( $file, $encoding ) {
1089 $count = 0;
1090 $handle = fopen( $file, 'r' );
1091 if ( ! $handle ) {
1092 return 0;
1093 }
1094 while ( true ) {
1095 $data = fgetcsv( $handle );
1096 if ( false === $data ) {
1097 break;
1098 }
1099 if ( ! empty( array_filter( $data ) ) ) {
1100 ++$count;
1101 }
1102 }
1103 fclose( $handle );
1104 return $count;
1105 }
1106
1107 /**
1108 * Get main columns
1109 */
1110 public function get_columns() {
1111 return $this->table_columns;
1112 }
1113
1114 /**
1115 * Get meta fields
1116 */
1117 public function get_meta_fields() {
1118 return $this->meta_fields;
1119 }
1120
1121 /**
1122 * Format seconds to time string
1123 *
1124 * @param int $seconds Seconds.
1125 * @return string Formatted time.
1126 */
1127 private function format_seconds( $seconds ) {
1128 $hours = floor( $seconds / 3600 );
1129 $minutes = floor( ( $seconds % 3600 ) / 60 );
1130 $secs = $seconds % 60;
1131 $str = '';
1132 if ( $hours > 0 ) {
1133 $str .= $hours . __( ' hours ', 'usces' );
1134 }
1135 if ( $minutes > 0 ) {
1136 $str .= $minutes . __( ' minutes ', 'usces' );
1137 }
1138 $str .= $secs . __( ' seconds', 'usces' );
1139 return $str;
1140 }
1141
1142 /**
1143 * File upload error message
1144 *
1145 * @return string Error message.
1146 */
1147 private function file_upload_error() {
1148 // phpcs:disable WordPress.Security.NonceVerification -- Already verified inside CSV importer class
1149 if ( ! isset( $_FILES['csv_file'] ) || empty( $_FILES['csv_file']['name'] ) ) {
1150 return __( 'Please select a file to upload.', 'usces' );
1151 }
1152 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
1153 $file = $_FILES['csv_file'];
1154 // phpcs:enable WordPress.Security.NonceVerification.Recommended
1155
1156 // Get error code.
1157 $error_code = absint( $file['error'] );
1158 $error_message = '';
1159
1160 // Error code messages.
1161 switch ( $error_code ) {
1162 case UPLOAD_ERR_OK:
1163 $error_message = false;
1164 break;
1165 case UPLOAD_ERR_INI_SIZE:
1166 $error_message = __( 'File size is too large.', 'usces' );
1167 break;
1168 case UPLOAD_ERR_FORM_SIZE:
1169 $error_message = __( 'Exceeds maximum file size specified in the form.', 'usces' );
1170 break;
1171 case UPLOAD_ERR_PARTIAL:
1172 $error_message = __( 'File was only partially uploaded.', 'usces' );
1173 break;
1174 case UPLOAD_ERR_NO_FILE:
1175 $error_message = __( 'No file selected.', 'usces' );
1176 break;
1177 case UPLOAD_ERR_NO_TMP_DIR:
1178 $error_message = __( 'Missing a temporary folder.', 'usces' );
1179 break;
1180 case UPLOAD_ERR_CANT_WRITE:
1181 $error_message = __( 'Failed to write file to disk.', 'usces' );
1182 break;
1183 case UPLOAD_ERR_EXTENSION:
1184 $error_message = __( 'File upload stopped by extension.', 'usces' );
1185 break;
1186 default:
1187 $error_message = __( 'An unknown error occurred.', 'usces' );
1188 break;
1189 }
1190
1191 return $error_message;
1192 }
1193
1194 /**
1195 * Error handling
1196 */
1197 public function handle_error() {
1198 $this->render_error_page( __( 'Import type not specified. (#029)', 'usces' ) );
1199 }
1200
1201 /**
1202 * Get error log file path
1203 */
1204 public function get_error_log_path() {
1205 return WEL_IMPORT_UPLOADS_DIR . '/csv-error-log.txt';
1206 }
1207 }
1208