/** * Import processing step (status console) */ public function process($save_history = true) { $wp_uploads = wp_upload_dir(); $import = $this->data['update_previous']; $history_log = new PMXI_History_Record(); $input = new PMXI_Input(); if (!empty(PMXI_Plugin::$session->history_id)) { $history_log->getById(PMXI_Plugin::$session->history_id); } $log_storage = (int) PMXI_Plugin::getInstance()->getOption('log_storage'); if (!PMXI_Plugin::is_ajax()) { $import->set((empty(PMXI_Plugin::$session->source) ? array() : PMXI_Plugin::$session->source) + array('xpath' => PMXI_Plugin::$session->xpath, 'options' => PMXI_Plugin::$session->options, 'count' => PMXI_Plugin::$session->count, 'friendly_name' => wp_all_import_clear_xss(PMXI_Plugin::$session->options['friendly_name']), 'feed_type' => PMXI_Plugin::$session->feed_type, 'parent_import_id' => $this->data['update_previous']->isEmpty() ? PMXI_Plugin::$session->parent_import_id : $this->data['update_previous']->parent_import_id, 'queue_chunk_number' => 0, 'triggered' => 0, 'processing' => 0, 'executing' => 1, 'iteration' => !empty($import->iteration) ? $import->iteration : 0))->save(); if (PMXI_Plugin::$session->action != 'continue') { // store import info in database $import->set(array('imported' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'deleted' => 0))->update(); } // add history log $custom_type = get_post_type_object($import->options['custom_type']); // unlink previous logs $by = array(); $by[] = array(array('import_id' => $import->id, 'type NOT LIKE' => 'trigger'), 'AND'); $historyLogs = new PMXI_History_List(); $historyLogs->setColumns('id', 'import_id', 'type', 'date')->getBy($by, 'id ASC'); if ($historyLogs->count() and $historyLogs->count() >= $log_storage) { $logsToRemove = $historyLogs->count() - $log_storage; foreach ($historyLogs as $i => $file) { $historyRecord = new PMXI_History_Record(); $historyRecord->getBy('id', $file['id']); if (!$historyRecord->isEmpty()) { $historyRecord->delete(); } // unlink history file only if ($i == $logsToRemove) { break; } } } $history_log->set(array('import_id' => $import->id, 'date' => date('Y-m-d H:i:s'), 'type' => PMXI_Plugin::$session->action != 'continue' ? 'manual' : 'continue', 'summary' => sprintf(__("%d %ss created %d updated %d deleted %d skipped", "pmxi_plugin"), $import->created, $custom_type->labels->singular_name, $import->updated, $import->deleted, $import->skipped)))->save(); PMXI_Plugin::$session->set('history_id', $history_log->id); foreach (get_taxonomies() as $tax) { delete_transient("pmxi_{$tax}_terms"); } $functions = $wp_uploads['basedir'] . DIRECTORY_SEPARATOR . WP_ALL_IMPORT_UPLOADS_BASE_DIRECTORY . DIRECTORY_SEPARATOR . 'functions.php'; if (@file_exists($functions)) { require_once $functions; } do_action('pmxi_before_xml_import', $import->id); PMXI_Plugin::$session->set('update_previous', $import->id); if (empty($import->options['encoding'])) { $currentOptions = $import->options; $currentOptions['encoding'] = 'UTF-8'; $import->set(array('options' => $currentOptions))->update(); } // unlink previous files $history = new PMXI_File_List(); $history->setColumns('id', 'name', 'registered_on', 'path')->getBy(array('import_id' => $import->id), 'id DESC'); if ($history->count()) { foreach ($history as $file) { $history_file_path = wp_all_import_get_absolute_path($file['path']); if (@file_exists($history_file_path) and $history_file_path != PMXI_Plugin::$session->filePath) { if (in_array($import->type, array('upload'))) { wp_all_import_remove_source($history_file_path, false); } else { wp_all_import_remove_source($history_file_path); } } $history_file = new PMXI_File_Record(); $history_file->getBy('id', $file['id']); if (!$history_file->isEmpty()) { $history_file->delete($history_file_path != PMXI_Plugin::$session->filePath); } } } if ($save_history) { $history_file = new PMXI_File_Record(); $history_file->set(array('name' => $import->name, 'import_id' => $import->id, 'path' => wp_all_import_get_relative_path(PMXI_Plugin::$session->filePath), 'registered_on' => date('Y-m-d H:i:s')))->save(); } /* Split file up into 1000 record chunks. This option will decrease the amount of slowdown experienced at the end of large imports. The slowdown is partially caused by the need for WP All Import to read deeper and deeper into the file on each successive iteration. Splitting the file into pieces means that, for example, instead of having to read 19000 records into a 20000 record file when importing the last 1000 records, WP All Import will just split it into 20 chunks, and then read the last chunk from the beginning. */ if ("ajax" == $import->options['import_processing'] and $import->count > PMXI_Plugin::getInstance()->getOption('large_feed_limit') and $import->options['chuncking']) { $chunk_files = array(); if (!empty(PMXI_Plugin::$session->local_paths)) { $records_count = 0; $chunk_records_count = 0; $feed = "<?xml version=\"1.0\" encoding=\"" . $import->options['encoding'] . "\"?>" . "\n" . "<pmxi_records>"; foreach (PMXI_Plugin::$session->local_paths as $key => $path) { $file = new PMXI_Chunk($path, array('element' => $import->root_element, 'encoding' => $import->options['encoding'])); // loop through the file until all lines are read while ($xml = $file->read()) { if (!empty($xml)) { //PMXI_Import_Record::preprocessXml($xml); $chunk = "<?xml version=\"1.0\" encoding=\"" . $import->options['encoding'] . "\"?>" . "\n" . $xml; $dom = new DOMDocument('1.0', $import->options['encoding']); $old = libxml_use_internal_errors(true); $dom->loadXML($chunk); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load libxml_use_internal_errors($old); $xpath = new DOMXPath($dom); if ($elements = @$xpath->query($import->xpath) and $elements->length) { $records_count += $elements->length; $chunk_records_count += $elements->length; $feed .= $xml; } } if ($chunk_records_count == PMXI_Plugin::getInstance()->getOption('large_feed_limit') or $records_count == $import->count) { $feed .= "</pmxi_records>"; $chunk_file_path = wp_all_import_secure_file($wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::TEMP_DIRECTORY) . DIRECTORY_SEPARATOR . "pmxi_chunk_" . count($chunk_files) . "_" . basename($path); file_put_contents($chunk_file_path, $feed); $chunk_files[] = $chunk_file_path; $chunk_records_count = 0; $feed = "<?xml version=\"1.0\" encoding=\"" . $import->options['encoding'] . "\"?>" . "\n" . "<pmxi_records>"; } } } PMXI_Plugin::$session->set('local_paths', $chunk_files); } } PMXI_Plugin::$session->save_data(); if ($log_storage) { $log_file = wp_all_import_secure_file($wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::LOGS_DIRECTORY, $history_log->id) . DIRECTORY_SEPARATOR . $history_log->id . '.html'; if (PMXI_Plugin::$session->action != 'continue') { if (file_exists($log_file)) { wp_all_import_remove_source($log_file, false); } //@file_put_contents($log_file, sprintf(__('<p>Source path `%s`</p>', 'wp_all_import_plugin'), $import->path)); } } $this->data['ajax_processing'] = "ajax" == $import->options['import_processing'] ? true : false; $this->render(); wp_ob_end_flush_all(); flush(); @set_time_limit(0); $import_id = $input->get('id', 0); if ("ajax" == $import->options['import_processing'] and !$import_id) { PMXI_Plugin::$session->convertData($import->id); //die(); } } elseif (empty($import->id)) { $import = new PMXI_Import_Record(); $import_id = $input->get('id', PMXI_Plugin::$session->update_previous); $import->getById($import_id); } $ajax_processing = "ajax" == $import->options['import_processing'] ? true : false; if (PMXI_Plugin::is_ajax() and $ajax_processing and !check_ajax_referer('wp_all_import_secure', 'security', false)) { exit(__('Security check', 'wp_all_import_plugin')); } if ($ajax_processing) { $logger = create_function('$m', 'echo "<div class=\\"progress-msg\\">$m</div>\\n"; flush();'); } else { $logger = create_function('$m', 'echo "<div class=\\"progress-msg\\">$m</div>\\n"; if ( "" != strip_tags(wp_all_import_strip_tags_content($m))) { PMXI_Plugin::$session->log .= "<p>".strip_tags(wp_all_import_strip_tags_content($m))."</p>"; flush(); }'); } PMXI_Plugin::$session->set('start_time', empty(PMXI_Plugin::$session->start_time) ? time() : PMXI_Plugin::$session->start_time); wp_cache_flush(); wp_defer_term_counting(true); wp_defer_comment_counting(true); if (PMXI_Plugin::is_ajax() or !$ajax_processing) { $functions = $wp_uploads['basedir'] . DIRECTORY_SEPARATOR . WP_ALL_IMPORT_UPLOADS_BASE_DIRECTORY . DIRECTORY_SEPARATOR . 'functions.php'; if (@file_exists($functions)) { require_once $functions; } $iteration_start_time = time(); if ($log_storage) { $log_file = wp_all_import_secure_file($wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::LOGS_DIRECTORY, $history_log->id) . DIRECTORY_SEPARATOR . $history_log->id . '.html'; } if ($ajax_processing) { // HTTP headers for no cache etc header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); } $loop = 0; $pointer = 0; $records = array(); if ($import->options['is_import_specified']) { foreach (preg_split('% *, *%', $import->options['import_specified'], -1, PREG_SPLIT_NO_EMPTY) as $chank) { if (preg_match('%^(\\d+)-(\\d+)$%', $chank, $mtch)) { $records = array_merge($records, range(intval($mtch[1]), intval($mtch[2]))); } else { $records = array_merge($records, array(intval($chank))); } } } $records_to_import = empty($records) ? $import->count : $records[count($records) - 1]; $failures = $input->get('failures', 0); // auto decrease records per iteration option if ($failures) { $options = $import->options; $options['records_per_request'] = ceil($options['records_per_request'] / 2) ? ceil($options['records_per_request'] / 2) : 1; $import->set(array('options' => $options))->update(); } $records_per_request = (!$ajax_processing and $import->options['records_per_request'] < 50) ? 50 : $import->options['records_per_request']; if (!empty(PMXI_Plugin::$session->local_paths)) { $feed = "<?xml version=\"1.0\" encoding=\"" . $import->options['encoding'] . "\"?>" . "\n" . "<pmxi_records>"; foreach (PMXI_Plugin::$session->local_paths as $key => $path) { $import_done = $import->imported + $import->skipped == $records_to_import ? true : false; if ($import_done) { if (strpos($path, "pmxi_chunk_") !== false and @file_exists($path)) { wp_all_import_remove_source($path, false); } PMXI_Plugin::$session->set('local_paths', array()); PMXI_Plugin::$session->save_data(); break; } $file = new PMXI_Chunk($path, array('element' => $import->root_element, 'encoding' => $import->options['encoding'], 'pointer' => PMXI_Plugin::$session->pointer, 'filter' => true)); // loop through the file until all lines are read while ($xml = $file->read() and empty($import->canceled)) { if (!empty($xml)) { // if ( ! $import->options['chuncking'] ) // PMXI_Import_Record::preprocessXml($xml); $chunk = "<?xml version=\"1.0\" encoding=\"" . $import->options['encoding'] . "\"?>" . "\n" . $xml; $dom = new DOMDocument('1.0', $import->options['encoding']); $old = libxml_use_internal_errors(true); $dom->loadXML($chunk); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load libxml_use_internal_errors($old); $xpath = new DOMXPath($dom); $pointer++; if ($this->data['elements'] = $elements = @$xpath->query($import->xpath) and $elements->length) { /* Merge nested XML/CSV files */ /*$nested_files = json_decode($import->options['nested_files'], true); if ( ! empty($nested_files) and is_array($nested_files)){ $merger = new PMXI_Nested($dom, $nested_files, $xml, $import->xpath, $elements); $merger->merge(); $xml = $merger->get_xml(); unset($merger); } */ // continue action if ($import->imported + $import->skipped >= PMXI_Plugin::$session->chunk_number + $elements->length - 1) { PMXI_Plugin::$session->set('chunk_number', PMXI_Plugin::$session->chunk_number + $elements->length); PMXI_Plugin::$session->save_data(); continue; } if (!$loop and $ajax_processing) { ob_start(); } $feed .= $xml; $loop += $elements->length; $processed_records = $import->imported + $import->skipped; if ($loop == $records_per_request or $processed_records + $loop == $records_to_import or $processed_records == $records_to_import) { $feed .= "</pmxi_records>"; $import->process($feed, $logger, PMXI_Plugin::$session->chunk_number, false, '/pmxi_records', $loop); unset($dom, $xpath); if (!$ajax_processing) { $feed = "<?xml version=\"1.0\" encoding=\"" . $import->options['encoding'] . "\"?>" . "\n" . "<pmxi_records>"; $loop = 0; } else { if (!$history_log->isEmpty()) { $custom_type = get_post_type_object($import->options['custom_type']); $history_log->set(array('time_run' => time() - strtotime($history_log->date), 'summary' => sprintf(__("%d %ss created %d updated %d deleted %d skipped", "pmxi_plugin"), $import->created, $custom_type->labels->singular_name, $import->updated, $import->deleted, $import->skipped)))->update(); } unset($file); PMXI_Plugin::$session->set('pointer', PMXI_Plugin::$session->pointer + $pointer); PMXI_Plugin::$session->save_data(); $log_data = ob_get_clean(); if ($log_storage) { $log = @fopen($log_file, 'a+'); @fwrite($log, $log_data); @fclose($log); } $iteration_execution_time = time() - $iteration_start_time; wp_send_json(array('imported' => $import->imported, 'created' => $import->created, 'updated' => $import->updated, 'skipped' => $import->skipped, 'percentage' => ceil($processed_records / $import->count * 100), 'warnings' => PMXI_Plugin::$session->warnings, 'errors' => PMXI_Plugin::$session->errors, 'log' => $log_data, 'done' => false, 'records_per_request' => $import->options['records_per_request'], 'iteration_execution_time' => $iteration_execution_time)); } } } } } // Move to the next file, set pointer to first element if ($ajax_processing) { if (strpos($path, "pmxi_chunk_") !== false and @file_exists($path)) { @unlink($path); } PMXI_Plugin::$session->set('pointer', 1); $pointer = 0; $lp = PMXI_Plugin::$session->local_paths; array_shift($lp); PMXI_Plugin::$session->set('local_paths', $lp); PMXI_Plugin::$session->save_data(); } else { break; } } } } // delete missing records if (PMXI_Plugin::is_ajax() and empty(PMXI_Plugin::$session->local_paths) or !$ajax_processing) { ob_start(); $is_all_records_deleted = $import->delete_missing_records($logger, $import->iteration); $log_data = ob_get_clean(); if ($log_storage) { $log = @fopen($log_file, 'a+'); @fwrite($log, $log_data); @fclose($log); } $iteration_execution_time = time() - $iteration_start_time; if ($ajax_processing and !$is_all_records_deleted) { wp_send_json(array('imported' => $import->imported, 'created' => $import->created, 'updated' => $import->updated, 'skipped' => $import->skipped, 'deleted' => $import->deleted, 'percentage' => 99, 'warnings' => PMXI_Plugin::$session->warnings, 'errors' => PMXI_Plugin::$session->errors, 'log' => $log_data, 'done' => false, 'records_per_request' => $import->options['records_per_request'], 'iteration_execution_time' => $iteration_execution_time)); } } if (PMXI_Plugin::is_ajax() and empty(PMXI_Plugin::$session->local_paths) or !$ajax_processing or !empty($import->canceled)) { $import->set(array('processing' => 0, 'triggered' => 0, 'queue_chunk_number' => 0, 'registered_on' => date('Y-m-d H:i:s'), 'iteration' => ++$import->iteration))->update(); if ("ajax" != $import->options['import_processing'] and $log_storage) { $log_file = wp_all_import_secure_file($wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::LOGS_DIRECTORY, $history_log->id) . DIRECTORY_SEPARATOR . $history_log->id . '.html'; if (PMXI_Plugin::$session->action != 'continue') { @file_put_contents($log_file, PMXI_Plugin::$session->log); } else { $log = @fopen($log_file, 'a+'); @fwrite($log, PMXI_Plugin::$session->log); @fclose($log); } } wp_cache_flush(); foreach (get_taxonomies() as $tax) { delete_option("{$tax}_children"); _get_term_hierarchy($tax); } $import->set(array('registered_on' => date('Y-m-d H:i:s'), 'executing' => 0))->update(); wp_defer_term_counting(false); wp_defer_comment_counting(false); // add history log $custom_type = get_post_type_object($import->options['custom_type']); $history_log->set(array('time_run' => time() - strtotime($history_log->date), 'summary' => sprintf(__("%d %ss created %d updated %d deleted %d skipped", "pmxi_plugin"), $import->created, $custom_type->labels->singular_name, $import->updated, $import->deleted, $import->skipped)))->update(); // clear import session PMXI_Plugin::$session->clean_session($import->id); // clear session data (prevent from reimporting the same data on page refresh) // [indicate in header process is complete] $msg = !empty($import->canceled) ? addcslashes(__('Canceled', 'wp_all_import_plugin'), "\n\r") : addcslashes(__('Complete', 'wp_all_import_plugin'), "\n\r"); if ($ajax_processing) { ob_start(); } do_action('pmxi_after_xml_import', $import->id); $import->delete_source($logger); $import->options['is_import_specified'] and $logger and call_user_func($logger, 'Done'); echo <<<COMPLETE <script type="text/javascript"> //<![CDATA[ (function(\$){\t \t\$('#status').html('{$msg}');\t \twindow.onbeforeunload = false; })(jQuery); //]]> </script> COMPLETE; // [/indicate in header process is complete] if ($ajax_processing) { wp_send_json(array('imported' => $import->imported, 'created' => $import->created, 'updated' => $import->updated, 'skipped' => $import->skipped, 'percentage' => 100, 'warnings' => PMXI_Plugin::$session->warnings, 'errors' => PMXI_Plugin::$session->errors, 'log' => ob_get_clean(), 'done' => true, 'records_per_request' => $import->options['records_per_request'])); } } }