PluginProbe
Import WP – CSV & XML Import Export for WordPress / 2.15.0
Import WP – CSV & XML Import Export for WordPress v2.15.0
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 / Model / ImporterModel.php

ImporterModel.php in Import WP – CSV & XML Import Export for WordPress 2.15.0, at class/Common/Model/ImporterModel.php

744 lines 20.0 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\Model;
4
5 use ImportWP\Common\Filesystem\Filesystem;
6 use ImportWP\Common\Util\Logger;
7
8 class ImporterModel
9 {
10 /**
11 * @var int $id
12 */
13 protected $id;
14
15 /**
16 * @var int $user_id
17 */
18 protected $user_id;
19
20 /**
21 * @var string $name
22 */
23 protected $name;
24
25 /**
26 * @var string $template
27 */
28 protected $template;
29
30 /**
31 * @var string $template_type
32 */
33 protected $template_type;
34
35 /**
36 * @var string $parser
37 */
38 protected $parser;
39
40 /**
41 * @var string $mapper
42 */
43 protected $mapper;
44
45 /**
46 * @var string $datasource
47 */
48 protected $datasource;
49
50 /**
51 * @var array $datasource_settings
52 */
53 protected $datasource_settings;
54
55 /**
56 * @var string $file
57 */
58 protected $file;
59
60 /**
61 * @var int $file_id
62 */
63 protected $file_id;
64
65 /**
66 * @var array $file_settings
67 */
68 protected $file_settings;
69
70 /**
71 * @var array $map
72 */
73 protected $map;
74
75 /**
76 * @var array $enabled
77 */
78 protected $enabled;
79
80 /**
81 * @var array $permissions
82 */
83 protected $permissions;
84
85 /**
86 * @var int $max_row
87 */
88 protected $max_row;
89
90 /**
91 * @var int $start_row
92 */
93 protected $start_row;
94
95 /**
96 * Importer general settings
97 *
98 * @var array
99 */
100 protected $settings = [];
101
102 /**
103 * @var int
104 */
105 protected $version;
106 protected $version_latest = 2;
107
108 /**
109 * @var bool
110 */
111 protected $debug;
112
113 public function __construct($data = null, $debug = false)
114 {
115 $this->debug = $debug;
116 $this->setup_data($data);
117 }
118
119 private function setup_data($data)
120 {
121
122 if (is_array($data)) {
123
124 // fetch data from array
125 $this->id = isset($data['id']) && intval($data['id']) > 0 ? intval($data['id']) : null;
126 $this->name = $data['name'];
127 $this->template = isset($data['template']) ? $data['template'] : null;
128 $this->template_type = isset($data['template_type']) ? $data['template_type'] : null;
129 $this->parser = isset($data['parser']) ? $data['parser'] : null;
130 $this->mapper = isset($data['mapper']) ? $data['mapper'] : null;
131 $this->map = isset($data['map']) ? $data['map'] : null;
132 $this->enabled = isset($data['enabled']) ? $data['enabled'] : null;
133 $this->file_id = isset($data['file'], $data['file']['id']) ? $data['file']['id'] : null;
134 if ($this->file_id) {
135 $this->file = $this->get_attached_file($this->file_id);
136 }
137 $this->file_settings = array_merge($this->getDetaultFileSettings(), isset($data['file'], $data['file']['settings']) ? $data['file']['settings'] : array());
138 $this->datasource = isset($data['datasource'], $data['datasource']['type']) ? $data['datasource']['type'] : null;
139 $this->datasource_settings = isset($data['datasource'], $data['datasource']['settings']) ? $data['datasource']['settings'] : null;
140 $this->permissions = isset($data['permissions']) ? $data['permissions'] : null;
141 $this->start_row = isset($data['settings'], $data['settings']['start_row']) ? $data['settings']['start_row'] : null;
142 $this->max_row = isset($data['settings'], $data['settings']['max_row']) ? $data['settings']['max_row'] : null;
143 $this->settings = isset($data['settings']) ? $data['settings'] : [];
144 $this->version = isset($data['version']) ? $data['version'] : 0;
145 } elseif (!is_null($data)) {
146
147 $post = false;
148
149 if ($data instanceof \WP_Post) {
150
151 // fetch data from post
152 $post = $data;
153 } elseif (intval($data) > 0) {
154
155 // fetch data from id
156 $this->id = intval($data);
157 $post = get_post($this->id);
158 }
159
160 if ($post && $post->post_type === IWP_POST_TYPE) {
161
162 // Fix broken importer issue.
163 $json = maybe_unserialize($post->post_content, true);
164 if (!is_array($json)) {
165 $json = [];
166 }
167
168 $this->id = $post->ID;
169 $this->name = $post->post_title;
170 $this->user_id = $post->post_author;
171
172 $this->template = isset($json['template']) ? $json['template'] : null;
173 $this->template_type = isset($json['template_type']) ? $json['template_type'] : null;
174 $this->parser = isset($json['parser']) ? $json['parser'] : null;
175 $this->mapper = isset($json['mapper']) ? $json['mapper'] : null;
176 $this->map = isset($json['map']) ? $json['map'] : [];
177 $this->enabled = isset($json['enabled']) ? $json['enabled'] : [];
178 $this->file_id = isset($json['file'], $json['file']['id']) ? intval($json['file']['id']) : 0;
179 if ($this->file_id > 0) {
180 $this->file = $this->get_attached_file($this->file_id);
181 }
182
183 if (!isset($json['file']['settings']) || !is_array($json['file']['settings'])) {
184 $json['file']['settings'] = [];
185 }
186
187 $this->file_settings = array_merge($this->getDetaultFileSettings(), $json['file']['settings']);
188
189 $this->datasource = isset($json['datasource'], $json['datasource']['type']) ? $json['datasource']['type'] : null;
190 $this->datasource_settings = isset($json['datasource'], $json['datasource']['settings']) ? $json['datasource']['settings'] : [];
191
192 $this->permissions = isset($json['permissions']) ? $json['permissions'] : [];
193
194 $this->start_row = isset($json['settings'], $json['settings']['start_row']) ? $json['settings']['start_row'] : null;
195 $this->max_row = isset($json['settings'], $json['settings']['max_row']) ? $json['settings']['max_row'] : null;
196 $this->settings = isset($json['settings']) ? $json['settings'] : [];
197 $this->version = isset($json['version']) ? $json['version'] : 0;
198 }
199 }
200
201 Logger::setId($this->getId());
202 }
203
204 public function data($view = 'public')
205 {
206 $files = $this->getFiles();
207 $file = $this->getFile();
208 if ($view === 'public' && false === $this->debug) {
209
210 if ($file) {
211 $file = basename($file);
212 }
213
214 foreach ($files as &$tmp_file) {
215 $tmp_file = basename($tmp_file) . ' - (Added: ' . date(get_option('date_format') . ' \a\t ' . get_option('time_format'), filemtime($tmp_file)) . ')';
216 }
217 } else {
218 foreach ($files as &$tmp_file) {
219
220 $tmp_file .= ' - (Added: ' . date(get_option('date_format') . ' \a\t ' . get_option('time_format'), filemtime($tmp_file)) . ')';
221 }
222 }
223
224 $file_data = [
225 'id' => $this->getFileId(),
226 'src' => $file,
227 'settings' => $this->file_settings
228 ];
229
230 $datasource_data = [
231 'type' => $this->getDatasource(),
232 'settings' => (object) $this->getDatasourceSettings()
233 ];
234
235 $settings = array_merge($this->settings, [
236 'start_row' => $this->start_row,
237 'max_row' => $this->max_row,
238 ]);
239
240 $result = array(
241 'id' => $this->id,
242 'name' => $this->getName(),
243 'template' => $this->template,
244 'template_type' => $this->template_type,
245 'parser' => $this->getParser(),
246 'cron' => [],
247 'file' => $file_data,
248 'files' => (object) $files,
249 'datasource' => $datasource_data,
250 'map' => (object) $this->map,
251 'enabled' => (object) $this->enabled,
252 'permissions' => (object) $this->getPermissions(),
253 'settings' => (object) $settings,
254 'version' => $this->version,
255 );
256
257 if (true === $this->debug) {
258 global $wpdb;
259 $content = $wpdb->get_var($wpdb->prepare("SELECT post_content from {$wpdb->posts} WHERE post_type='%s' AND ID=%d", IWP_POST_TYPE, $this->getId()));
260 $result['debug'] = [
261 'settings' => base64_encode($content),
262 // 'log' => file_get_contents(Logger::getLogFile($this->getId()))
263 ];
264 }
265
266 return $result;
267 }
268
269 public function save()
270 {
271 // Match what happens in wp-rest.
272 remove_filter('content_save_pre', 'wp_filter_post_kses');
273
274 $settings = array_merge($this->settings, [
275 'start_row' => $this->start_row,
276 'max_row' => $this->max_row,
277 ]);
278
279 $post_content = array(
280 'template' => $this->template,
281 'template_type' => $this->template_type,
282 'file' => [
283 'id' => $this->file_id,
284 'settings' => $this->file_settings
285 ],
286 'datasource' => [
287 'type' => $this->datasource,
288 'settings' => $this->getDatasourceSettings()
289 ],
290 'parser' => $this->parser,
291 'map' => $this->map,
292 'enabled' => $this->enabled,
293 'permissions' => $this->permissions,
294 'settings' => $settings,
295 'version' => $this->version
296 );
297
298 if (is_null($this->id)) {
299
300 if ($this->template === 'jet-engine-cct') {
301
302 // do not force the new permissions interface.
303
304 } else {
305
306 // set defaults on new importers
307 $post_content['version'] = $this->version_latest;
308 $post_content['settings']['unique_identifier_type'] = 'field';
309 }
310 }
311
312 $postarr = array(
313 'post_title' => $this->name,
314 'post_content' => wp_slash(serialize($post_content)),
315 );
316
317 if (is_null($this->id)) {
318 $postarr['post_type'] = IWP_POST_TYPE;
319 $postarr['post_status'] = 'publish';
320
321 $result = wp_insert_post($postarr, true);
322 } else {
323 $postarr['ID'] = $this->id;
324 $result = wp_update_post($postarr, true);
325 }
326
327 // Match what happens in wp-rest.
328 add_filter('content_save_pre', 'wp_filter_post_kses');
329
330
331 if (!is_wp_error($result)) {
332 $this->setup_data($result);
333 }
334
335 return $result;
336 }
337
338 public function delete()
339 {
340 if (get_post_type($this->getId()) === IWP_POST_TYPE) {
341 wp_delete_post($this->getId(), true);
342 }
343 }
344
345 public function getAllowedFileTypes()
346 {
347
348 $parser = $this->getParser();
349 $allowed_file_types = apply_filters('iwp/importer/datasource/allowed_file_types', ['xml', 'csv', 'json'], $this);
350
351 if (!is_null($parser)) {
352 $allowed_file_types = [$parser];
353 }
354
355 return $allowed_file_types;
356 }
357
358 public function setDatasource($datasource)
359 {
360 $this->datasource = $datasource;
361 }
362
363 public function setDatasourceSetting($key, $value)
364 {
365 $this->datasource_settings[$key] = $value;
366 }
367
368 public function getSetting($key)
369 {
370 return isset($this->settings[$key]) ? $this->settings[$key] : null;
371 }
372
373 public function setSetting($key, $value)
374 {
375 $this->settings[$key] = $value;
376 }
377
378 public function setFileId($file_id)
379 {
380 $this->file_id = $file_id;
381 $this->file = $this->get_attached_file($this->file_id);
382
383 if (is_null($this->file_settings)) {
384 $this->file_settings = $this->getDetaultFileSettings();
385 }
386 }
387
388 public function getDetaultFileSettings()
389 {
390 switch ($this->getParser()) {
391 case 'xml':
392 return [
393 'base_path' => null,
394 'setup' => false
395 ];
396 break;
397 case 'json':
398 return [
399 'base_path' => null,
400 'setup' => false
401 ];
402 break;
403 case 'csv':
404 return [
405 'enclosure' => '"',
406 'delimiter' => ',',
407 'escape' => '\\',
408 'show_headings' => true,
409 'setup' => false
410 ];
411 break;
412 }
413
414 return [];
415 }
416
417 public function setFile($file_id, $settings)
418 {
419 $this->file_id = $file_id;
420 $this->file = $this->get_attached_file($this->file_id);
421 $this->file_settings = array_merge($this->getDetaultFileSettings(), $settings);
422 }
423
424 public function setMaxRow($max)
425 {
426 $this->max_row = $max;
427 }
428
429 public function setStartRow($start)
430 {
431 $this->start_row = $start;
432 }
433
434 public function setName($name)
435 {
436 $this->name = $name;
437 }
438
439 public function setParser($parser)
440 {
441 $this->parser = $parser;
442 }
443
444 public function setTemplate($template, $template_type = '')
445 {
446 $this->template = $template;
447 $this->template_type = $template_type;
448 }
449
450 public function getDatasource()
451 {
452 return $this->datasource;
453 }
454
455 public function getDatasourceSettings()
456 {
457 return $this->datasource_settings;
458 }
459
460 public function getDatasourceSetting($key)
461 {
462 return isset($this->datasource_settings[$key]) ? $this->datasource_settings[$key] : null;
463 }
464
465 public function getFile()
466 {
467 return $this->file;
468 }
469
470 public function getFileId()
471 {
472 return $this->file_id;
473 }
474
475 public function getFiles()
476 {
477 $files = [];
478
479 if (!$this->getId()) {
480 return $files;
481 }
482
483 global $wpdb;
484 $query = "SELECT meta_key, meta_value
485 FROM {$wpdb->postmeta}
486 WHERE post_id={$this->getId()} AND meta_key
487 LIKE '\_importer\_file\_%'";
488
489 $results = $wpdb->get_results($query, ARRAY_A);
490
491 foreach ($results as $result) {
492 $key = $result['meta_key'];
493 $id = intval(str_replace('_importer_file_', '', $key));
494 $value = $result['meta_value'];
495 $resolved = Filesystem::resolve_importer_file_path($value);
496 if (!$resolved) {
497 continue;
498 }
499
500 $files[$id] = $resolved;
501
502 // Soft-migrate legacy absolute paths to uploads-relative storage.
503 $relative = Filesystem::to_uploads_relative_path($resolved);
504 if ($relative !== '' && $relative !== $value) {
505 update_post_meta($this->getId(), $key, $relative);
506 }
507 }
508
509 return $files;
510 }
511
512 public function get_attached_file($post_id)
513 {
514 $files = $this->getFiles();
515 return isset($files[$post_id]) ? $files[$post_id] : false;
516 }
517
518 /**
519 * Set the limit of importer files
520 *
521 * @param integer $limit The number of files to keep, 0 to keep all files.
522 * @return void
523 */
524 public function limit_importer_files($limit = 0)
525 {
526
527 $limit = intval($limit);
528 if ($limit <= -1) {
529 return;
530 }
531
532 $files = $this->getFiles();
533 if (empty($files) || count($files) <= $limit) {
534 return;
535 }
536
537 ksort($files);
538
539 $file_ids = array_keys($files);
540
541 for ($i = 0; $i < count($files) - $limit; $i++) {
542
543 $id = $file_ids[$i];
544 $path = $files[$id];
545
546 if ($id === $this->getFileId()) {
547 continue;
548 }
549
550 if (!file_exists($path) || unlink($path)) {
551 global $wpdb;
552 $query = "DELETE FROM {$wpdb->postmeta} WHERE post_id={$this->getId()} AND meta_key = '_importer_file_{$id}'";
553 $result = $wpdb->query($query);
554 }
555 }
556 }
557
558 public function getId()
559 {
560 return $this->id;
561 }
562
563 public function getMaxRow()
564 {
565 return $this->max_row;
566 }
567
568 public function getStartRow()
569 {
570 return $this->start_row;
571 }
572
573 public function getName()
574 {
575 return $this->name;
576 }
577
578 public function getParser()
579 {
580 return $this->parser;
581 }
582
583 public function getStatus()
584 {
585 clean_post_cache($this->id);
586 $post = get_post($this->id);
587 return (array) maybe_unserialize($post->post_excerpt);
588 }
589
590 public function getStatusId()
591 {
592 return get_post_meta($this->getId(), '_iwp_session', true);
593 }
594
595 public function getTemplate()
596 {
597 return $this->template;
598 }
599
600 public function getFileSettings()
601 {
602 return $this->file_settings;
603 }
604
605 public function getFileSetting($key, $default = null)
606 {
607 return isset($this->file_settings[$key]) ? $this->file_settings[$key] : $default;
608 }
609
610 public function setFileSetting($key, $value)
611 {
612 $this->file_settings[$key] = $value;
613 }
614
615 public function getMap()
616 {
617 return $this->map;
618 }
619
620 public function setMap($key, $value)
621 {
622 $this->map[$key] = $value;
623 }
624
625 /**
626 * Replace the entire field map (skips null values from deleted repeater rows).
627 *
628 * @param array $map
629 */
630 public function replaceMap($map)
631 {
632 $this->map = [];
633 if (!is_array($map)) {
634 return;
635 }
636
637 foreach ($map as $key => $value) {
638 if ($value === null) {
639 continue;
640 }
641 $this->map[$key] = $value;
642 }
643 }
644
645 public function getEnabled()
646 {
647 return $this->enabled;
648 }
649
650 public function setEnabled($key, $value = true)
651 {
652 if ($value === true) {
653 $this->enabled[$key] = $value;
654 } elseif (isset($this->enabled[$key])) {
655 unset($this->enabled[$key]);
656 }
657 }
658
659 public function isEnabledField($key)
660 {
661 return isset($this->enabled[$key]) && $this->enabled[$key] === true ? true : false;
662 }
663
664 public function getPermission($key)
665 {
666 return isset($this->permissions[$key]) ? $this->permissions[$key] : false;
667 }
668
669 public function getPermissions()
670 {
671 return $this->permissions;
672 }
673
674 public function setPermission($key, $settings)
675 {
676 $this->permissions[$key] = $settings;
677 }
678
679 public function getFilters()
680 {
681 $output = [];
682 $filter_data = $this->getSetting('filters');
683 if (!is_array($filter_data)) {
684 return $output;
685 }
686
687 $max_groups = isset($filter_data['filters._index']) ? intval($filter_data['filters._index']) : 0;
688 if ($max_groups <= 0) {
689 return $output;
690 }
691
692 for ($i = 0; $i < $max_groups; $i++) {
693 $group_data = [];
694 $max_rows = isset($filter_data["filters.{$i}._index"]) ? intval($filter_data["filters.{$i}._index"]) : 0;
695 if ($max_groups <= 0) {
696 continue;
697 }
698
699 for ($j = 0; $j < $max_rows; $j++) {
700
701 $group_data[] = [
702 'left' => isset($filter_data["filters.{$i}.{$j}.left"]) ? $filter_data["filters.{$i}.{$j}.left"] : "",
703 'condition' => isset($filter_data["filters.{$i}.{$j}.condition"]) ? $filter_data["filters.{$i}.{$j}.condition"] : "equal",
704 'right' => isset($filter_data["filters.{$i}.{$j}.right"]) ? $filter_data["filters.{$i}.{$j}.right"] : "",
705 ];
706 }
707
708 $output[] = $group_data;
709 }
710
711 return $output;
712 }
713
714 public function getUserId()
715 {
716 return intval($this->user_id) > 0 ? intval($this->user_id) : false;
717 }
718
719 public function getVersion()
720 {
721 return $this->version;
722 }
723
724 public function get_iwp_reference_meta_key()
725 {
726 return '_iwp_ref_uid';
727 }
728
729 public function has_custom_unique_identifier()
730 {
731 return $this->getSetting('unique_identifier_type') === 'custom';
732 }
733
734 public function has_field_unique_identifier()
735 {
736 return $this->getSetting('unique_identifier_type') === 'field';
737 }
738
739 public function has_legacy_unique_identifier()
740 {
741 return !in_array($this->getSetting('unique_identifier_type'), ['custom', 'field']);
742 }
743 }
744