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
← All changes | class/Common/Importer/ImporterManager.php +103 -0 2.14.23 → 2.15.0 View file →
@@ -4,8 +4,9 @@
4 4
5 5 use ImportWP\Common\Filesystem\Filesystem;
6 6 use ImportWP\Common\Importer\Config\Config;
7 7 use ImportWP\Common\Importer\File\CSVFile;
8 +use ImportWP\Common\Importer\File\JSONFile;
8 9 use ImportWP\Common\Importer\File\XMLFile;
9 10 use ImportWP\Common\Importer\Mapper\AttachmentMapper;
10 11 use ImportWP\Common\Importer\Mapper\CommentMapper;
11 12 use ImportWP\Common\Importer\Mapper\PostMapper;
@@ -11,8 +12,9 @@
11 12 use ImportWP\Common\Importer\Mapper\PostMapper;
12 13 use ImportWP\Common\Importer\Mapper\TermMapper;
13 14 use ImportWP\Common\Importer\Mapper\UserMapper;
14 15 use ImportWP\Common\Importer\Parser\CSVParser;
16 +use ImportWP\Common\Importer\Parser\JSONParser;
15 17 use ImportWP\Common\Importer\Parser\XMLParser;
16 18 use ImportWP\Common\Importer\Permission\Permission;
17 19 use ImportWP\Common\Importer\State\ImporterState;
18 20 use ImportWP\Common\Importer\Template\AttachmentTemplate;
@@ -54,11 +56,57 @@
54 56 {
55 57 $this->filesystem = $filesystem;
56 58 $this->template_manager = $template_manager;
57 59 $this->event_handler = $event_handler;
60 +
61 + add_action('admin_init', [$this, 'download_debug_log']);
58 62 }
59 63
60 64 /**
65 + * Stream an importer debug log through an authenticated admin request.
66 + *
67 + * Direct public URLs under uploads/importwp are blocked by .htaccess (CVE-2025-12894).
68 + *
69 + * @return void
70 + */
71 + public function download_debug_log()
72 + {
73 + if (!isset($_GET['page'], $_GET['import'], $_GET['download_debug']) || $_GET['page'] !== 'importwp') {
74 + return;
75 + }
76 +
77 + if (!is_user_logged_in() || !current_user_can('manage_options')) {
78 + wp_die(esc_html__('You do not have permission to download this file.', 'jc-importer'), '', array('response' => 403));
79 + }
80 +
81 + if (!isset($_GET['_wpnonce']) || !wp_verify_nonce(sanitize_key(wp_unslash($_GET['_wpnonce'])), 'iwp_debug_log_download')) {
82 + wp_die(esc_html__('Invalid download request.', 'jc-importer'), '', array('response' => 403));
83 + }
84 +
85 + $importer_id = intval($_GET['import']);
86 + $importer_data = $this->get_importer($importer_id);
87 + if (!$importer_data) {
88 + wp_die(esc_html__('Invalid download request.', 'jc-importer'), '', array('response' => 403));
89 + }
90 +
91 + if (!$this->is_debug()) {
92 + wp_die(esc_html__('Debug mode is not enabled.', 'jc-importer'), '', array('response' => 403));
93 + }
94 +
95 + $file_path = Logger::getLogFile($importer_id);
96 + if (!is_string($file_path) || !file_exists($file_path)) {
97 + wp_die(esc_html__('Debug log file not found.', 'jc-importer'), '', array('response' => 404));
98 + }
99 +
100 + nocache_headers();
101 + header('Content-Type: text/plain; charset=utf-8');
102 + header('Content-Disposition: attachment; filename="' . basename($file_path) . '"');
103 + header('Content-Length: ' . (string) filesize($file_path));
104 + readfile($file_path);
105 + exit;
106 + }
107 +
108 + /**
61 109 * Get Importers
62 110 *
63 111 * @return ImporterModel[]
64 112 */
@@ -146,8 +194,10 @@
146 194 if ('xml' === $parser) {
147 195 return $this->get_xml_file($importer, $config);
148 196 } elseif ('csv' === $parser) {
149 197 return $this->get_csv_file($importer, $config);
198 + } elseif ('json' === $parser) {
199 + return $this->get_json_file($importer, $config);
150 200 }
151 201
152 202 return false;
153 203 }
@@ -169,8 +219,16 @@
169 219 $file->setRecordPath($importer->getFileSetting('base_path'));
170 220 return $file;
171 221 }
172 222
223 + public function get_json_file($id, $config)
224 + {
225 + $importer = $this->get_importer($id);
226 + $file = new JSONFile($importer->getFile(), $config);
227 + $file->setRecordPath($importer->getFileSetting('base_path'));
228 + return $file;
229 + }
230 +
173 231 public function preview_csv_file($id, $fields = [], $row = 0)
174 232 {
175 233 $importer = $this->get_importer($id);
176 234 $config = $this->get_config($importer, true);
@@ -194,8 +252,20 @@
194 252 $record = $parser->getRecord($row);
195 253 return $record->queryGroup(['fields' => $fields]);
196 254 }
197 255
256 + public function preview_json_file($id, $fields = [], $row = 0)
257 + {
258 + $importer = $this->get_importer($id);
259 + $config = $this->get_config($importer, true);
260 +
261 + $file = $this->get_json_file($importer, $config);
262 + $parser = new JSONParser($file);
263 +
264 + $record = $parser->getRecord($row);
265 + return $record->queryGroup(['fields' => $fields]);
266 + }
267 +
198 268 public function process_csv_file($id, $delimiter, $enclosure, $tmp = false)
199 269 {
200 270 $importer = $this->get_importer($id);
201 271 $config = $this->get_config($importer->getId(), $tmp);
@@ -230,8 +300,19 @@
230 300
231 301 return $results;
232 302 }
233 303
304 + public function process_json_file($id, $tmp = false)
305 + {
306 + $importer = $this->get_importer($id);
307 + $config = $this->get_config($importer->getId(), $tmp);
308 +
309 + $file = new JSONFile($importer->getFile(), $config);
310 + $file->processing(true);
311 +
312 + return $file->get_path_list();
313 + }
314 +
234 315 /**
235 316 * Link import file to importer via post meta
236 317 *
237 318 * @param ImporterModel $id
@@ -247,8 +328,15 @@
247 328 }
248 329
249 330 $index++;
250 331
332 + // Store uploads-relative paths so site moves / open_basedir changes do not break lookups.
333 + $file_path = wp_normalize_path($file_path);
334 + $relative = Filesystem::to_uploads_relative_path($file_path);
335 + if ($relative !== '' && $relative !== $file_path) {
336 + $file_path = $relative;
337 + }
338 +
251 339 update_post_meta($importer->getId(), '_importer_files', $index);
252 340 update_post_meta($importer->getId(), '_importer_file_' . $index, $file_path);
253 341 return $index;
254 342 }
@@ -720,10 +808,25 @@
720 808 Logger::debug('IM -get_xml_file');
721 809 $file = $this->get_xml_file($importer_data, $config);
722 810 Logger::debug('IM -load_parser');
723 811 $parser = new XMLParser($file);
812 + } elseif ($importer_data->getParser() === 'json') {
813 + Logger::debug('IM -get_json_file');
814 + $file = $this->get_json_file($importer_data, $config);
815 + Logger::debug('IM -load_parser');
816 + $parser = new JSONParser($file);
724 817 } else {
725 818 $parser = apply_filters('iwp/importer/init_parser', false, $importer_data, $config);
819 + }
820 +
821 + if (!$parser || !is_object($parser) || !method_exists($parser, 'file')) {
822 + $parser_type = $importer_data->getParser();
823 + throw new \Exception(
824 + sprintf(
825 + __('Unable to load importer parser for type: %s', 'jc-importer'),
826 + $parser_type ? $parser_type : __('unknown', 'jc-importer')
827 + )
828 + );
726 829 }
727 830
728 831 // if this is a new session, set start / end rows to state
729 832 if ($state->has_status('init')) {