PluginProbe
Import WP – CSV & XML Import Export for WordPress / 2.7.12
Import WP – CSV & XML Import Export for WordPress v2.7.12
2.15.1 2.15.0 2.14.24 2.14.23 2.7.0 2.7.1 2.7.10 2.7.11 2.7.12 2.7.13 2.7.14 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.2 2.8.3 2.9.0 2.9.1 All 144 releases
jc-importer / class / Common / Importer / ImporterManager.php

ImporterManager.php in Import WP – CSV & XML Import Export for WordPress 2.7.12, at class/Common/Importer/ImporterManager.php

882 lines 28.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace ImportWP\Common\Importer;
4
5 use ImportWP\Common\Filesystem\Filesystem;
6 use ImportWP\Common\Importer\Config\Config;
7 use ImportWP\Common\Importer\File\CSVFile;
8 use ImportWP\Common\Importer\File\XMLFile;
9 use ImportWP\Common\Importer\Mapper\PostMapper;
10 use ImportWP\Common\Importer\Mapper\TermMapper;
11 use ImportWP\Common\Importer\Mapper\UserMapper;
12 use ImportWP\Common\Importer\Parser\CSVParser;
13 use ImportWP\Common\Importer\Parser\XMLParser;
14 use ImportWP\Common\Importer\Permission\Permission;
15 use ImportWP\Common\Importer\State\ImporterState;
16 use ImportWP\Common\Importer\Template\CustomPostTypeTemplate;
17 use ImportWP\Common\Importer\Template\PageTemplate;
18 use ImportWP\Common\Importer\Template\PostTemplate;
19 use ImportWP\Common\Importer\Template\Template;
20 use ImportWP\Common\Importer\Template\TemplateManager;
21 use ImportWP\Common\Importer\Template\TermTemplate;
22 use ImportWP\Common\Importer\Template\UserTemplate;
23 use ImportWP\Common\Model\ImporterModel;
24 use ImportWP\Common\Properties\Properties;
25 use ImportWP\Common\Runner\ImporterRunnerState;
26 use ImportWP\Common\Util\Logger;
27 use ImportWP\Common\Util\Util;
28 use ImportWP\Container;
29 use ImportWP\EventHandler;
30
31 class ImporterManager
32 {
33
34 /**
35 * @var Filesystem
36 */
37 private $filesystem;
38
39 /**
40 * @var TemplateManager $template_manager
41 */
42 private $template_manager;
43
44 /**
45 * @var EventHandler $event_handler
46 */
47 protected $event_handler;
48
49 public function __construct(Filesystem $filesystem, TemplateManager $template_manager, EventHandler $event_handler)
50 {
51 $this->filesystem = $filesystem;
52 $this->template_manager = $template_manager;
53 $this->event_handler = $event_handler;
54 }
55
56 /**
57 * Get Importers
58 *
59 * @return ImporterModel[]
60 */
61 public function get_importers()
62 {
63
64 $result = array();
65 $query = new \WP_Query(array(
66 'post_type' => IWP_POST_TYPE,
67 'posts_per_page' => -1,
68 ));
69
70 foreach ($query->posts as $post) {
71 $result[] = $this->get_importer($post);
72 }
73 return $result;
74 }
75
76 /**
77 * Get Importer
78 *
79 * @param int $id
80 * @return ImporterModel
81 */
82 public function get_importer($id)
83 {
84 if ($id instanceof ImporterModel) {
85 return $id;
86 }
87
88 if (IWP_POST_TYPE !== get_post_type($id)) {
89 return false;
90 }
91
92 return new ImporterModel($id, $this->is_debug());
93 }
94
95 public function is_debug()
96 {
97
98 if (defined('IWP_DEBUG') && true === IWP_DEBUG) {
99 return true;
100 }
101
102 $uninstall_enabled = get_option('iwp_settings');
103 if (isset($uninstall_enabled['debug']) && true === $uninstall_enabled['debug']) {
104 return true;
105 }
106
107 return false;
108 }
109
110 public function set_current_user($id)
111 {
112 $importer_model = $this->get_importer($id);
113 $user_id = $importer_model->getUserId();
114
115 Logger::write('set_current_user -user=' . $user_id, $importer_model->getId());
116
117 if ($user_id) {
118 return wp_set_current_user($user_id);
119 }
120
121 return false;
122 }
123
124 /**
125 * Delete Importer
126 *
127 * @param int $id
128 * @return void
129 */
130 public function delete_importer($id)
131 {
132 $importer = $this->get_importer($id);
133 $importer->delete();
134 }
135
136 public function get_file($id)
137 {
138 $importer = $this->get_importer($id);
139 $config = $this->get_config($importer);
140 $parser = $importer->getParser();
141
142 if ('xml' === $parser) {
143 return $this->get_xml_file($importer, $config);
144 } elseif ('csv' === $parser) {
145 return $this->get_csv_file($importer, $config);
146 }
147
148 return false;
149 }
150
151 public function get_csv_file($id, $config)
152 {
153 $importer = $this->get_importer($id);
154 $file = new CSVFile($importer->getFile(), $config);
155 $file->setDelimiter($importer->getFileSetting('delimiter'));
156 $file->setEnclosure($importer->getFileSetting('enclosure'));
157 return $file;
158 }
159
160 public function get_xml_file($id, $config)
161 {
162 $importer = $this->get_importer($id);
163 $file = new XMLFile($importer->getFile(), $config);
164 $file->setRecordPath($importer->getFileSetting('base_path'));
165 return $file;
166 }
167
168 public function preview_csv_file($id, $fields = [], $row = 0)
169 {
170 $importer = $this->get_importer($id);
171 $config = $this->get_config($importer, true);
172
173 $file = $this->get_csv_file($importer, $config);
174 $parser = new CSVParser($file);
175
176 $record = $parser->getRecord($row);
177
178 return $record->queryGroup(['fields' => $fields]);
179 }
180
181 public function preview_xml_file($id, $fields = [], $row = 0)
182 {
183 $importer = $this->get_importer($id);
184 $config = $this->get_config($importer, true);
185
186 $file = $this->get_xml_file($importer, $config);
187 $parser = new XMLParser($file);
188
189 $record = $parser->getRecord($row);
190 return $record->queryGroup(['fields' => $fields]);
191 }
192
193 public function process_csv_file($id, $delimiter, $enclosure, $tmp = false)
194 {
195 $importer = $this->get_importer($id);
196 $config = $this->get_config($importer->getId(), $tmp);
197
198 $file = $this->get_csv_file($importer, $config);
199 $file->setDelimiter($delimiter);
200 $file->setEnclosure($enclosure);
201 $file->processing(true);
202
203 if (empty($importer->getMap())) {
204
205 // we are on first file import
206 $headings = str_getcsv($file->getRecord(0), $file->getDelimiter(), $file->getEnclosure());
207 $headings = array_map('trim', $headings);
208
209 $template = $this->get_importer_template($id);
210 $field_map = $template->generate_field_map($headings, $importer);
211 $field_map = apply_filters('iwp/importer/generate_field_map', $field_map, $headings, $importer);
212
213 $map = $field_map['map'];
214 foreach ($map as $key => $value) {
215 $importer->setMap($key, $value);
216 }
217
218 $enabled = $field_map['enabled'];
219 foreach ($enabled as $enabled_field) {
220 $importer->setEnabled($enabled_field);
221 }
222
223 // Disabled due to testing:
224 // https://localdev/wp-admin/tools.php?page=importwp&edit=29&step=1
225 //
226 // a:9:{s:8:"template";s:19:"woocommerce-product";s:13:"template_type";s:0:"";s:4:"file";a:2:{s:2:"id";i:9;s:8:"settings";a:6:{s:9:"enclosure";s:1:""";s:9:"delimiter";s:1:",";s:13:"show_headings";b:1;s:5:"setup";b:0;s:5:"count";i:2;s:9:"processed";b:1;}}s:10:"datasource";a:2:{s:4:"type";s:5:"local";s:8:"settings";a:2:{s:10:"remote_url";s:0:"";s:9:"local_url";s:48:"/var/www/html/wp-content/uploads/exportwp/30.csv";}}s:6:"parser";s:3:"csv";s:3:"map";a:0:{}s:7:"enabled";a:0:{}s:11:"permissions";a:0:{}s:8:"settings";a:4:{s:9:"post_type";a:2:{i:0;s:7:"product";i:1;s:17:"product_variation";}s:12:"unique_field";a:3:{i:0;s:2:"ID";i:1;s:4:"_sku";i:2;s:9:"post_name";}s:9:"start_row";N;s:7:"max_row";N;}}
227 //
228 $importer->save();
229 }
230
231 return $file->getRecordCount();
232 }
233
234 public function process_xml_file($id, $tmp = false)
235 {
236
237 $importer = $this->get_importer($id);
238 $config = $this->get_config($importer->getId(), $tmp);
239
240 $filePath = $importer->getFile();
241 $file = new XMLFile($filePath, $config);
242 $file->processing(true);
243 $nodes = $file->get_node_list();
244 $results = [];
245
246 foreach ($nodes as $node) {
247 $config = $this->get_config($importer->getId(), $tmp);
248 $file = new XMLFile($filePath, $config);
249 $file->setRecordPath($node);
250 // TODO: Seperate record count, to when a node has been selected.
251 $results[$node] = 0; //$file->getRecordCount();
252 }
253
254 return $results;
255 }
256
257 /**
258 * Link import file to importer via post meta
259 *
260 * @param ImporterModel $id
261 * @param string $file_path
262 * @return integer Id of inserted file
263 */
264 public function link_importer_file($id, $file_path)
265 {
266 $importer = $this->get_importer($id);
267 $index = get_post_meta($importer->getId(), '_importer_files', true);
268 if (!$index) {
269 $index = 1;
270 }
271
272 $index++;
273
274 update_post_meta($importer->getId(), '_importer_files', $index);
275 update_post_meta($importer->getId(), '_importer_file_' . $index, $file_path);
276 return $index;
277 }
278
279 public function get_importer_file_prefix($importer)
280 {
281 $importer = $this->get_importer($importer);
282
283 $file_index = get_post_meta($importer->getId(), '_importer_files', true);
284 if (!$file_index) {
285 $file_index = 1;
286 }
287 $file_index++;
288
289 return $importer->getId() . '-' . intval($file_index) . '-';
290 }
291
292 public function upload_file($id, $file)
293 {
294 $importer = $this->get_importer($id);
295 Logger::setId($importer->getId());
296
297 $allowed_file_types = $this->event_handler->run('importer.allowed_file_types', [$importer->getAllowedFileTypes()]);
298 $result = $this->filesystem->upload_file($file, $allowed_file_types);
299
300 if (is_wp_error($result)) {
301 return $result;
302 }
303
304 $attachment_id = $this->insert_file_attachment($importer, $result['dest'], $result['type']);
305 if (is_wp_error($attachment_id)) {
306 return $attachment_id;
307 }
308
309 return $attachment_id;
310 }
311
312 public function remote_file($id, $source, $filetype = null)
313 {
314 $importer = $this->get_importer($id);
315 Logger::setId($importer->getId());
316
317 $allowed_file_types = $this->event_handler->run('importer.allowed_file_types', [$importer->getAllowedFileTypes()]);
318 $prefix = $this->get_importer_file_prefix($importer);
319 $result = $this->filesystem->download_file($source, $filetype, $allowed_file_types, null, $prefix);
320
321 if (is_wp_error($result)) {
322 return $result;
323 }
324
325 $attachment_id = $this->insert_file_attachment($importer, $result['dest'], $result['type']);
326 if (is_wp_error($attachment_id)) {
327 return $attachment_id;
328 }
329
330 return $attachment_id;
331 }
332
333 public function local_file($id, $source)
334 {
335 $importer = $this->get_importer($id);
336 Logger::setId($importer->getId());
337
338 $allowed_file_types = $this->event_handler->run('importer.allowed_file_types', [$importer->getAllowedFileTypes()]);
339 $prefix = $this->get_importer_file_prefix($importer);
340 $result = $this->filesystem->copy_file($source, $allowed_file_types, null, $prefix);
341
342 if (is_wp_error($result)) {
343 return $result;
344 }
345
346 $attachment_id = $this->insert_file_attachment($importer, $result['dest'], $result['type']);
347 if (is_wp_error($attachment_id)) {
348 return $attachment_id;
349 }
350
351 return $attachment_id;
352 }
353
354 /**
355 * Add uploaded file to importer
356 *
357 * Insert file record in database, set as current import file.
358 *
359 * @param integer|ImporterModel $id Importer to attach file
360 * @param string $file_path File location on server
361 * @param string $file_type Type of file
362 *
363 * @return \WP_Error|int Id of file
364 */
365 private function insert_file_attachment($id, $file_path, $file_type)
366 {
367 $importer_model = $this->get_importer($id);
368 Logger::setId($importer_model->getId());
369
370 // Allow the modification of file path
371 $file_path = wp_normalize_path($file_path);
372 $file_path = apply_filters('iwp/importer/file_uploaded/file_path', $file_path, $importer_model);
373
374 $file_id = $this->link_importer_file($id, $file_path);
375 if (!$file_id) {
376 return new \WP_Error('IWP_IM_01', 'Unable to link importer file');
377 }
378
379 if (is_null($importer_model->getParser())) {
380 $importer_model->setParser($file_type);
381 }
382
383 $importer_model->setFileId($file_id);
384 $importer_model->save();
385
386 do_action('iwp/importer/file_uploaded', $file_path, $importer_model);
387
388 return $file_id;
389 }
390
391 /**
392 * Clear config files
393 *
394 * @param int $id
395 * @return void
396 */
397 public function clear_config_files($id, $tmp = false, $all = true)
398 {
399 $config_path = $this->get_config_path($id, $tmp);
400 if (file_exists($config_path)) {
401
402 unlink($config_path);
403 if (true === $all) {
404 foreach (glob($config_path . '*') as $file) {
405
406 // don't remove status file
407 if (basename($file) === basename($config_path) . '.status') {
408 continue;
409 }
410
411 unlink($file);
412 }
413 }
414 }
415 }
416
417 public function get_config($importer, $tmp = false)
418 {
419 $config_path = $this->get_config_path($importer, $tmp);
420 $config = new Config($config_path);
421
422
423 $importer = $this->get_importer($importer);
424 $file_encoding = $importer->getFileSetting('file_encoding');
425
426 // file encoding
427 $config->set('file_encoding', apply_filters('iwp/importer/file_encoding', $file_encoding, $importer));
428
429 return $config;
430 }
431
432 public function get_session_path($id, $session, $max_depth = 4)
433 {
434 $base = $this->filesystem->get_temp_directory() . DIRECTORY_SEPARATOR;
435
436 $base .= str_pad($id, 2, STR_PAD_LEFT) . DIRECTORY_SEPARATOR;
437 if (!file_exists($base)) {
438 if (!is_writable(dirname($base)) || !mkdir($base)) {
439 throw new \Exception("Unable to create directory: " . $base);
440 }
441 }
442
443 for ($i = 0; $i < ceil(strlen($session) / 2); $i++) {
444 $base .= substr($session, $i * 2, 2) . DIRECTORY_SEPARATOR;
445 if (!file_exists($base)) {
446
447 if (!is_writable(dirname($base)) || !mkdir($base)) {
448 throw new \Exception("Unable to create directory: " . $base);
449 }
450 }
451
452 if ($i >= $max_depth - 2) {
453 break;
454 }
455 }
456 return $base;
457 }
458
459 public function get_config_path($id, $tmp = false, $session_id = null)
460 {
461 $importer = $this->get_importer($id);
462
463 $key = 'config-%d.json';
464 if ($tmp) {
465 $key = 'temp-config-%d.json';
466 }
467
468 $base = !is_null($session_id) ? $this->get_session_path($id, $session_id) : $this->filesystem->get_temp_directory() . DIRECTORY_SEPARATOR;
469
470 return $base . sprintf($key, $importer->getId());
471 }
472
473 public function import($id, $user, $session = null)
474 {
475 Logger::timer();
476
477 $importer_data = $this->get_importer($id);
478 $importer_id = $importer_data->getId();
479
480 $config_data = get_site_option('iwp_importer_config_' . $importer_id, []);
481
482 $this->event_handler->run('importer_manager.import', [$importer_data]);
483
484 $state = new ImporterState($importer_id, $user);
485
486 try {
487
488 Logger::debug('IM -init_state');
489 $state->init($session);
490
491 if ($state->has_status('init')) {
492 Logger::debug('IM -clear_config_files');
493 $this->clear_config_files($importer_id, false, true);
494 $config_data['features'] = [
495 'session_table' => true
496 ];
497 }
498
499 Logger::debug('IM -get_config');
500 $config = $this->get_config($importer_data);
501
502 // template
503 Logger::debug('IM -get_importer_template');
504 $template = $this->get_importer_template($importer_data);
505
506 Logger::debug('IM -register_hooks');
507 $template->register_hooks($importer_data);
508
509 // permission
510 Logger::debug('IM -permissions');
511 $permission = new Permission($importer_data);
512
513 // mapper
514 Logger::debug('IM -get_importer_mapper');
515 $mapper = $this->get_importer_mapper($importer_data, $template, $permission);
516
517 if ($state->has_status('init')) {
518
519 Logger::debug('IM -generate_config');
520
521 $config_data['data'] = $template->config_field_map($importer_data->getMap());
522 $config->set('data', $config_data['data']);
523
524 $config_data['id'] = $state->get_session();
525
526 // This is used for storing version on imported records
527 update_post_meta($importer_id, '_iwp_session', $config_data['id']);
528
529 // Increase Version
530 $version = get_post_meta($importer_id, '_iwp_version', true);
531 if ($version !== false) {
532 $version++;
533 } else {
534 $version = 0;
535 }
536 update_post_meta($importer_id, '_iwp_version', $version);
537 $config_data['version'] = $version;
538 }
539
540 $start = 0;
541
542 // get parser
543 if ($importer_data->getParser() === 'csv') {
544 Logger::debug('IM -get_csv_file');
545 $file = $this->get_csv_file($importer_data, $config);
546 Logger::debug('IM -load_parser');
547 $parser = new CSVParser($file);
548 if (true === $importer_data->getFileSetting('show_headings')) {
549 $start = 1;
550 }
551 } elseif ($importer_data->getParser() === 'xml') {
552 Logger::debug('IM -get_xml_file');
553 $file = $this->get_xml_file($importer_data, $config);
554 Logger::debug('IM -load_parser');
555 $parser = new XMLParser($file);
556 } else {
557 $parser = apply_filters('iwp/importer/init_parser', false, $importer_data, $config);
558 }
559
560 if ($state->has_status('init')) {
561
562 Logger::debug('IM -get_record_count');
563 $end = $parser->file()->getRecordCount();
564
565 $config_data['start'] = $this->get_start($importer_data, $start);
566 $config_data['end'] = $this->get_end($importer_data, $config_data['start'], $end);
567
568 update_site_option('iwp_importer_config_' . $importer_id, $config_data);
569
570 Logger::debug('IM -update_state');
571 $state->update(function ($state) use ($config_data) {
572
573 Logger::debug('IM -update_state=running');
574
575 $state['id'] = $config_data['id'];
576 $state['status'] = 'running';
577 $state['progress']['import']['start'] = $config_data['start'];
578 $state['progress']['import']['end'] = $config_data['end'];
579 return $state;
580 });
581
582 Logger::debug('IM -write_status_session_to_file');
583 Util::write_status_session_to_file($id, $state);
584
585 do_action('iwp/importer/init', $importer_data);
586 }
587
588 Logger::debug('IM -import');
589 $importer = new \ImportWP\Common\Importer\Importer($config);
590 $importer->parser($parser);
591 $importer->mapper($mapper);
592 $importer->from($config_data['start']);
593 $importer->to($config_data['end']);
594 $importer->filter($importer_data->getFilters());
595 $importer->import($importer_id, $user, $state);
596 Logger::debug('IM -import_complete');
597 } catch (\Exception $e) {
598
599 // TODO: Missing template errors are currently not being logged to history, possibly others?
600 Logger::error('import -error=' . $e->getMessage(), $importer_id);
601 return $state->error($e)->get_raw();
602 }
603
604 /**
605 * @var Properties $properties
606 */
607 $properties = Container::getInstance()->get('properties');
608
609 // rotate files to not fill up server
610 $importer_data->limit_importer_files($properties->file_rotation);
611 $this->prune_importer_logs($importer_data, $properties->log_rotation);
612
613 $template->unregister_hooks();
614
615 $this->event_handler->run('importer_manager.import_shutdown', [$importer_data]);
616
617 return $state->update(function ($data) {
618 $data['duration'] = floatval($data['duration']) + Logger::timer();
619 return $data;
620 })->get_raw();
621 }
622
623 public function get_start($importer_data, $start)
624 {
625 $tmp_start = $importer_data->getStartRow();
626 if (!is_null($tmp_start) && "" !== $tmp_start) {
627 $tmp_start = intval($tmp_start);
628
629 if ($tmp_start > $start) {
630 $start = $tmp_start;
631 }
632 }
633
634 return $start;
635 }
636
637 public function get_end($importer_data, $start, $end)
638 {
639 $tmp_max_row = $importer_data->getMaxRow();
640 if (!is_null($tmp_max_row) && $tmp_max_row !== '') {
641 $tmp_end = $start + intval($tmp_max_row);
642 if ($tmp_end < $end) {
643 $end = $tmp_end;
644 }
645 }
646
647 return $end;
648 }
649
650 public function get_importer_template($id)
651 {
652 $importer_model = $this->get_importer($id);
653 $templates = $this->get_templates();
654 $template_name = $importer_model->getTemplate();
655
656 if (!isset($templates[$template_name])) {
657 $exception_msg = "Unable to locate importer template: " . $template_name;
658 Logger::error('import -get_importer_template=' . $exception_msg, $importer_model->getId());
659 throw new \Exception($exception_msg);
660 }
661
662 return $this->template_manager->load_template($templates[$template_name]);
663 }
664
665 /**
666 * Get importer mapper
667 *
668 * @param int $id
669 * @param Template $template
670 * @param Permission $permission
671 * @return MapperInterface
672 */
673 public function get_importer_mapper($id, $template, $permission = null)
674 {
675 $importer = $this->get_importer($id);
676 $mapper_name = $template->get_mapper();
677
678 $mappers = $this->get_mappers();
679 return isset($mappers[$mapper_name]) ? new $mappers[$mapper_name]($importer, $template, $permission) : false;
680 }
681
682 public function get_mappers()
683 {
684 $mappers = $this->event_handler->run('mappers.register', [[]]); // apply_filters('iwp/mappers/register', []);
685 $mappers = array_merge($mappers, [
686 'post' => PostMapper::class,
687 'user' => UserMapper::class,
688 'term' => TermMapper::class
689 ]);
690 return $mappers;
691 }
692
693 public function get_mapper($key)
694 {
695 $mappers = $this->get_mappers();
696 if (!isset($mappers[$key])) {
697 return new \WP_Error('IWP_IM_1', 'Unable to locate mapper: ' . $key);
698 }
699
700 return $mappers[$key];
701 }
702
703 public function get_templates()
704 {
705 $templates = $this->event_handler->run('templates.register', [[]]);
706 $templates = array_merge($templates, [
707 'post' => PostTemplate::class,
708 'page' => PageTemplate::class,
709 'user' => UserTemplate::class,
710 'term' => TermTemplate::class,
711 'custom-post-type' => CustomPostTypeTemplate::class,
712 ]);
713 return $templates;
714 }
715
716 public function get_template($key)
717 {
718 $templates = $this->get_templates();
719 if (!isset($templates[$key])) {
720 return new \WP_Error('IWP_IM_1', 'Unable to locate template: ' . $key);
721 }
722
723 return $templates[$key];
724 }
725
726 public function get_importer_debug_log(ImporterModel $importer_data, $page = 0, $per_page = -1)
727 {
728 $file_path = Logger::getLogFile($importer_data->getId());
729
730 $line_counter = 0;
731 $lines = [];
732 $start = $end = -1;
733
734 if ($per_page > 0) {
735 $start = ($page - 1) * $per_page;
736 $end = $start + $per_page;
737 }
738
739 if (file_exists($file_path)) {
740 $fh = fopen($file_path, 'r');
741 if ($fh !== false) {
742 while (($data = fgetcsv($fh)) !== false) {
743 if ($line_counter === $end) {
744 return $lines;
745 } elseif ($per_page === -1 || $line_counter >= $start) {
746 $lines[] = $data;
747 }
748
749 $line_counter++;
750 }
751 fclose($fh);
752 }
753 }
754 return $lines;
755 }
756
757 public function prune_importer_logs($importer_model, $limit)
758 {
759 $limit = intval($limit);
760 if ($limit <= -1) {
761 return;
762 }
763
764 $file_path = Util::get_importer_status_file_path($importer_model->getId());
765 $tmp_file_path = Util::get_importer_status_file_path($importer_model->getId()) . '.tmp';
766 $lines = $this->get_importer_logs($importer_model);
767
768 if (count($lines) > $limit) {
769
770 require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
771 require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php');
772 $fileSystemDirect = new \WP_Filesystem_Direct(false);
773
774 $fh = fopen($tmp_file_path, 'w');
775 for ($i = 0; $i < count($lines); $i++) {
776
777 if ($i < count($lines) - $limit) {
778 $log_file_path = Util::get_importer_log_file_path($importer_model->getId(), $lines[$i]['id']);
779 if ($fileSystemDirect->exists($log_file_path)) {
780
781 $fileSystemDirect->delete($log_file_path);
782
783 $tmp = $log_file_path;
784 for ($j = 0; $j < 3; $j++) {
785 $tmp = dirname($tmp);
786 $sub_files = $fileSystemDirect->dirlist($log_file_path);
787 if (empty($sub_files)) {
788 $fileSystemDirect->rmdir($tmp);
789 }
790 }
791 }
792 } else {
793 fputs($fh, json_encode($lines[$i]) . "\n");
794 }
795 }
796 fclose($fh);
797
798 if ($fileSystemDirect->move($tmp_file_path, $file_path, true)) {
799 $fileSystemDirect->delete($tmp_file_path);
800 }
801 }
802 }
803
804 public function get_importer_logs(ImporterModel $importer_data, $page = 0, $per_page = -1)
805 {
806 $file_path = Util::get_importer_status_file_path($importer_data->getId());
807
808 $line_counter = 0;
809 $lines = [];
810
811 $start = $end = -1;
812
813 if ($per_page > 0) {
814 $start = ($page - 1) * $per_page;
815 $end = $start + $per_page;
816 }
817
818 if (file_exists($file_path)) {
819 $fh = fopen($file_path, 'r');
820 if ($fh !== false) {
821 while (($data = fgets($fh)) !== false) {
822 if ($data[strlen($data) - 1] === "\n") {
823 $data = substr($data, 0, strlen($data) - 1);
824 }
825
826 if ($line_counter === $end) {
827 return $lines;
828 } elseif ($per_page === -1 || $line_counter >= $start) {
829 $lines[] = json_decode($data, true);
830 }
831
832 $line_counter++;
833 }
834 fclose($fh);
835 }
836 }
837 return $lines;
838 }
839
840 public function get_importer_log(ImporterModel $importer_data, $session_id, $page = 0, $per_page = -1)
841 {
842 $file_path = Util::get_importer_log_file_path($importer_data->getId(), $session_id);
843
844 $line_counter = 0;
845 $lines = [];
846 $start = $end = -1;
847
848 if ($per_page > 0) {
849 $start = ($page - 1) * $per_page;
850 $end = $start + $per_page;
851 }
852
853 if (file_exists($file_path)) {
854 $fh = fopen($file_path, 'r');
855 if ($fh !== false) {
856 while (($data = fgetcsv($fh)) !== false) {
857 if ($line_counter === $end) {
858 return $lines;
859 } elseif ($per_page === -1 || $line_counter >= $start) {
860 $lines[] = $data;
861 }
862
863 $line_counter++;
864 }
865 fclose($fh);
866 }
867 }
868 return $lines;
869 }
870
871 public function get_importer_status_report(ImporterModel $immpoter_data, $session)
872 {
873 $logs = $this->get_importer_logs($immpoter_data);
874 foreach ($logs as $log) {
875 if ($log && isset($log['id']) && $log['id'] === $session) {
876 return $log;
877 }
878 }
879 return false;
880 }
881 }
882