/** * 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' => 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"); } 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(); } } } 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(); if (PMXI_Plugin::is_ajax() or !$ajax_processing) { $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, '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'])); } } } } } // 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; } } } } if (PMXI_Plugin::is_ajax() and empty(PMXI_Plugin::$session->local_paths) or !$ajax_processing or !empty($import->canceled)) { 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(); // 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->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, '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'])); } } }
/** * Import processing step (status console) */ public function process($save_history = true) { $wp_uploads = wp_upload_dir(); $import = $this->data['update_previous']; $logger = create_function('$m', 'echo "<div class=\\"progress-msg\\">$m</div>\\n"; if ( "" != strip_tags(pmxi_strip_tags_content($m)) and !empty(PMXI_Plugin::$session[\'pmxi_import\'][\'log\'])) { PMXI_Plugin::$session[\'pmxi_import\'][\'log\'] .= "<p>".strip_tags(pmxi_strip_tags_content($m))."</p>"; flush(); }'); if (!PMXI_Plugin::is_ajax()) { $import->set((empty(PMXI_Plugin::$session->data['pmxi_import']['source']) ? array() : PMXI_Plugin::$session->data['pmxi_import']['source']) + array('xpath' => PMXI_Plugin::$session->data['pmxi_import']['xpath'], 'template' => PMXI_Plugin::$session->data['pmxi_import']['template'], 'options' => PMXI_Plugin::$session->data['pmxi_import']['options'], 'count' => PMXI_Plugin::$session->data['pmxi_import']['count'], 'friendly_name' => PMXI_Plugin::$session->data['pmxi_import']['options']['friendly_name'], 'feed_type' => PMXI_Plugin::$session->data['pmxi_import']['feed_type'], 'parent_import_id' => $this->data['update_previous']->isEmpty() ? PMXI_Plugin::$session->data['pmxi_import']['parent_import_id'] : $this->data['update_previous']->parent_import_id, 'queue_chunk_number' => 0, 'triggered' => 0, 'processing' => 0, 'iteration' => !empty($import->iteration) ? $import->iteration : 0))->save(); if (PMXI_Plugin::$session->data['pmxi_import']['action'] != 'continue') { // store import info in database $import->set(array('imported' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0))->update(); } foreach (get_taxonomies() as $tax) { delete_transient("pmxi_{$tax}_terms"); } do_action('pmxi_before_xml_import', $import->id); PMXI_Plugin::$session['pmxi_import']['update_previous'] = $import->id; // unlick 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) { if (@file_exists($file['path']) and $file['path'] != PMXI_Plugin::$session->data['pmxi_import']['filePath']) { @unlink($file['path']); } $history_file = new PMXI_File_Record(); $history_file->getBy('id', $file['id']); if (!$history_file->isEmpty()) { $history_file->delete(); } } } if ($save_history) { $history_file = new PMXI_File_Record(); $history_file->set(array('name' => $import->name, 'import_id' => $import->id, 'path' => PMXI_Plugin::$session->data['pmxi_import']['filePath'], 'contents' => $this->get_xml(), '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->data['pmxi_import']['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->data['pmxi_import']['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_uploads['path'] . "/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['pmxi_import']['local_paths'] = $chunk_files; } } pmxi_session_commit(); $this->render(); wp_ob_end_flush_all(); flush(); @set_time_limit(0); if ("ajax" == $import->options['import_processing']) { die; } } elseif (empty($import->id)) { $import = new PMXI_Import_Record(); $import->getById(PMXI_Plugin::$session->data['pmxi_import']['update_previous']); } $ajax_processing = "ajax" == $import->options['import_processing'] ? true : false; PMXI_Plugin::$session['pmxi_import']['start_time'] = empty(PMXI_Plugin::$session->data['pmxi_import']['start_time']) ? time() : PMXI_Plugin::$session->data['pmxi_import']['start_time']; wp_cache_flush(); if (PMXI_Plugin::is_ajax() or !$ajax_processing) { if ("ajax" == $import->options['import_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]; $records_per_request = (!$ajax_processing and $import->options['records_per_request'] < 50) ? 50 : $import->options['records_per_request']; if (!empty(PMXI_Plugin::$session->data['pmxi_import']['local_paths'])) { $feed = "<?xml version=\"1.0\" encoding=\"" . $import->options['encoding'] . "\"?>" . "\n" . "<pmxi_records>"; foreach (PMXI_Plugin::$session->data['pmxi_import']['local_paths'] as $key => $path) { $import_done = $import->imported + $import->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors'] == $records_to_import ? true : false; if ($import_done) { if (strpos($path, "pmxi_chunk_") !== false and @file_exists($path)) { @unlink($path); } PMXI_Plugin::$session['pmxi_import']['local_paths'] = array(); pmxi_session_commit(); break; } $file = new PMXI_Chunk($path, array('element' => $import->root_element, 'encoding' => $import->options['encoding'], 'pointer' => PMXI_Plugin::$session->data['pmxi_import']['pointer'])); // 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); $pointer++; if ($this->data['elements'] = $elements = @$xpath->query($import->xpath) and $elements->length) { // continue action if ($import->imported + $import->skipped >= PMXI_Plugin::$session->data['pmxi_import']['chunk_number'] + $elements->length - 1) { PMXI_Plugin::$session['pmxi_import']['chunk_number'] = PMXI_Plugin::$session->data['pmxi_import']['chunk_number'] + $elements->length; pmxi_session_commit(); continue; } if (!$loop and $ajax_processing) { ob_start(); } $feed .= $xml; $loop += $elements->length; $processed_records = $import->imported + $import->skipped + PMXI_Plugin::$session->data['pmxi_import']['errors']; 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->data['pmxi_import']['chunk_number'], false, '/pmxi_records'); unset($dom, $xpath); if (!$ajax_processing) { $feed = "<?xml version=\"1.0\" encoding=\"" . $import->options['encoding'] . "\"?>" . "\n" . "<pmxi_records>"; $loop = 0; } else { unset($file); PMXI_Plugin::$session['pmxi_import']['pointer'] = PMXI_Plugin::$session->data['pmxi_import']['pointer'] + $pointer; pmxi_session_commit(); wp_send_json(array('created' => $import->created, 'updated' => $import->updated, 'percentage' => ceil($processed_records / $import->count * 100), 'warnings' => PMXI_Plugin::$session->data['pmxi_import']['warnings'], 'errors' => PMXI_Plugin::$session->data['pmxi_import']['errors'], 'log' => ob_get_clean(), 'done' => false)); } } } } } // 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['pmxi_import']['pointer'] = 1; $pointer = 0; array_shift(PMXI_Plugin::$session->data['pmxi_import']['local_paths']); PMXI_Plugin::$session['pmxi_import']['local_paths'] = PMXI_Plugin::$session->data['pmxi_import']['local_paths']; pmxi_session_commit(); } else { break; } } } } if (PMXI_Plugin::is_ajax() and empty(PMXI_Plugin::$session->data['pmxi_import']['local_paths']) or !$ajax_processing) { // Save import process log $log_file = $wp_uploads['basedir'] . '/wpallimport_logs/' . $import->id . '.html'; if (file_exists($log_file)) { unlink($log_file); } @file_put_contents($log_file, PMXI_Plugin::$session->data['pmxi_import']['log']); if (!empty(PMXI_Plugin::$session->data['pmxi_import'])) { do_action('pmxi_after_xml_import', $import->id); } wp_cache_flush(); foreach (get_taxonomies() as $tax) { delete_option("{$tax}_children"); _get_term_hierarchy($tax); } $import->set('registered_on', date('Y-m-d H:i:s'))->update(); // clear import session pmxi_session_unset(); // clear session data (prevent from reimporting the same data on page refresh) // [indicate in header process is complete] $msg = addcslashes(__('Complete', 'pmxi_plugin'), "\n\r"); if ($ajax_processing) { ob_start(); } $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\$('#import_finished').show(); \twindow.onbeforeunload = false; })(jQuery); //]]> </script> COMPLETE; // [/indicate in header process is complete] if ($ajax_processing) { wp_send_json(array('created' => $import->created, 'updated' => $import->updated, 'percentage' => 100, 'warnings' => PMXI_Plugin::$session->data['pmxi_import']['warnings'], 'errors' => PMXI_Plugin::$session->data['pmxi_import']['errors'], 'log' => ob_get_clean(), 'done' => true)); } } }
/** * Import all files matched by path * @param callback[optional] $logger Method where progress messages are submmitted * @return PMXI_Import_Record * @chainable */ public function execute($logger = NULL, $cron = true, $history_log_id = false) { $uploads = wp_upload_dir(); if ($this->path) { $files = array($this->path); foreach ($files as $ind => $path) { $filePath = ''; if ($this->queue_chunk_number == 0 and $this->processing == 0) { $this->set(array('processing' => 1))->update(); // lock cron requests if ($this->type == 'ftp') { $this->set(array('processing' => 0))->update(); return array('status' => 500, 'message' => sprintf(__('This import appears to be using FTP. Unfortunately WP All Import no longer supports the FTP protocol. Please contact <a href="mailto:support@wpallimport.com">%s</a> if you have any questions.', 'wp_all_import_plugin'), '*****@*****.**')); //$logger and call_user_func($logger, sprintf(__('This import appears to be using FTP. Unfortunately WP All Import no longer supports the FTP protocol. Please contact <a href="mailto:support@wpallimport.com">%s</a> if you have any questions.', 'wp_all_import_plugin'), '*****@*****.**')); die; } elseif ($this->type == 'url') { $filesXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<data><node></node></data>"; $filePaths = XmlImportParser::factory($filesXML, '/data/node', $this->path, $file)->parse(); $tmp_files[] = $file; foreach ($tmp_files as $tmp_file) { // remove all temporary files created @unlink($tmp_file); } $file_to_import = $this->path; if (!empty($filePaths) and is_array($filePaths)) { $file_to_import = array_shift($filePaths); } $uploader = new PMXI_Upload(trim($file_to_import), $this->errors); $upload_result = $uploader->url($this->feed_type, $this->path); if ($upload_result instanceof WP_Error) { $this->errors = $upload_result; } else { $filePath = $upload_result['filePath']; } } elseif ($this->type == 'file') { $uploader = new PMXI_Upload(trim(basename($this->path)), $this->errors); $upload_result = $uploader->file(); if ($upload_result instanceof WP_Error) { $this->errors = $upload_result; } else { $filePath = $upload_result['filePath']; } } elseif (!in_array($this->type, array('ftp'))) { // retrieve already uploaded file $uploader = new PMXI_Upload(trim($this->path), $this->errors, rtrim(str_replace(basename($this->path), '', $this->path), '/')); $upload_result = $uploader->upload(); if ($upload_result instanceof WP_Error) { $this->errors = $upload_result; } else { $filePath = $upload_result['filePath']; } } if (!$this->errors->get_error_codes() and "" != $filePath) { $this->set(array('queue_chunk_number' => 1))->update(); } elseif ($this->errors->get_error_codes()) { $msgs = $this->errors->get_error_messages(); if (!is_array($msgs)) { $msgs = array($msgs); } // foreach ($msgs as $msg){ // $logger and call_user_func($logger, sprintf(__('ERROR: %s', 'wp_all_import_plugin'), $msg)); // } $this->set(array('processing' => 0))->update(); return array('status' => 500, 'message' => $msgs); die; } $this->set(array('processing' => 0))->update(); // unlock cron requests } // if empty file path, than it's mean feed in cron process. Take feed path from history. if (empty($filePath)) { $history = new PMXI_File_List(); $history->setColumns('id', 'name', 'registered_on', 'path')->getBy(array('import_id' => $this->id), 'id DESC'); if ($history->count()) { $history_file = new PMXI_File_Record(); $history_file->getBy('id', $history[0]['id']); $filePath = wp_all_import_get_absolute_path($history_file->path); } } // if feed path found if (!empty($filePath) and @file_exists($filePath)) { if ($this->queue_chunk_number === 1 and $this->processing == 0) { // import first cron request $this->set(array('processing' => 1))->update(); // lock cron requests if (empty($this->options['encoding'])) { $currentOptions = $this->options; $currentOptions['encoding'] = 'UTF-8'; $this->set(array('options' => $currentOptions))->update(); } set_time_limit(0); $file = new PMXI_Chunk($filePath, array('element' => $this->root_element, 'encoding' => $this->options['encoding'])); // chunks counting $chunks = 0; $history_xml = ''; while ($xml = $file->read()) { if (!empty($xml)) { PMXI_Import_Record::preprocessXml($xml); $xml = "<?xml version=\"1.0\" encoding=\"" . $this->options['encoding'] . "\"?>" . "\n" . $xml; $dom = new DOMDocument('1.0', !empty($this->options['encoding']) ? $this->options['encoding'] : 'UTF-8'); $old = libxml_use_internal_errors(true); $dom->loadXML($xml); libxml_use_internal_errors($old); $xpath = new DOMXPath($dom); if ($elements = @$xpath->query($this->xpath) and $elements->length) { $chunks += $elements->length; if ("" == $history_xml) { $history_xml = $xml; } } unset($dom, $xpath, $elements); } } unset($file); if (!$chunks) { //$logger and call_user_func($logger, sprintf(__('#%s No matching elements found for Root element and XPath expression specified', 'wp_all_import_plugin'), $this->id)); $this->set(array('queue_chunk_number' => 0, 'processing' => 0, 'imported' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'deleted' => 0, 'triggered' => 0))->update(); return array('status' => 500, 'message' => sprintf(__('#%s No matching elements found for Root element and XPath expression specified', 'wp_all_import_plugin'), $this->id)); die; } // unlick previous files $history = new PMXI_File_List(); $history->setColumns('id', 'name', 'registered_on', 'path')->getBy(array('import_id' => $this->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 != $filePath) { if (in_array($this->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 != $filePath); } } } // update history $history_file = new PMXI_File_Record(); $history_file->set(array('name' => $this->name, 'import_id' => $this->id, 'path' => wp_all_import_get_relative_path($filePath), 'registered_on' => date('Y-m-d H:i:s')))->insert(); do_action('pmxi_before_xml_import', $this->id); $this->set(array('count' => $chunks, 'processing' => 0))->update(); // set pointer to the first chunk, updates feed elements count and unlock cron process } // compose data to look like result of wizard steps if ($this->queue_chunk_number and $this->processing == 0) { $this->set(array('processing' => 1))->update(); // lock cron requests @set_time_limit(0); $file = new PMXI_Chunk($filePath, array('element' => $this->root_element, 'encoding' => $this->options['encoding'], 'pointer' => $this->queue_chunk_number)); $feed = "<?xml version=\"1.0\" encoding=\"" . $this->options['encoding'] . "\"?>" . "\n" . "<pmxi_records>"; $loop = 0; $xml = ''; $processing_time_limit = PMXI_Plugin::getInstance()->getOption('cron_processing_time_limit') ? PMXI_Plugin::getInstance()->getOption('cron_processing_time_limit') : 120; $start_rocessing_time = time(); $chunk_number = $this->queue_chunk_number; $functions = $uploads['basedir'] . DIRECTORY_SEPARATOR . WP_ALL_IMPORT_UPLOADS_BASE_DIRECTORY . DIRECTORY_SEPARATOR . 'functions.php'; if (@file_exists($functions)) { require_once $functions; } while ($xml = $file->read() and $this->processing == 1 and time() - $start_rocessing_time <= $processing_time_limit) { if (!empty($xml)) { $chunk_number++; PMXI_Import_Record::preprocessXml($xml); $xml_chunk = "<?xml version=\"1.0\" encoding=\"" . $this->options['encoding'] . "\"?>" . "\n" . $xml; $dom = new DOMDocument('1.0', !empty($this->options['encoding']) ? $this->options['encoding'] : 'UTF-8'); $old = libxml_use_internal_errors(true); $dom->loadXML($xml_chunk); libxml_use_internal_errors($old); $xpath = new DOMXPath($dom); if ($elements = @$xpath->query($this->xpath) and $elements->length) { $feed .= $xml; $loop += $elements->length; } unset($dom, $xpath, $elements); } if ($loop == $this->options['records_per_request'] or $this->count == $this->imported + $this->skipped or $this->count == $loop + $this->imported + $this->skipped) { // skipping scheduled imports if any for the next hit $feed .= "</pmxi_records>"; $this->process($feed, $logger, $chunk_number, $cron, '/pmxi_records', $loop); // set last update $this->set(array('registered_on' => date('Y-m-d H:i:s'), 'queue_chunk_number' => $chunk_number))->update(); $loop = 0; $feed = "<?xml version=\"1.0\" encoding=\"" . $this->options['encoding'] . "\"?>" . "\n" . "<pmxi_records>"; } } unset($file); // delect, if cron process if finished if ((int) $this->count <= (int) $this->imported + (int) $this->skipped) { // Delete posts that are no longer present in your file if (!empty($this->options['is_delete_missing']) and $this->options['duplicate_matching'] == 'auto') { $postList = new PMXI_Post_List(); $missing_ids = array(); $missingPosts = $postList->getBy(array('import_id' => $this->id, 'iteration !=' => $this->iteration)); if (!$missingPosts->isEmpty()) { foreach ($missingPosts as $missingPost) { $missing_ids[] = $missingPost['post_id']; } } // Delete posts from database if (!empty($missing_ids) && is_array($missing_ids)) { $missing_ids_arr = array_chunk($missing_ids, 100); foreach ($missing_ids_arr as $key => $ids) { if (!empty($ids)) { foreach ($ids as $k => $id) { $to_delete = true; // Instead of deletion, set Custom Field if ($this->options['is_update_missing_cf']) { update_post_meta($id, $this->options['update_missing_cf_name'], $this->options['update_missing_cf_value']); $to_delete = false; } // Instead of deletion, change post status to Draft $final_post_type = get_post_type($pid); if ($this->options['set_missing_to_draft'] and $final_post_type != 'product_variation') { $this->wpdb->update($this->wpdb->posts, array('post_status' => 'draft'), array('ID' => $id)); $to_delete = false; } // Delete posts that are no longer present in your file if ($to_delete) { // Remove attachments empty($this->options['is_keep_attachments']) and wp_delete_attachments($id, true, 'files'); // Remove images empty($this->options['is_keep_imgs']) and wp_delete_attachments($id, true, 'images'); // Clear post's relationships if ($this->options['custom_type'] != "import_users") { wp_delete_object_term_relationships($id, get_object_taxonomies('' != $this->options['custom_type'] ? $this->options['custom_type'] : 'post')); } } else { unset($ids[$k]); } } if (!empty($ids)) { do_action('pmxi_delete_post', $ids); if ($this->options['custom_type'] == "import_users") { $sql = "delete a,b\n\t\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->wpdb->users . " a\n\t\t\t\t\t\t\t\t\t\t\t\t\tLEFT JOIN " . $this->wpdb->usermeta . " b ON ( a.ID = b.user_id )\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\tWHERE a.ID IN (" . implode(',', $ids) . ");"; } else { $sql = "delete a,b,c\n\t\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->wpdb->posts . " a\n\t\t\t\t\t\t\t\t\t\t\t\t\tLEFT JOIN " . $this->wpdb->term_relationships . " b ON ( a.ID = b.object_id )\n\t\t\t\t\t\t\t\t\t\t\t\t\tLEFT JOIN " . $this->wpdb->postmeta . " c ON ( a.ID = c.post_id )\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\tWHERE a.ID IN (" . implode(',', $ids) . ");"; } $this->wpdb->query($sql); // Delete record form pmxi_posts $sql = "DELETE FROM " . PMXI_Plugin::getInstance()->getTablePrefix() . "posts WHERE post_id IN (" . implode(',', $ids) . ") AND import_id = %d"; $this->wpdb->query($this->wpdb->prepare($sql, $this->id)); $this->set(array('deleted' => $this->deleted + count($ids)))->update(); } } } } } // Set out of stock status for missing records [Woocommerce add-on option] if (empty($this->options['is_delete_missing']) and $this->options['custom_type'] == "product" and class_exists('PMWI_Plugin') and !empty($this->options['missing_records_stock_status'])) { $postList = new PMXI_Post_List(); $missingPosts = $postList->getBy(array('import_id' => $this->id, 'iteration !=' => $this->iteration)); if (!$missingPosts->isEmpty()) { foreach ($missingPosts as $missingPost) { update_post_meta($missingPost['post_id'], '_stock_status', 'outofstock'); update_post_meta($missingPost['post_id'], '_stock', 0); $postRecord = new PMXI_Post_Record(); $postRecord->getBy('id', $missingPost['id']); if (!$postRecord->isEmpty()) { $postRecord->set(array('iteration' => $this->iteration))->update(); } unset($postRecord); } } } $this->set(array('processing' => 0, 'triggered' => 0, 'queue_chunk_number' => 0, 'registered_on' => date('Y-m-d H:i:s'), 'iteration' => ++$this->iteration))->update(); wp_cache_flush(); foreach (get_taxonomies() as $tax) { delete_option("{$tax}_children"); _get_term_hierarchy($tax); } if ($history_log_id) { $history_log = new PMXI_History_Record(); $history_log->getById($history_log_id); if (!$history_log->isEmpty()) { $custom_type = get_post_type_object($this->options['custom_type']); $history_log->set(array('time_run' => time() - strtotime($history_log->date), 'summary' => sprintf(__("import finished & cron un-triggered<br>%s %s created %s updated %s deleted %s skipped", "pmxi_plugin"), $this->created, $custom_type->labels->name, $this->updated, $this->deleted, $this->skipped)))->save(); } } do_action('pmxi_after_xml_import', $this->id); return array('status' => 200, 'message' => sprintf(__('Import #%s complete', 'wp_all_import_plugin'), $this->id)); //$logger and call_user_func($logger, sprintf(__('Import #%s complete', 'wp_all_import_plugin'), $this->id)); } else { $this->set(array('processing' => 0))->update(); if ($history_log_id) { $history_log = new PMXI_History_Record(); $history_log->getById($history_log_id); if (!$history_log->isEmpty()) { $custom_type = get_post_type_object($this->options['custom_type']); $history_log->set(array('time_run' => time() - strtotime($history_log->date), 'summary' => sprintf(__("%d %s created %d updated %d deleted %d skipped", "pmxi_plugin"), $this->created, $custom_type->labels->name, $this->updated, $this->deleted, $this->skipped)))->save(); } } return array('status' => 200, 'message' => sprintf(__('Records Processed %s. Records Count %s.', 'wp_all_import_plugin'), (int) $this->queue_chunk_number, (int) $this->count)); // $logger and call_user_func($logger, sprintf(__('Records Count %s', 'wp_all_import_plugin'), (int) $this->count)); // $logger and call_user_func($logger, sprintf(__('Records Processed %s', 'wp_all_import_plugin'), (int) $this->imported + (int) $this->skipped)); } } } else { $this->set(array('processing' => 0, 'triggered' => 0, 'queue_chunk_number' => 0, 'imported' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'deleted' => 0))->update(); return array('status' => 500, 'message' => sprintf(__('#%s source file not found', 'wp_all_import_plugin'), $this->id)); //$logger and call_user_func($logger, sprintf(__('#%s source file not found', 'wp_all_import_plugin'), $this->id)); die; } } } return $this; }
public static function link_template_to_import(&$export, $file_path, $foundPosts) { $exportOptions = $export->options; // associate exported posts with new import if (wp_all_export_is_compatible()) { $options = self::$templateOptions + PMXI_Plugin::get_default_import_options(); $import = new PMXI_Import_Record(); $import->getById($exportOptions['import_id']); if (!$import->isEmpty() and $import->parent_import_id == 99999) { $xmlPath = $file_path; $root_element = ''; $historyPath = $file_path; if ('csv' == $exportOptions['export_to']) { $is_secure_import = PMXE_Plugin::getInstance()->getOption('secure'); $options['delimiter'] = $exportOptions['delimiter']; include_once PMXI_Plugin::ROOT_DIR . '/libraries/XmlImportCsvParse.php'; $path_info = pathinfo($xmlPath); $path_parts = explode(DIRECTORY_SEPARATOR, $path_info['dirname']); $security_folder = array_pop($path_parts); $wp_uploads = wp_upload_dir(); $target = $is_secure_import ? $wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXE_Plugin::UPLOADS_DIRECTORY . DIRECTORY_SEPARATOR . $security_folder : $wp_uploads['path']; $csv = new PMXI_CsvParser(array('filename' => $xmlPath, 'targetDir' => $target)); if (!in_array($xmlPath, $exportOptions['attachment_list'])) { $exportOptions['attachment_list'][] = $csv->xml_path; } $historyPath = $csv->xml_path; $root_element = 'node'; } else { $root_element = apply_filters('wp_all_export_record_xml_tag', $exportOptions['record_xml_tag'], $export->id); } $import->set(array('xpath' => '/' . $root_element, 'type' => 'upload', 'options' => $options, 'root_element' => $root_element, 'path' => $xmlPath, 'name' => basename($xmlPath), 'imported' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'deleted' => 0, 'iteration' => 1, 'count' => $foundPosts))->save(); $history_file = new PMXI_File_Record(); $history_file->set(array('name' => $import->name, 'import_id' => $import->id, 'path' => $historyPath, 'registered_on' => date('Y-m-d H:i:s')))->save(); $exportOptions['import_id'] = $import->id; $export->set(array('options' => $exportOptions))->save(); } } }
/** * Import all files matched by path * @param callback[optional] $logger Method where progress messages are submmitted * @return PMXI_Import_Record * @chainable */ public function execute($logger = NULL, $cron = false) { $this->set('registered_on', date('Y-m-d H:i:s'))->save(); // update registered_on to indicated that job has been exectured even if no files are going to be imported by the rest of the method $wp_uploads = wp_upload_dir(); $this->set(array('processing' => 1))->update(); // lock cron requests wp_reset_postdata(); XmlExportEngine::$exportOptions = $this->options; XmlExportEngine::$is_user_export = $this->options['is_user_export']; if ('advanced' == $this->options['export_type']) { if (XmlExportEngine::$is_user_export) { $exportQuery = eval('return new WP_User_Query(array(' . $this->options['wp_query'] . ', \'orderby\' => \'ID\', \'order\' => \'ASC\', \'offset\' => ' . $this->exported . ', \'number\' => ' . $this->options['records_per_iteration'] . '));'); } else { $exportQuery = eval('return new WP_Query(array(' . $this->options['wp_query'] . ', \'orderby\' => \'ID\', \'order\' => \'ASC\', \'offset\' => ' . $this->exported . ', \'posts_per_page\' => ' . $this->options['records_per_iteration'] . '));'); } } else { XmlExportEngine::$post_types = $this->options['cpt']; if (!in_array('users', $this->options['cpt'])) { add_filter('posts_where', 'wp_all_export_posts_where', 10, 1); add_filter('posts_join', 'wp_all_export_posts_join', 10, 1); $exportQuery = new WP_Query(array('post_type' => $this->options['cpt'], 'post_status' => 'any', 'orderby' => 'ID', 'order' => 'ASC', 'offset' => $this->exported, 'posts_per_page' => $this->options['records_per_iteration'])); remove_filter('posts_join', 'wp_all_export_posts_join'); remove_filter('posts_where', 'wp_all_export_posts_where'); } else { add_action('pre_user_query', 'wp_all_export_pre_user_query', 10, 1); $exportQuery = new WP_User_Query(array('orderby' => 'ID', 'order' => 'ASC', 'number' => $this->options['records_per_iteration'], 'offset' => $this->exported)); remove_action('pre_user_query', 'wp_all_export_pre_user_query'); } } XmlExportEngine::$exportQuery = $exportQuery; $file_path = false; $is_secure_import = PMXE_Plugin::getInstance()->getOption('secure'); if ($this->exported == 0) { $import = new PMXI_Import_Record(); $import->getById($this->options['import_id']); if ($import->isEmpty()) { $import->set(array('parent_import_id' => 99999, 'xpath' => '/', 'type' => 'upload', 'options' => array('empty'), 'root_element' => 'root', 'path' => 'path', 'imported' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'deleted' => 0, 'iteration' => 1))->save(); $exportOptions = $this->options; $exportOptions['import_id'] = $import->id; $this->set(array('options' => $exportOptions))->save(); } else { if ($import->parent_import_id != 99999) { $newImport = new PMXI_Import_Record(); $newImport->set(array('parent_import_id' => 99999, 'xpath' => '/', 'type' => 'upload', 'options' => array('empty'), 'root_element' => 'root', 'path' => 'path', 'imported' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'deleted' => 0, 'iteration' => 1))->save(); $exportOptions = $this->options; $exportOptions['import_id'] = $newImport->id; $this->set(array('options' => $exportOptions))->save(); } } if (!empty($this->attch_id)) { wp_delete_attachment($this->attch_id, true); } $target = $is_secure_import ? wp_all_export_secure_file($wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXE_Plugin::UPLOADS_DIRECTORY) : $wp_uploads['path']; $file_path = $target . DIRECTORY_SEPARATOR . time() . '.' . $this->options['export_to']; if (!$is_secure_import) { $wp_filetype = wp_check_filetype(basename($file_path), null); $attachment_data = array('guid' => $wp_uploads['baseurl'] . '/' . _wp_relative_upload_path($file_path), 'post_mime_type' => $wp_filetype['type'], 'post_title' => preg_replace('/\\.[^.]+$/', '', basename($file_path)), 'post_content' => '', 'post_status' => 'inherit'); $attach_id = wp_insert_attachment($attachment_data, $file_path); $this->set(array('attch_id' => $attach_id))->save(); } else { wp_all_export_remove_source(wp_all_export_get_absolute_path($this->options['filepath'])); $exportOptions = $this->options; $exportOptions['filepath'] = $file_path; $this->set(array('options' => $exportOptions))->save(); } } else { if (!$is_secure_import) { $file_path = str_replace($wp_uploads['baseurl'], $wp_uploads['basedir'], wp_get_attachment_url($this->attch_id)); } else { $file_path = wp_all_export_get_absolute_path($this->options['filepath']); } } $foundPosts = !XmlExportEngine::$is_user_export ? $exportQuery->found_posts : $exportQuery->get_total(); $postCount = !XmlExportEngine::$is_user_export ? $exportQuery->post_count : count($exportQuery->get_results()); // if posts still exists then export them if ($postCount) { switch ($this->options['export_to']) { case 'xml': if (!XmlExportEngine::$is_user_export) { $exported_to_file = pmxe_export_xml($exportQuery, $this->options, false, $cron, $file_path); } else { $exported_to_file = pmxe_export_users_xml($exportQuery, $this->options, false, $cron, $file_path); } break; case 'csv': if (!XmlExportEngine::$is_user_export) { $exported_to_file = pmxe_export_csv($exportQuery, $this->options, false, $cron, $file_path, $this->exported); } else { $exported_to_file = pmxe_export_users_csv($exportQuery, $this->options, false, $cron, $file_path, $this->exported); } break; default: # code... break; } wp_reset_postdata(); $this->set(array('exported' => $this->exported + $postCount, 'last_activity' => date('Y-m-d H:i:s'), 'processing' => 0))->save(); } else { wp_reset_postdata(); if (file_exists($file_path)) { if ($this->options['export_to'] == 'xml') { file_put_contents($file_path, '</data>', FILE_APPEND); } if (wp_all_export_is_compatible() and ($this->options['is_generate_templates'] or $this->options['is_generate_import'])) { $custom_type = empty($exportOptions['cpt']) ? 'post' : $exportOptions['cpt'][0]; $templateOptions = array('type' => (!empty($exportOptions['cpt']) and $exportOptions['cpt'][0] == 'page') ? 'page' : 'post', 'wizard_type' => 'new', 'deligate' => 'wpallexport', 'custom_type' => XmlExportEngine::$is_user_export ? 'import_users' : $custom_type, 'status' => 'xpath', 'is_multiple_page_parent' => 'no', 'unique_key' => '', 'acf' => array(), 'fields' => array(), 'is_multiple_field_value' => array(), 'multiple_value' => array(), 'fields_delimiter' => array(), 'update_all_data' => 'no', 'is_update_status' => 0, 'is_update_title' => 0, 'is_update_author' => 0, 'is_update_slug' => 0, 'is_update_content' => 0, 'is_update_excerpt' => 0, 'is_update_dates' => 0, 'is_update_menu_order' => 0, 'is_update_parent' => 0, 'is_update_attachments' => 0, 'is_update_acf' => 0, 'update_acf_logic' => 'only', 'acf_list' => '', 'is_update_product_type' => 1, 'is_update_attributes' => 0, 'update_attributes_logic' => 'only', 'attributes_list' => '', 'is_update_images' => 0, 'is_update_custom_fields' => 0, 'update_custom_fields_logic' => 'only', 'custom_fields_list' => '', 'is_update_categories' => 0, 'update_categories_logic' => 'only', 'taxonomies_list' => '', 'export_id' => $this->id); if (in_array('product', $this->options['cpt'])) { $templateOptions['_virtual'] = 1; $templateOptions['_downloadable'] = 1; } if (XmlExportEngine::$is_user_export) { $templateOptions['is_update_first_name'] = 0; $templateOptions['is_update_last_name'] = 0; $templateOptions['is_update_role'] = 0; $templateOptions['is_update_nickname'] = 0; $templateOptions['is_update_description'] = 0; $templateOptions['is_update_login'] = 0; $templateOptions['is_update_password'] = 0; $templateOptions['is_update_nicename'] = 0; $templateOptions['is_update_email'] = 0; $templateOptions['is_update_registered'] = 0; $templateOptions['is_update_display_name'] = 0; $templateOptions['is_update_url'] = 0; } if ('xml' == $this->options['export_to']) { wp_all_export_prepare_template_xml($this->options, $templateOptions); } else { wp_all_export_prepare_template_csv($this->options, $templateOptions); } $options = $templateOptions + PMXI_Plugin::get_default_import_options(); if ($this->options['is_generate_templates']) { $template = new PMXI_Template_Record(); $tpl_data = array('name' => $this->options['template_name'], 'is_keep_linebreaks' => 0, 'is_leave_html' => 0, 'fix_characters' => 0, 'options' => $options); if (!empty($this->options['template_name'])) { // save template in database $template->getByName($this->options['template_name'])->set($tpl_data)->save(); } } if ($this->options['is_generate_import']) { $import = new PMXI_Import_Record(); $import->getById($this->options['import_id']); if (!$import->isEmpty() and $import->parent_import_id == 99999) { $xmlPath = $file_path; $root_element = ''; if ('csv' == $this->options['export_to']) { $options['delimiter'] = $this->options['delimiter']; include_once PMXI_Plugin::ROOT_DIR . '/libraries/XmlImportCsvParse.php'; $path_parts = pathinfo($xmlPath); $path_parts_arr = explode(DIRECTORY_SEPARATOR, $path_parts['dirname']); $target = $is_secure_import ? $wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXE_Plugin::UPLOADS_DIRECTORY . DIRECTORY_SEPARATOR . array_pop($path_parts_arr) : $wp_uploads['path']; $csv = new PMXI_CsvParser(array('filename' => $xmlPath, 'targetDir' => $target)); $xmlPath = $csv->xml_path; $root_element = 'node'; } else { $root_element = 'post'; } $import->set(array('xpath' => '/' . $root_element, 'type' => 'upload', 'options' => $options, 'root_element' => $root_element, 'path' => $xmlPath, 'name' => basename($xmlPath), 'imported' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'deleted' => 0, 'count' => $exportQuery->found_posts))->save(); $history_file = new PMXI_File_Record(); $history_file->set(array('name' => $import->name, 'import_id' => $import->id, 'path' => $xmlPath, 'registered_on' => date('Y-m-d H:i:s')))->save(); $exportOptions = $this->options; $exportOptions['import_id'] = $import->id; $this->set(array('options' => $exportOptions))->save(); } } } // update export file for remove access # 1 meg at a time, you can adjust this. $to_dirname = $wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXE_Plugin::CRON_DIRECTORY . DIRECTORY_SEPARATOR . md5(PMXE_Plugin::getInstance()->getOption('cron_job_key') . $this->id); if (!@is_dir($to_dirname)) { wp_mkdir_p($to_dirname); } if (!@file_exists($to_dirname . DIRECTORY_SEPARATOR . 'index.php')) { @touch($to_dirname . DIRECTORY_SEPARATOR . 'index.php'); } $to = $to_dirname . DIRECTORY_SEPARATOR . (!empty($this->friendly_name) ? sanitize_file_name($this->friendly_name) : 'feed') . '.' . $this->options['export_to']; $buffer_size = 1048576; $fin = @fopen($file_path, "rb"); $fout = @fopen($to, "w"); while (!@feof($fin)) { @fwrite($fout, @fread($fin, $buffer_size)); } @fclose($fin); @fclose($fout); if ($this->options['is_scheduled'] and "" != $this->options['scheduled_email']) { add_filter('wp_mail_content_type', array($this, 'set_html_content_type')); $headers = 'From: ' . get_bloginfo('name') . ' <' . get_bloginfo('admin_email') . '>' . "\r\n"; $message = '<p>Export ' . $this->options['friendly_name'] . ' has been completed. You can find exported file in attachments.</p>'; wp_mail($this->options['scheduled_email'], __("WP All Export", "pmxe_plugin"), $message, $headers, array($file_path)); remove_filter('wp_mail_content_type', array($this, 'set_html_content_type')); } } $this->set(array('processing' => 0, 'triggered' => 0, 'canceled' => 0, 'registered_on' => date('Y-m-d H:i:s')))->update(); } return $this; }
/** * AJAX action export processing */ function pmxe_wp_ajax_wpallexport() { if (!check_ajax_referer('wp_all_export_secure', 'security', false)) { exit(__('Security check', 'wp_all_export_plugin')); } if (!current_user_can('manage_options')) { exit(__('Security check', 'wp_all_export_plugin')); } $input = new PMXE_Input(); $export_id = $input->get('id', 0); if (empty($export_id)) { $export_id = !empty(PMXE_Plugin::$session->update_previous) ? PMXE_Plugin::$session->update_previous : 0; } $wp_uploads = wp_upload_dir(); $export = new PMXE_Export_Record(); $export->getById($export_id); if ($export->isEmpty()) { exit(__('Export is not defined.', 'wp_all_export_plugin')); } $exportOptions = $export->options + PMXE_Plugin::get_default_import_options(); wp_reset_postdata(); XmlExportEngine::$exportOptions = $exportOptions; XmlExportEngine::$is_user_export = $exportOptions['is_user_export']; XmlExportEngine::$exportID = $export_id; $posts_per_page = $exportOptions['records_per_iteration']; if ('advanced' == $exportOptions['export_type']) { if (XmlExportEngine::$is_user_export) { exit(json_encode(array('html' => __('Upgrade to the professional edition of WP All Export to export users.', 'wp_all_export_plugin')))); } else { $exportQuery = eval('return new WP_Query(array(' . $exportOptions['wp_query'] . ', \'offset\' => ' . $export->exported . ', \'posts_per_page\' => ' . $posts_per_page . ' ));'); } } else { XmlExportEngine::$post_types = $exportOptions['cpt']; if (!in_array('users', $exportOptions['cpt'])) { $exportQuery = new WP_Query(array('post_type' => $exportOptions['cpt'], 'post_status' => 'any', 'orderby' => 'ID', 'order' => 'ASC', 'offset' => $export->exported, 'posts_per_page' => $posts_per_page)); } else { exit(json_encode(array('html' => __('Upgrade to the professional edition of WP All Export to export users.', 'wp_all_export_plugin')))); } } XmlExportEngine::$exportQuery = $exportQuery; $foundPosts = !XmlExportEngine::$is_user_export ? $exportQuery->found_posts : $exportQuery->get_total(); $postCount = !XmlExportEngine::$is_user_export ? $exportQuery->post_count : count($exportQuery->get_results()); if (!$export->exported) { $attachment_list = $export->options['attachment_list']; if (!empty($attachment_list)) { foreach ($attachment_list as $attachment) { if (!is_numeric($attachment)) { @unlink($attachment); } } } $exportOptions['attachment_list'] = array(); $export->set(array('options' => $exportOptions))->save(); $is_secure_import = PMXE_Plugin::getInstance()->getOption('secure'); if ($is_secure_import and !empty($exportOptions['filepath'])) { // if 'Create a new file each time export is run' disabled remove all previously generated source files // if ( ! $exportOptions['creata_a_new_export_file'] or ! $export->iteration ){ // wp_all_export_remove_source(wp_all_export_get_absolute_path($exportOptions['filepath'])); // } $exportOptions['filepath'] = ''; } PMXE_Plugin::$session->set('count', $foundPosts); PMXE_Plugin::$session->save_data(); } // if posts still exists then export them if ($postCount) { switch ($exportOptions['export_to']) { case 'xml': pmxe_export_xml($exportQuery, $exportOptions); break; case 'csv': pmxe_export_csv($exportQuery, $exportOptions); break; default: # code... break; } wp_reset_postdata(); } if ($postCount) { $export->set(array('exported' => $export->exported + $postCount))->save(); } if ($posts_per_page != -1 and $postCount) { wp_send_json(array('exported' => $export->exported, 'percentage' => ceil($export->exported / $foundPosts * 100), 'done' => false, 'records_per_request' => $exportOptions['records_per_iteration'])); } else { wp_reset_postdata(); if (file_exists(PMXE_Plugin::$session->file)) { if ($exportOptions['export_to'] == 'xml') { file_put_contents(PMXE_Plugin::$session->file, '</' . $exportOptions['main_xml_tag'] . '>', FILE_APPEND); } $is_secure_import = PMXE_Plugin::getInstance()->getOption('secure'); if (!$is_secure_import) { if (!$export->isEmpty()) { $wp_filetype = wp_check_filetype(basename(PMXE_Plugin::$session->file), null); $attachment_data = array('guid' => $wp_uploads['baseurl'] . '/' . _wp_relative_upload_path(PMXE_Plugin::$session->file), 'post_mime_type' => $wp_filetype['type'], 'post_title' => preg_replace('/\\.[^.]+$/', '', basename(PMXE_Plugin::$session->file)), 'post_content' => '', 'post_status' => 'inherit'); if (empty($export->attch_id)) { $attach_id = wp_insert_attachment($attachment_data, PMXE_Plugin::$session->file); } elseif ($export->options['creata_a_new_export_file']) { $attach_id = wp_insert_attachment($attachment_data, PMXE_Plugin::$session->file); } else { $attach_id = $export->attch_id; $attachment = get_post($attach_id); if ($attachment) { update_attached_file($attach_id, PMXE_Plugin::$session->file); wp_update_attachment_metadata($attach_id, $attachment_data); } else { $attach_id = wp_insert_attachment($attachment_data, PMXE_Plugin::$session->file); } } if (!in_array($attach_id, $exportOptions['attachment_list'])) { $exportOptions['attachment_list'][] = $attach_id; } $export->set(array('attch_id' => $attach_id, 'options' => $exportOptions))->save(); } } else { $exportOptions['filepath'] = wp_all_export_get_relative_path(PMXE_Plugin::$session->file); if (!$export->isEmpty()) { $export->set(array('options' => $exportOptions))->save(); } } // Generate templa for WP All Import if ($exportOptions['is_generate_templates']) { $custom_type = empty($exportOptions['cpt']) ? 'post' : $exportOptions['cpt'][0]; $templateOptions = array('type' => (!empty($exportOptions['cpt']) and $exportOptions['cpt'][0] == 'page') ? 'page' : 'post', 'wizard_type' => 'new', 'deligate' => 'wpallexport', 'custom_type' => XmlExportEngine::$is_user_export ? 'import_users' : $custom_type, 'status' => 'xpath', 'is_multiple_page_parent' => 'no', 'unique_key' => '', 'acf' => array(), 'fields' => array(), 'is_multiple_field_value' => array(), 'multiple_value' => array(), 'fields_delimiter' => array(), 'update_all_data' => 'no', 'is_update_status' => 0, 'is_update_title' => 0, 'is_update_author' => 0, 'is_update_slug' => 0, 'is_update_content' => 0, 'is_update_excerpt' => 0, 'is_update_dates' => 0, 'is_update_menu_order' => 0, 'is_update_parent' => 0, 'is_update_attachments' => 0, 'is_update_acf' => 0, 'update_acf_logic' => 'only', 'acf_list' => '', 'is_update_product_type' => 1, 'is_update_attributes' => 0, 'update_attributes_logic' => 'only', 'attributes_list' => '', 'is_update_images' => 0, 'is_update_custom_fields' => 0, 'update_custom_fields_logic' => 'only', 'custom_fields_list' => '', 'is_update_categories' => 0, 'update_categories_logic' => 'only', 'taxonomies_list' => '', 'export_id' => $export->id); if (in_array('product', $exportOptions['cpt'])) { $templateOptions['_virtual'] = 1; $templateOptions['_downloadable'] = 1; $templateOptions['put_variation_image_to_gallery'] = 1; $templateOptions['disable_auto_sku_generation'] = 1; } if (XmlExportEngine::$is_user_export) { $templateOptions['is_update_first_name'] = 0; $templateOptions['is_update_last_name'] = 0; $templateOptions['is_update_role'] = 0; $templateOptions['is_update_nickname'] = 0; $templateOptions['is_update_description'] = 0; $templateOptions['is_update_login'] = 0; $templateOptions['is_update_password'] = 0; $templateOptions['is_update_nicename'] = 0; $templateOptions['is_update_email'] = 0; $templateOptions['is_update_registered'] = 0; $templateOptions['is_update_display_name'] = 0; $templateOptions['is_update_url'] = 0; } if ('xml' == $exportOptions['export_to']) { wp_all_export_prepare_template_xml($exportOptions, $templateOptions); } else { wp_all_export_prepare_template_csv($exportOptions, $templateOptions); } //$template = new PMXI_Template_Record(); $tpl_options = $templateOptions; if ('csv' == $exportOptions['export_to']) { $tpl_options['delimiter'] = $exportOptions['delimiter']; } $tpl_options['update_all_data'] = 'yes'; $tpl_options['is_update_status'] = 1; $tpl_options['is_update_title'] = 1; $tpl_options['is_update_author'] = 1; $tpl_options['is_update_slug'] = 1; $tpl_options['is_update_content'] = 1; $tpl_options['is_update_excerpt'] = 1; $tpl_options['is_update_dates'] = 1; $tpl_options['is_update_menu_order'] = 1; $tpl_options['is_update_parent'] = 1; $tpl_options['is_update_attachments'] = 1; $tpl_options['is_update_acf'] = 1; $tpl_options['update_acf_logic'] = 'full_update'; $tpl_options['acf_list'] = ''; $tpl_options['is_update_product_type'] = 1; $tpl_options['is_update_attributes'] = 1; $tpl_options['update_attributes_logic'] = 'full_update'; $tpl_options['attributes_list'] = ''; $tpl_options['is_update_images'] = 1; $tpl_options['is_update_custom_fields'] = 1; $tpl_options['update_custom_fields_logic'] = 'full_update'; $tpl_options['custom_fields_list'] = ''; $tpl_options['is_update_categories'] = 1; $tpl_options['update_categories_logic'] = 'full_update'; $tpl_options['taxonomies_list'] = ''; $tpl_data = array('name' => $exportOptions['template_name'], 'is_keep_linebreaks' => 0, 'is_leave_html' => 0, 'fix_characters' => 0, 'options' => $tpl_options); $exportOptions['tpl_data'] = $tpl_data; $export->set(array('options' => $exportOptions))->save(); // if ( ! empty($exportOptions['template_name'])) { // save template in database // $template->getByName($exportOptions['template_name'])->set($tpl_data)->save(); // } } // associate exported posts with new import if (wp_all_export_is_compatible() and $exportOptions['is_generate_import']) { $options = $templateOptions + PMXI_Plugin::get_default_import_options(); $import = new PMXI_Import_Record(); $import->getById($exportOptions['import_id']); if (!$import->isEmpty() and $import->parent_import_id == 99999) { $xmlPath = PMXE_Plugin::$session->file; $root_element = ''; $historyPath = PMXE_Plugin::$session->file; if ('csv' == $exportOptions['export_to']) { $options['delimiter'] = $exportOptions['delimiter']; include_once PMXI_Plugin::ROOT_DIR . '/libraries/XmlImportCsvParse.php'; $path_info = pathinfo($xmlPath); $path_parts = explode(DIRECTORY_SEPARATOR, $path_info['dirname']); $security_folder = array_pop($path_parts); $target = $is_secure_import ? $wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXE_Plugin::UPLOADS_DIRECTORY . DIRECTORY_SEPARATOR . $security_folder : $wp_uploads['path']; $csv = new PMXI_CsvParser(array('filename' => $xmlPath, 'targetDir' => $target)); if (!in_array($xmlPath, $exportOptions['attachment_list'])) { $exportOptions['attachment_list'][] = $csv->xml_path; } $historyPath = $csv->xml_path; $root_element = 'node'; } else { $root_element = 'post'; } $import->set(array('xpath' => '/' . $root_element, 'type' => 'upload', 'options' => $options, 'root_element' => $root_element, 'path' => $xmlPath, 'name' => basename($xmlPath), 'imported' => 0, 'created' => 0, 'updated' => 0, 'skipped' => 0, 'deleted' => 0, 'iteration' => 1, 'count' => PMXE_Plugin::$session->count))->save(); $history_file = new PMXI_File_Record(); $history_file->set(array('name' => $import->name, 'import_id' => $import->id, 'path' => $historyPath, 'registered_on' => date('Y-m-d H:i:s')))->save(); $exportOptions['import_id'] = $import->id; $export->set(array('options' => $exportOptions))->save(); } } } $export->set(array('executing' => 0, 'canceled' => 0))->save(); do_action('pmxe_after_export', $export->id); wp_send_json(array('exported' => $export->exported, 'percentage' => 100, 'done' => true, 'records_per_request' => $exportOptions['records_per_iteration'], 'file' => PMXE_Plugin::$session->file)); } }