public function merge() { /* Merge nested XML/CSV files */ if (!empty($this->nested_files)) { $tmp_files = array(); foreach ($this->nested_files as $key => $nfile) { $nested_fileURL = array_shift(XmlImportParser::factory($this->xml, $this->xpath, $nfile, $tmp_file)->parse()); $tmp_files[] = $tmp_file; if (!empty($nested_fileURL)) { $errors = new WP_Error(); $uploader = new PMXI_Upload($nested_fileURL, $errors); $upload_result = $uploader->url(); if ($upload_result instanceof WP_Error) { $errors = $upload_result; } else { $source = $upload_result['source']; $filePath = $upload_result['filePath']; if (!empty($upload_result['root_element'])) { $root_element = $upload_result['root_element']; } else { $root_element = ''; } $feed_type = $upload_result['feed_type']; } unset($uploader); $nested_xml = file_get_contents($filePath); if (!empty($nested_xml)) { PMXI_Import_Record::preprocessXml($nested_xml); if (PMXI_Import_Record::validateXml($nested_xml) === true) { $nestedDom = new DOMDocument('1.0', 'UTF-8'); $nestedold = libxml_use_internal_errors(true); $nestedDom->loadXML($nested_xml); libxml_use_internal_errors($nestedold); $second = $nestedDom->documentElement; if ($second->hasChildNodes()) { foreach ($second->childNodes as $node) { $importNode = $this->dom->importNode($node, true); $this->dom->documentElement->appendChild($importNode); } $this->xml = $this->elements ? $this->dom->saveXML($this->elements->item(0)) : $this->dom->saveXML(); } unset($nestedDom); } } } } foreach ($tmp_files as $tmp_file) { // remove all temporary files created @unlink($tmp_file); } } }
/** * Re-run import */ public function update() { $id = $this->input->get('id'); PMXI_Plugin::$session->clean_session($id); $action_type = false; $this->data['import'] = $item = new PMXI_Import_Record(); if (!$id or $item->getById($id)->isEmpty()) { wp_redirect($this->baseUrl); die; } $this->data['isWizard'] = false; $default = PMXI_Plugin::get_default_import_options(); $DefaultOptions = $item->options + $default; foreach (PMXI_Admin_Addons::get_active_addons() as $class) { if (class_exists($class)) { $DefaultOptions += call_user_func(array($class, "get_default_import_options")); } } $this->data['post'] =& $DefaultOptions; $this->data['source'] = array('path' => $item->path, 'root_element' => $item->root_element); $this->data['xpath'] = $item->xpath; $this->data['count'] = $item->count; $history = new PMXI_File_List(); $history->setColumns('id', 'name', 'registered_on', 'path')->getBy(array('import_id' => $item->id), 'id DESC'); if ($history->count()) { foreach ($history as $file) { if (@file_exists($file['path'])) { $this->data['locfilePath'] = $file['path']; break; } } } $chunks = 0; if ($this->input->post('is_confirmed') and check_admin_referer('confirm', '_wpnonce_confirm')) { $continue = $this->input->post('is_continue', 'no'); // mark action type ad continue if ($continue == 'yes') { $action_type = 'continue'; } $filePath = ''; // upload new file in case when import is not continue if (empty(PMXI_Plugin::$session->chunk_number)) { if ($item->type == 'upload') { // retrieve already uploaded file $uploader = new PMXI_Upload(trim($item->path), $this->errors, rtrim(str_replace(basename($item->path), '', $item->path), '/')); $upload_result = $uploader->upload(); if ($upload_result instanceof WP_Error) { $this->errors = $upload_result; } else { $filePath = $upload_result['filePath']; } } if (empty($item->options['encoding'])) { $currentOptions = $item->options; $currentOptions['encoding'] = 'UTF-8'; $item->set(array('options' => $currentOptions))->update(); } @set_time_limit(0); $local_paths = !empty($local_paths) ? $local_paths : array($filePath); foreach ($local_paths as $key => $path) { if (!empty($action_type) and $action_type == 'continue') { $chunks = $item->count; } else { $file = new PMXI_Chunk($path, array('element' => $item->root_element, 'encoding' => $item->options['encoding'])); while ($xml = $file->read()) { if (!empty($xml)) { PMXI_Import_Record::preprocessXml($xml); $xml = "<?xml version=\"1.0\" encoding=\"" . $item->options['encoding'] . "\"?>" . "\n" . $xml; $dom = new DOMDocument('1.0', !empty($item->options['encoding']) ? $item->options['encoding'] : 'UTF-8'); $old = libxml_use_internal_errors(true); $dom->loadXML($xml); // 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($item->xpath) and !empty($elements) and !empty($elements->length)) { $chunks += $elements->length; } unset($dom, $xpath, $elements); } } unset($file); } !$key and $filePath = $path; } if (empty($chunks)) { $this->errors->add('form-validation', __('No matching elements found for Root element and XPath expression specified', 'wp_all_import_plugin')); } } if ($chunks) { // xml is valid if (!PMXI_Plugin::is_ajax() and empty(PMXI_Plugin::$session->chunk_number)) { // compose data to look like result of wizard steps $sesson_data = array('filePath' => $filePath, 'source' => array('name' => $item->name, 'type' => $item->type, 'path' => $item->path, 'root_element' => $item->root_element), 'feed_type' => $item->feed_type, 'update_previous' => $item->id, 'parent_import_id' => $item->parent_import_id, 'xpath' => $item->xpath, 'options' => $item->options, 'encoding' => !empty($item->options['encoding']) ? $item->options['encoding'] : 'UTF-8', 'is_csv' => !empty($item->options['delimiter']) ? $item->options['delimiter'] : PMXI_Plugin::$is_csv, 'csv_path' => PMXI_Plugin::$csv_path, 'chunk_number' => 1, 'log' => '', 'warnings' => 0, 'errors' => 0, 'start_time' => 0, 'pointer' => 1, 'count' => isset($chunks) ? $chunks : 0, 'local_paths' => !empty($local_paths) ? $local_paths : array(), 'action' => (!empty($action_type) and $action_type == 'continue') ? 'continue' : 'update', 'nonce' => wp_create_nonce('import')); foreach ($sesson_data as $key => $value) { PMXI_Plugin::$session->set($key, $value); } PMXI_Plugin::$session->save_data(); } $item->set(array('canceled' => 0, 'failed' => 0))->update(); // deligate operation to other controller $controller = new PMXI_Admin_Import(); $controller->data['update_previous'] = $item; $controller->process(); return; } } $this->render('admin/import/confirm'); }
function pmxi_wp_ajax_upload_resource() { if (!check_ajax_referer('wp_all_import_secure', 'security', false)) { exit(json_encode(array('success' => false, 'errors' => '<div class="error inline"><p>' . __('Security check', 'wp_all_import_plugin') . '</p></div>'))); } if (!current_user_can('manage_options')) { exit(json_encode(array('success' => false, 'errors' => '<div class="error inline"><p>' . __('Security check', 'wp_all_import_plugin') . '</p></div>'))); } $input = new PMXI_Input(); $post = $input->post(array('type' => '', 'file' => '')); $response = array('success' => true, 'errors' => false, 'upload_result' => '', 'filesize' => 0); if ($post['type'] == 'url') { $filesXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<data><node></node></data>"; $files = XmlImportParser::factory($filesXML, '/data/node', $post['file'], $file)->parse(); $tmp_files[] = $file; foreach ($tmp_files as $tmp_file) { // remove all temporary files created @unlink($tmp_file); } $file_to_import = $post['file']; if (!empty($files) and is_array($files)) { $file_to_import = array_shift($files); } $errors = new WP_Error(); $uploader = new PMXI_Upload(trim($file_to_import), $errors); $upload_result = $uploader->url('', $post['file']); if ($upload_result instanceof WP_Error) { $errors = $upload_result; $msgs = $errors->get_error_messages(); ob_start(); ?> <?php foreach ($msgs as $msg) { ?> <div class="error inline"><p><?php echo $msg; ?> </p></div> <?php } ?> <?php $response = array('success' => false, 'errors' => ob_get_clean()); } else { // validate XML $file = new PMXI_Chunk($upload_result['filePath'], array('element' => $upload_result['root_element'])); $is_valid = true; if (!empty($file->options['element'])) { $defaultXpath = "/" . $file->options['element']; } else { $is_valid = false; } if ($is_valid) { while ($xml = $file->read()) { if (!empty($xml)) { PMXI_Import_Record::preprocessXml($xml); $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" . "\n" . $xml; $dom = new DOMDocument('1.0', 'UTF-8'); $old = libxml_use_internal_errors(true); $dom->loadXML($xml); libxml_use_internal_errors($old); $xpath = new DOMXPath($dom); if ($elements = $xpath->query($defaultXpath) and $elements->length) { break; } } /*else { $is_valid = false; break; }*/ } if (empty($xml)) { $is_valid = false; } } unset($file); if (!$is_valid) { ob_start(); ?> <div class="error inline"><p><?php _e('Please confirm you are importing a valid feed.<br/> Often, feed providers distribute feeds with invalid data, improperly wrapped HTML, line breaks where they should not be, faulty character encodings, syntax errors in the XML, and other issues.<br/><br/>WP All Import has checks in place to automatically fix some of the most common problems, but we can’t catch every single one.<br/><br/>It is also possible that there is a bug in WP All Import, and the problem is not with the feed.<br/><br/>If you need assistance, please contact support – <a href="mailto:support@wpallimport.com">support@wpallimport.com</a> – with your XML/CSV file. We will identify the problem and release a bug fix if necessary.', 'wp_all_import_plugin'); ?> </p></div> <?php $response = array('success' => false, 'errors' => ob_get_clean()); } else { $response['upload_result'] = $upload_result; $response['filesize'] = filesize($upload_result['filePath']); } } } exit(json_encode($response)); }
/** * Step #4: Options */ public function options() { $default = PMXI_Plugin::get_default_import_options(); if ($this->isWizard) { $this->data['source_type'] = PMXI_Plugin::$session->source['type']; $DefaultOptions = (isset(PMXI_Plugin::$session->options) ? PMXI_Plugin::$session->options : array()) + $default; foreach (PMXI_Admin_Addons::get_active_addons() as $class) { if (class_exists($class)) { $DefaultOptions += call_user_func(array($class, "get_default_import_options")); } } if (PMXI_Plugin::$session->options['custom_type'] != 'import_users') { if (empty(PMXI_Plugin::$session->options['title'])) { $this->warnings->add('form-validation', __('<strong>Warning:</strong> your title is blank.')); } if (empty(PMXI_Plugin::$session->options['content'])) { $this->warnings->add('form-validation', __('<strong>Warning:</strong> your content is blank.')); } } if (empty(PMXI_Plugin::$session->options['unique_key'])) { $keys_black_list = array('programurl'); if (empty(PMXI_Plugin::$session->deligate)) { $DefaultOptions['unique_key'] = PMXI_Plugin::$session->options['title']; } // auto searching ID element if (!empty($this->data['dom']) and empty(PMXI_Plugin::$session->deligate)) { $this->find_unique_key($this->data['dom']->documentElement); if (!empty($this->_unique_key)) { foreach ($keys_black_list as $key => $value) { $DefaultOptions['unique_key'] = str_replace('{' . $value . '[1]}', "", $DefaultOptions['unique_key']); } foreach ($this->_unique_key as $key) { if (stripos($key, 'id') !== false) { $DefaultOptions['unique_key'] .= ' - {' . $key . '[1]}'; break; } } foreach ($this->_unique_key as $key) { if (stripos($key, 'url') !== false or stripos($key, 'sku') !== false or stripos($key, 'ref') !== false) { if (!in_array($key, $keys_black_list)) { $DefaultOptions['unique_key'] .= ' - {' . $key . '[1]}'; break; } } } } $DefaultOptions['unique_key'] = apply_filters('pmxi_unique_key', $DefaultOptions['unique_key'], PMXI_Plugin::$session->options); } } else { $DefaultOptions['unique_key'] = PMXI_Plugin::$session->options['unique_key']; } if ($DefaultOptions['custom_type'] == "product" and class_exists('PMWI_Plugin') and $DefaultOptions['wizard_type'] != 'new') { $DefaultOptions['duplicate_indicator'] = 'custom field'; $DefaultOptions['custom_duplicate_name'] = '_sku'; } $post = $this->input->post($DefaultOptions); } else { $this->data['source_type'] = $this->data['import']->type; $DefaultOptions = is_array($this->data['import']->options) ? $this->data['import']->options + $default : $default; foreach (PMXI_Admin_Addons::get_active_addons() as $class) { if (class_exists($class)) { $DefaultOptions += call_user_func(array($class, "get_default_import_options")); } } $source = array('name' => $this->data['import']->name, 'type' => $this->data['import']->type, 'path' => wp_all_import_get_relative_path($this->data['import']->path), 'root_element' => $this->data['import']->root_element); PMXI_Plugin::$session->set('source', $source); $post = $this->input->post($DefaultOptions); } $this->data['post'] =& $post; PMXI_Plugin::$session->set('options', $post); if ($this->input->post('is_submitted')) { check_admin_referer('options', '_wpnonce_options'); if ($post['is_import_specified']) { if (empty($post['import_specified'])) { $this->errors->add('form-validation', __('Records to import must be specified or uncheck `Import only specified records` option to process all records', 'wp_all_import_plugin')); } else { $chanks = preg_split('% *, *%', $post['import_specified']); foreach ($chanks as $chank) { if (!preg_match('%^([1-9]\\d*)( *- *([1-9]\\d*))?$%', $chank, $mtch)) { $this->errors->add('form-validation', __('Wrong format of `Import only specified records` value', 'wp_all_import_plugin')); break; } elseif (isset($mtch[3]) and intval($mtch[3]) > PMXI_Plugin::$session->count) { $this->errors->add('form-validation', __('One of the numbers in `Import only specified records` value exceeds record quantity in XML file', 'wp_all_import_plugin')); break; } } } } if ('manual' != $post['duplicate_matching'] and '' == $post['unique_key']) { $this->errors->add('form-validation', __('Expression for `Post Unique Key` must be set, use the same expression as specified for post title if you are not sure what to put there', 'wp_all_import_plugin')); } elseif ('manual' != $post['duplicate_matching']) { $this->_validate_template($post['unique_key'], __('Post Unique Key', 'wp_all_import_plugin')); } if ('manual' == $post['duplicate_matching'] and 'custom field' == $post['duplicate_indicator']) { if ('' == $post['custom_duplicate_name']) { $this->errors->add('form-validation', __('Custom field name must be specified.', 'wp_all_import_plugin')); } if ('' == $post['custom_duplicate_value']) { $this->errors->add('form-validation', __('Custom field value must be specified.', 'wp_all_import_plugin')); } } // Categories/taxonomies logic if ($post['update_categories_logic'] == 'only' and !empty($post['taxonomies_only_list'])) { $post['taxonomies_list'] = explode(",", $post['taxonomies_only_list']); } elseif ($post['update_categories_logic'] == 'all_except' and !empty($post['taxonomies_except_list'])) { $post['taxonomies_list'] = explode(",", $post['taxonomies_except_list']); } // Custom fields logic if ($post['update_custom_fields_logic'] == 'only' and !empty($post['custom_fields_only_list'])) { $post['custom_fields_list'] = explode(",", $post['custom_fields_only_list']); } elseif ($post['update_custom_fields_logic'] == 'all_except' and !empty($post['custom_fields_except_list'])) { $post['custom_fields_list'] = explode(",", $post['custom_fields_except_list']); } $upload_result = false; if (!$this->isWizard) { // File Path validation switch ($this->input->post('new_type')) { case 'upload': $filePath = $this->input->post('filepath'); if ($this->data['import']['path'] != $filePath) { $uploader = new PMXI_Upload($filePath, $this->errors); $upload_result = $uploader->upload(); } break; case 'url': $filePath = $this->input->post('url'); if ($this->data['import']['path'] != $filePath) { $filesXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<data><node></node></data>"; $filePaths = XmlImportParser::factory($filesXML, '/data/node', $filePath, $file)->parse(); $tmp_files[] = $file; foreach ($tmp_files as $tmp_file) { // remove all temporary files created @unlink($tmp_file); } $file_to_import = $filePath; if (!empty($filePaths) and is_array($filePaths)) { $file_to_import = array_shift($filePaths); } $uploader = new PMXI_Upload($file_to_import, $this->errors); $upload_result = $uploader->url($this->data['import']->feed_type, $filePath); } break; case 'file': $filePath = $this->input->post('file'); if ($this->data['import']['path'] != $filePath) { $uploader = new PMXI_Upload($filePath, $this->errors); $upload_result = $uploader->file(); } break; default: $this->errors->add('form-validation', __('WP All Import doesn\'t support this import type.', 'wp_all_import_plugin')); break; } if ($upload_result instanceof WP_Error) { $this->errors = $upload_result; } elseif ($upload_result !== false and $this->data['import']['path'] != $filePath) { $file = new PMXI_Chunk($upload_result['filePath'], array('element' => !empty($this->data['import']->root_element) ? $this->data['import']->root_element : '')); $root_element = ''; if (!empty($file->options['element'])) { $root_element = $file->options['element']; $baseXpath = $this->data['import']->xpath; $loop = 0; // loop through the file until all lines are read while ($xml = $file->read()) { if (!empty($xml)) { PMXI_Import_Record::preprocessXml($xml); $xml = "<?xml version=\"1.0\" encoding=\"" . $this->data['import']['options']['encoding'] . "\"?>" . "\n" . $xml; $dom = new DOMDocument('1.0', $this->data['import']['options']['encoding']); $old = libxml_use_internal_errors(true); $dom->loadXML($xml); libxml_use_internal_errors($old); $xpath = new DOMXPath($dom); if ($elements = @$xpath->query($baseXpath) and $elements->length) { $loop += $elements->length; } unset($dom, $xpath, $elements); } } unset($file); if ((int) $loop === 0) { $this->warnings->add('form-validation', __('<strong>Warning:</strong> this file does not have the same structure as the last file associated with this import. WP All Import won\'t be able to import this file with your current settings. Probably you\'ll need to adjust your XPath in the "Configure Advanced Settings" box below, and reconfigure your import by clicking "Edit" on the Manage Imports page.', 'wp_all_import_plugin')); $file = new PMXI_Chunk($upload_result['filePath'], array('element' => !empty($upload_result['root_element']) ? $upload_result['root_element'] : '')); if (!empty($file->options['element'])) { $root_element = $file->options['element']; $baseXpath = '/' . $upload_result['root_element']; $loop = 0; // loop through the file until all lines are read while ($xml = $file->read()) { if (!empty($xml)) { PMXI_Import_Record::preprocessXml($xml); $xml = "<?xml version=\"1.0\" encoding=\"" . $this->data['import']['options']['encoding'] . "\"?>" . "\n" . $xml; $dom = new DOMDocument('1.0', $this->data['import']['options']['encoding']); $old = libxml_use_internal_errors(true); $dom->loadXML($xml); libxml_use_internal_errors($old); $xpath = new DOMXPath($dom); if ($elements = @$xpath->query($baseXpath) and $elements->length) { $loop += $elements->length; } unset($dom, $xpath, $elements); } } unset($file); if ($loop) { $this->data['import']->set(array('count' => $loop))->save(); } } } $upload_result['root_element'] = $root_element; $post['delimiter'] = !empty($upload_result['is_csv']) ? $upload_result['is_csv'] : ''; } else { $this->errors->add('form-validation', __('Root element not found for uploaded feed.', 'wp_all_import_plugin')); } } } $this->errors = apply_filters('pmxi_options_validation', $this->errors, $post, $this->data['import']); if (!$this->errors->get_error_codes()) { // no validation errors found // Attributes fields logic $post = apply_filters('pmxi_save_options', $post); if ($this->isWizard) { PMXI_Plugin::$session->set('options', $post); PMXI_Plugin::$session->save_data(); // update import template with final settings if (PMXI_Plugin::$session->saved_template) { $template = new PMXI_Template_Record(); $template->getById(PMXI_Plugin::$session->saved_template)->set(array('options' => $post))->save(); } if (!$this->input->post('save_only')) { wp_redirect(add_query_arg('action', 'confirm', $this->baseUrl)); die; } else { $import = $this->data['update_previous']; $is_update = !$import->isEmpty(); $import->set(PMXI_Plugin::$session->source + array('xpath' => PMXI_Plugin::$session->xpath, 'options' => PMXI_Plugin::$session->options, 'count' => PMXI_Plugin::$session->count, 'friendly_name' => $this->data['post']['friendly_name']))->save(); $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(); wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmxi_nt' => urlencode($is_update ? __('Import updated', 'wp_all_import_plugin') : __('Import created', 'wp_all_import_plugin'))), admin_url('admin.php'))); die; } } else { $xpath = $this->input->post('xpath'); $toUpdate = array('friendly_name' => $this->data['post']['friendly_name'], 'xpath' => $this->input->post('xpath'), 'settings_update_on' => date('Y-m-d H:i:s')); // detecting root element if ($xpath != $this->data['import']->xpath) { $xpath_elements = explode('[', $xpath); $xpath_parts = explode('/', $xpath_elements[0]); $toUpdate['root_element'] = $xpath_parts[1]; } $this->data['import']->set('options', $post)->set($toUpdate)->save(); // set new import file switch ($this->input->post('new_type')) { case 'upload': $filePath = $this->input->post('filepath'); $source = array('name' => basename($filePath), 'type' => 'upload', 'path' => $filePath); break; case 'url': $filePath = $this->input->post('url'); $source = array('name' => basename(parse_url($filePath, PHP_URL_PATH)), 'type' => 'url', 'path' => $filePath); break; case 'file': $wp_uploads = wp_upload_dir(); $filePath = $this->input->post('file'); $source = array('name' => basename($filePath), 'type' => 'file', 'path' => $wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::FILES_DIRECTORY . DIRECTORY_SEPARATOR . $filePath); break; /*case 'ftp': $ftp = $this->input->post('ftp'); $filePath = preg_replace('%://([^@/]*@)?%', '://' . rawurlencode($ftp['user']) . ':' . rawurlencode($ftp['pass']) . '@', $ftp['url'], 1); $source = array( 'name' => basename($filePath), 'type' => 'ftp', 'path' => $filePath, ); break;*/ } $source['path'] = wp_all_import_get_relative_path($source['path']); // if new file is successfully uploaded if (!empty($upload_result['filePath'])) { // unlink previous files $history = new PMXI_File_List(); $history->setColumns('id', 'name', 'registered_on', 'path')->getBy(array('import_id' => $this->data['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 != $upload_result['filePath']) { if (in_array($this->data['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 = new PMXI_File_Record(); $history_file->set(array('name' => $this->data['import']->name, 'import_id' => $this->data['import']->id, 'path' => wp_all_import_get_relative_path($upload_result['filePath']), 'registered_on' => date('Y-m-d H:i:s')))->save(); } if (!$this->warnings->get_error_codes()) { $this->data['import']->set($source)->save(); wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmxi_nt' => urlencode(__('Configuration updated', 'wp_all_import_plugin'))) + array_intersect_key($_GET, array_flip($this->baseUrlParamNames)), admin_url('admin.php'))); die; } else { $source['root_element'] = $upload_result['root_element']; PMXI_Plugin::$session->set('source', $source); $this->data['import']->set(array_merge($source, array('xpath' => '/' . $upload_result['root_element'])))->save(); } } } } PMXI_Plugin::$session->save_data(); $this->data['existing_meta_keys'] = array(); if (!in_array($post['custom_type'], array('import_users'))) { global $wpdb; // Get all meta keys for requested post type $hide_fields = array('_wp_page_template', '_edit_lock', '_edit_last', '_wp_trash_meta_status', '_wp_trash_meta_time'); $records = get_posts(array('post_type' => $post['custom_type'])); if (!empty($records)) { foreach ($records as $record) { $record_meta = get_post_meta($record->ID, ''); if (!empty($record_meta)) { foreach ($record_meta as $record_meta_key => $record_meta_value) { if (!in_array($record_meta_key, $this->data['existing_meta_keys']) and !in_array($record_meta_key, $hide_fields)) { $this->data['existing_meta_keys'][] = $record_meta_key; } } } } } // Get existing product attributes $existing_attributes = $wpdb->get_results("SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_product_attributes' LIMIT 0 , 50"); $this->data['existing_attributes'] = array(); if (!empty($existing_attributes)) { foreach ($existing_attributes as $key => $existing_attribute) { $existing_attribute = maybe_unserialize($existing_attribute->meta_value); if (!empty($existing_attribute) and is_array($existing_attribute)) { foreach ($existing_attribute as $key => $value) { if (strpos($key, "pa_") === false and !in_array($key, $this->data['existing_attributes'])) { $this->data['existing_attributes'][] = $key; } } } } } } $this->render(); }
/** * upload.php * * Copyright 2009, Moxiecode Systems AB * Released under GPL License. * * License: http://www.plupload.com/license * Contributing: http://www.plupload.com/contributing */ public function upload() { if (!check_ajax_referer('wp_all_import_secure', '_wpnonce', false)) { exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 100, "message" => __('Security check', 'wp_all_import_plugin')), "id" => "id"))); } // 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"); // Settings //$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload"; //$uploads = wp_upload_dir(); $targetDir = self::$path; if (!is_dir($targetDir) || !is_writable($targetDir)) { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 100, "message" => __("Uploads folder is not writable.", "wp_all_import_plugin")), "id" => "id"))); } $cleanupTargetDir = true; // Remove old files $maxFileAge = 5 * 3600; // Temp file age in seconds // 5 minutes execution time @set_time_limit(5 * 60); // Uncomment this one to fake upload time // usleep(5000); // Get parameters $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0; $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0; $fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : ''; // Clean the fileName for security reasons $fileName = preg_replace('/[^\\w\\._]+/', '_', $fileName); if (!preg_match('%\\W(xml|gzip|zip|csv|gz|json|txt|dat|psv|sql|xls|xlsx)$%i', trim(basename($fileName)))) { exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 100, "message" => __("Uploaded file must be XML, CSV, ZIP, GZIP, GZ, JSON, SQL, TXT, DAT or PSV", "wp_all_import_plugin")), "id" => "id"))); } // Make sure the fileName is unique but only if chunking is disabled if ($chunks < 2 && file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName)) { $ext = strrpos($fileName, '.'); $fileName_a = substr($fileName, 0, $ext); $fileName_b = substr($fileName, $ext); $count = 1; while (file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b)) { $count++; } $fileName = $fileName_a . '_' . $count . $fileName_b; } $filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName; // Create target dir if (!file_exists($targetDir)) { @mkdir($targetDir); } // Remove old temp files if ($cleanupTargetDir && is_dir($targetDir) && ($dir = opendir($targetDir))) { while (($file = readdir($dir)) !== false) { $tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file; // Remove temp file if it is older than the max age and is not the current file if (preg_match('/\\.part$/', $file) && filemtime($tmpfilePath) < time() - $maxFileAge && $tmpfilePath != "{$filePath}.part") { @unlink($tmpfilePath); } } closedir($dir); } else { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 100, "message" => __("Failed to open temp directory.", "wp_all_import_plugin")), "id" => "id"))); } // Look for the content type header if (isset($_SERVER["HTTP_CONTENT_TYPE"])) { $contentType = $_SERVER["HTTP_CONTENT_TYPE"]; } if (isset($_SERVER["CONTENT_TYPE"])) { $contentType = $_SERVER["CONTENT_TYPE"]; } // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5 if (strpos($contentType, "multipart") !== false) { if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) { // Open temp file $out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab"); if ($out) { // Read binary input stream and append it to temp file $in = fopen($_FILES['file']['tmp_name'], "rb"); if ($in) { while ($buff = fread($in, 4096)) { fwrite($out, $buff); } } else { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 101, "message" => __("Failed to open input stream.", "wp_all_import_plugin")), "id" => "id"))); } fclose($in); fclose($out); @unlink($_FILES['file']['tmp_name']); } else { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 102, "message" => __("Failed to open output stream.", "wp_all_import_plugin")), "id" => "id"))); } } else { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 103, "message" => __("Failed to move uploaded file.", "wp_all_import_plugin")), "id" => "id"))); } } else { // Open temp file $out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab"); if ($out) { // Read binary input stream and append it to temp file $in = fopen("php://input", "rb"); if ($in) { while ($buff = fread($in, 4096)) { fwrite($out, $buff); } } else { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 101, "message" => __("Failed to open input stream.", "wp_all_import_plugin")), "id" => "id"))); } fclose($in); fclose($out); } else { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 102, "message" => __("Failed to open output stream.", "wp_all_import_plugin")), "id" => "id"))); } } $post_type = false; // Check if file has been uploaded if (!$chunks || $chunk == $chunks - 1) { // Strip the temp .part suffix off rename("{$filePath}.part", $filePath); chmod($filePath, 0755); delete_transient(self::$upload_transient); $errors = new WP_Error(); $uploader = new PMXI_Upload($filePath, $errors, rtrim(str_replace(basename($filePath), '', $filePath), '/')); $upload_result = $uploader->upload(); if ($upload_result instanceof WP_Error) { $errors = $upload_result; $msgs = $errors->get_error_messages(); ob_start(); ?> <?php foreach ($msgs as $msg) { ?> <div class="error inline"><p><?php echo $msg; ?> </p></div> <?php } ?> <?php $response = ob_get_clean(); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 102, "message" => $response), "id" => "id"))); } else { // validate XML $file = new PMXI_Chunk($upload_result['filePath'], array('element' => $upload_result['root_element'])); $is_valid = true; if (!empty($file->options['element'])) { $defaultXpath = "/" . $file->options['element']; } else { $is_valid = false; } if ($is_valid) { while ($xml = $file->read()) { if (!empty($xml)) { PMXI_Import_Record::preprocessXml($xml); $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" . "\n" . $xml; $dom = new DOMDocument('1.0', 'UTF-8'); $old = libxml_use_internal_errors(true); $dom->loadXML($xml); libxml_use_internal_errors($old); $xpath = new DOMXPath($dom); if ($elements = $xpath->query($defaultXpath) and $elements->length) { break; } } /*else { $is_valid = false; break; }*/ } if (empty($xml)) { $is_valid = false; } } unset($file); if (!preg_match('%\\W(xml)$%i', trim($upload_result['source']['path']))) { @unlink($upload_result['filePath']); } if (!$is_valid) { ob_start(); ?> <div class="error inline"><p><?php _e('Please confirm you are importing a valid feed.<br/> Often, feed providers distribute feeds with invalid data, improperly wrapped HTML, line breaks where they should not be, faulty character encodings, syntax errors in the XML, and other issues.<br/><br/>WP All Import has checks in place to automatically fix some of the most common problems, but we can’t catch every single one.<br/><br/>It is also possible that there is a bug in WP All Import, and the problem is not with the feed.<br/><br/>If you need assistance, please contact support – <a href="mailto:support@wpallimport.com">support@wpallimport.com</a> – with your XML/CSV file. We will identify the problem and release a bug fix if necessary.', 'wp_all_import_plugin'); ?> </p></div> <?php $response = ob_get_clean(); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 102, "message" => $response), "id" => "id"))); } else { $wp_uploads = wp_upload_dir(); $uploads = $wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::FILES_DIRECTORY . DIRECTORY_SEPARATOR; if (!file_exists($uploads . basename($filePath))) { @copy($filePath, $uploads . basename($filePath)); } } if (!empty($upload_result['post_type'])) { $post_type = $upload_result['post_type']; } } } // Return JSON-RPC response exit(json_encode(array("jsonrpc" => "2.0", "error" => null, "result" => null, "id" => "id", "name" => $filePath, "post_type" => $post_type))); }
/** * * Ajax action that will parse nested XML/CSV files * */ function pmxi_wp_ajax_parse_nested_file() { extract($_POST); $result = array(); $wp_uploads = wp_upload_dir(); if (!empty($_POST['nested_type'])) { $root_element = ''; $feed_type = ''; $errors = new WP_Error(); switch ($_POST['nested_type']) { case 'upload': $uploader = new PMXI_Upload($_POST['nested_filepath'], $errors); $upload_result = $uploader->upload(); if ($upload_result instanceof WP_Error) { $errors = $upload_result; } else { $source = $upload_result['source']; $filePath = $upload_result['filePath']; if (!empty($upload_result['root_element'])) { $root_element = $upload_result['root_element']; } } break; case 'url': $uploader = new PMXI_Upload($_POST['nested_url'], $errors); $upload_result = $uploader->url(); if ($upload_result instanceof WP_Error) { $errors = $upload_result; } else { $source = $upload_result['source']; $filePath = $upload_result['filePath']; if (!empty($upload_result['root_element'])) { $root_element = $upload_result['root_element']; } $feed_type = $upload_result['feed_type']; } break; case 'file': $uploader = new PMXI_Upload($_POST['nested_file'], $errors); $upload_result = $uploader->file(); if ($upload_result instanceof WP_Error) { $errors = $upload_result; } else { $source = $upload_result['source']; $filePath = $upload_result['filePath']; if (!empty($upload_result['root_element'])) { $root_element = $upload_result['root_element']; } } break; } } if ($errors->get_error_codes()) { $msgs = $errors->get_error_messages(); ob_start(); ?> <?php foreach ($msgs as $msg) { ?> <div class="error"><p><?php echo $msg; ?> </p></div> <?php } ?> <?php exit(json_encode(array('success' => false, 'errors' => ob_get_clean()))); die; } else { $xml_tree = ''; if (@file_exists($filePath)) { $file = new PMXI_Chunk($filePath, array('element' => $root_element)); if (!empty($file->options['element'])) { $customXpath = "/" . $file->options['element']; $elements_cloud = $file->cloud; } $root_element = $file->options['element']; $file = new PMXI_Chunk($filePath, array('element' => $root_element, 'encoding' => 'UTF-8')); $tagno = 0; $loop = 0; $count = 0; while ($xml = $file->read()) { if (!empty($xml)) { PMXI_Import_Record::preprocessXml($xml); $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" . "\n" . $xml; if ('' != $customXpath) { $dom = new DOMDocument('1.0', 'UTF-8'); $old = libxml_use_internal_errors(true); $dom->loadXML($xml); libxml_use_internal_errors($old); $xpath = new DOMXPath($dom); if ($elements = $xpath->query($customXpath) and $elements->length) { $loop++; $count += $elements->length; if (!$tagno or $loop == $tagno) { ob_start(); PMXI_Render::render_xml_element($elements->item(0), true); $xml_tree = ob_get_clean(); $tagno = 1; } } } else { break; } } } unset($file); } exit(json_encode(array('success' => true, 'source' => $source, 'realpath' => $source['path'], 'filePath' => $filePath, 'root_element' => $root_element, 'xml_tree' => $xml_tree, 'xpath' => $customXpath, 'count' => $count ? sprintf("<p class='green pmxi_counter'>" . __('Elements founded', 'pmxi_pligun') . " <strong>%s</strong></p>", $count) : "<p class='red pmxi_counter'>" . __('Elements not found', 'pmxi_pligun') . "</p>"))); die; } }
/** * 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; }
/** * upload.php * * Copyright 2009, Moxiecode Systems AB * Released under GPL License. * * License: http://www.plupload.com/license * Contributing: http://www.plupload.com/contributing */ public function upload() { if (!check_ajax_referer('wp_all_import_secure', '_wpnonce', false)) { exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 100, "message" => __('Security check', 'wp_all_import_plugin')), "id" => "id"))); } // 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"); // Settings //$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload"; //$uploads = wp_upload_dir(); $targetDir = self::$path; if (!is_dir($targetDir) || !is_writable($targetDir)) { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 100, "message" => __("Uploads folder is not writable.", "wp_all_import_plugin")), "id" => "id"))); } $cleanupTargetDir = true; // Remove old files $maxFileAge = 5 * 3600; // Temp file age in seconds // 5 minutes execution time @set_time_limit(5 * 60); // Uncomment this one to fake upload time // usleep(5000); // Get parameters $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0; $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0; $fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : ''; // Clean the fileName for security reasons $fileName = preg_replace('/[^\\w\\._]+/', '_', $fileName); if (!preg_match('%\\W(xml|gzip|zip|csv|gz|json|txt|dat|psv|sql|xls|xlsx)$%i', trim(basename($fileName)))) { exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 100, "message" => __("Uploaded file must be XML, CSV, ZIP, GZIP, GZ, JSON, SQL, TXT, DAT or PSV", "wp_all_import_plugin")), "id" => "id"))); } // Make sure the fileName is unique but only if chunking is disabled if ($chunks < 2 && file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName)) { $ext = strrpos($fileName, '.'); $fileName_a = substr($fileName, 0, $ext); $fileName_b = substr($fileName, $ext); $count = 1; while (file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b)) { $count++; } $fileName = $fileName_a . '_' . $count . $fileName_b; } $filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName; // Create target dir if (!file_exists($targetDir)) { @mkdir($targetDir); } // Remove old temp files if ($cleanupTargetDir && is_dir($targetDir) && ($dir = opendir($targetDir))) { while (($file = readdir($dir)) !== false) { $tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file; // Remove temp file if it is older than the max age and is not the current file if (preg_match('/\\.part$/', $file) && filemtime($tmpfilePath) < time() - $maxFileAge && $tmpfilePath != "{$filePath}.part") { @unlink($tmpfilePath); } } closedir($dir); } else { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 100, "message" => __("Failed to open temp directory.", "wp_all_import_plugin")), "id" => "id"))); } // Look for the content type header if (isset($_SERVER["HTTP_CONTENT_TYPE"])) { $contentType = $_SERVER["HTTP_CONTENT_TYPE"]; } if (isset($_SERVER["CONTENT_TYPE"])) { $contentType = $_SERVER["CONTENT_TYPE"]; } // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5 if (strpos($contentType, "multipart") !== false) { if (isset($_FILES['async-upload']['tmp_name']) && is_uploaded_file($_FILES['async-upload']['tmp_name'])) { // Open temp file $out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab"); if ($out) { // Read binary input stream and append it to temp file $in = fopen($_FILES['async-upload']['tmp_name'], "rb"); if ($in) { while ($buff = fread($in, 4096)) { fwrite($out, $buff); } } else { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 101, "message" => __("Failed to open input stream.", "wp_all_import_plugin")), "id" => "id"))); } fclose($in); fclose($out); @unlink($_FILES['async-upload']['tmp_name']); } else { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 102, "message" => __("Failed to open output stream.", "wp_all_import_plugin")), "id" => "id"))); } } else { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 103, "message" => __("Failed to move uploaded file.", "wp_all_import_plugin")), "id" => "id"))); } } else { // Open temp file $out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab"); if ($out) { // Read binary input stream and append it to temp file $in = fopen("php://input", "rb"); if ($in) { while ($buff = fread($in, 4096)) { fwrite($out, $buff); } } else { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 101, "message" => __("Failed to open input stream.", "wp_all_import_plugin")), "id" => "id"))); } fclose($in); fclose($out); } else { delete_transient(self::$upload_transient); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 102, "message" => __("Failed to open output stream.", "wp_all_import_plugin")), "id" => "id"))); } } $post_type = false; $notice = false; $warning = false; // Check if file has been uploaded if (!$chunks || $chunk == $chunks - 1) { // Strip the temp .part suffix off rename("{$filePath}.part", $filePath); chmod($filePath, 0755); delete_transient(self::$upload_transient); $errors = new WP_Error(); $uploader = new PMXI_Upload($filePath, $errors, rtrim(str_replace(basename($filePath), '', $filePath), '/')); $upload_result = $uploader->upload(); if ($upload_result instanceof WP_Error) { $errors = $upload_result; $msgs = $errors->get_error_messages(); ob_start(); ?> <?php foreach ($msgs as $msg) { ?> <p><?php echo $msg; ?> </p> <?php } ?> <?php $response = ob_get_clean(); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 102, "message" => $response), "id" => "id"))); } else { if (!empty($upload_result['post_type'])) { $post_type = $upload_result['post_type']; if (!empty($upload_result['template'])) { $template = json_decode($upload_result['template'], true); if (!empty($template[0]['options'])) { $is_show_cf_notice = !empty($template[0]['options']['custom_name']) ? true : false; $is_show_images_notice = false; if ($post_type != 'product' && ($template[0]['options']['download_featured_image'] != '' || $template[0]['options']['gallery_featured_image'] != '' || $template[0]['options']['featured_image'] != '')) { $is_show_images_notice = true; } if ($is_show_cf_notice && $is_show_images_notice) { $warning = __('<a class="upgrade_link" target="_blank" href="http://www.wpallimport.com/upgrade-to-pro/?utm_source=free-plugin&utm_medium=in-plugin&utm_campaign=custom-fields">Upgrade to the Pro edition of WP All Import to import images and custom fields.</a> <p>If you already own it, remove the free edition and install the Pro edition.</p>', 'wp_all_import_plugin'); } else { if ($is_show_cf_notice) { $warning = __('<a class="upgrade_link" target="_blank" href="http://www.wpallimport.com/upgrade-to-pro/?utm_source=free-plugin&utm_medium=in-plugin&utm_campaign=custom-fields">Upgrade to the Pro edition of WP All Import to import custom fields.</a> <p>If you already own it, remove the free edition and install the Pro edition.</p>', 'wp_all_import_plugin'); } else { if ($is_show_images_notice) { $warning = __('<a class="upgrade_link" target="_blank" href="http://www.wpallimport.com/upgrade-to-pro/?utm_source=free-plugin&utm_medium=in-plugin&utm_campaign=custom-fields">Upgrade to the Pro edition of WP All Import to import images.</a> <p>If you already own it, remove the free edition and install the Pro edition.</p>', 'wp_all_import_plugin'); } } } } } switch ($post_type) { case 'product': case 'shop_order': if (!class_exists('WooCommerce')) { $notice = __('<p class="wpallimport-bundle-notice">The import bundle you are using requires WooCommerce.</p><a class="upgrade_link" href="https://wordpress.org/plugins/woocommerce/" target="_blank">Get WooCommerce</a>.', 'wp_all_import_plugin'); } else { if (!defined('PMWI_EDITION')) { $notice = __('<p class="wpallimport-bundle-notice">The import bundle you are using requires the Pro version of the WooCommerce Add-On.</p><a href="http://www.wpallimport.com/checkout/?edd_action=add_to_cart&download_id=1529&edd_options%5Bprice_id%5D=1" class="upgrade_link" target="_blank">Purchase the WooCommerce Add-On</a>.', 'wp_all_import_plugin'); } elseif (PMWI_EDITION != 'paid') { $notice = __('<p class="wpallimport-bundle-notice">The import bundle you are using requires the Pro version of the WooCommerce Add-On, but you have the free version installed.</p><a href="http://www.wpallimport.com/checkout/?edd_action=add_to_cart&download_id=1529&edd_options%5Bprice_id%5D=1" target="_blank" class="upgrade_link">Purchase the WooCommerce Add-On</a>.', 'wp_all_import_plugin'); } } break; case 'import_users': if (!class_exists('PMUI_Plugin')) { $notice = __('<p class="wpallimport-bundle-notice">The import bundle you are using requires the User Import Add-On.</p><a href="http://www.wpallimport.com/checkout/?edd_action=add_to_cart&download_id=1921&edd_options%5Bprice_id%5D=1" target="_blank" class="upgrade_link">Purchase the User Import Add-On</a>.', 'wp_all_import_plugin'); } break; default: # code... break; } } if (!empty($upload_result['is_empty_bundle_file'])) { // Return JSON-RPC response exit(json_encode(array("jsonrpc" => "2.0", "error" => null, "result" => null, "id" => "id", "name" => $upload_result['filePath'], "post_type" => $post_type, "notice" => $notice, "template" => $upload_result['template'], "url_bundle" => true))); } else { // $root_element = wp_all_import_get_reader_engine( array($upload_result['filePath']), array('root_element' => $upload_result['root_element']) ); // if ( ! empty($root_element) and empty($upload_result['root_element'])) // { // $upload_result['root_element'] = $root_element; // } // validate XML $file = new PMXI_Chunk($upload_result['filePath'], array('element' => $upload_result['root_element'])); $is_valid = true; if (!empty($file->options['element'])) { $defaultXpath = "/" . $file->options['element']; } else { $is_valid = false; } if ($is_valid) { while ($xml = $file->read()) { if (!empty($xml)) { //PMXI_Import_Record::preprocessXml($xml); $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" . "\n" . $xml; $dom = new DOMDocument('1.0', 'UTF-8'); $old = libxml_use_internal_errors(true); $dom->loadXML($xml); libxml_use_internal_errors($old); $xpath = new DOMXPath($dom); if ($elements = $xpath->query($defaultXpath) and $elements->length) { break; } } /*else { $is_valid = false; break; }*/ } if (empty($xml)) { $is_valid = false; } } unset($file); if (!preg_match('%\\W(xml)$%i', trim($upload_result['source']['path']))) { @unlink($upload_result['filePath']); } if (!$is_valid) { ob_start(); ?> <div class="error inline"><p><?php _e('Please confirm you are importing a valid feed.<br/> Often, feed providers distribute feeds with invalid data, improperly wrapped HTML, line breaks where they should not be, faulty character encodings, syntax errors in the XML, and other issues.<br/><br/>WP All Import has checks in place to automatically fix some of the most common problems, but we can’t catch every single one.<br/><br/>It is also possible that there is a bug in WP All Import, and the problem is not with the feed.<br/><br/>If you need assistance, please contact support – <a href="mailto:support@wpallimport.com">support@wpallimport.com</a> – with your XML/CSV file. We will identify the problem and release a bug fix if necessary.', 'wp_all_import_plugin'); ?> </p></div> <?php $response = ob_get_clean(); $file_type = strtoupper(pmxi_getExtension($upload_result['source']['path'])); $error_message = sprintf(__("Please verify that the file you uploading is a valid %s file.", "wp_all_import_plugin"), $file_type); exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 102, "message" => $error_message), "is_valid" => false, "id" => "id"))); } else { $wp_uploads = wp_upload_dir(); $uploads = $wp_uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::FILES_DIRECTORY . DIRECTORY_SEPARATOR; if (!file_exists($uploads . basename($filePath))) { @copy($filePath, $uploads . basename($filePath)); } } } } } // Return JSON-RPC response exit(json_encode(array("jsonrpc" => "2.0", "error" => null, "result" => null, "id" => "id", "name" => $filePath, "post_type" => $post_type, "notice" => $notice, "warning" => $warning))); }