* @copyright 2015 PrestaShow.pl * @license http://PrestaShow.pl/license */ class PShow_Import { public $id_shop; public $filepath; public $filename; protected $import_status; protected $lang; protected $langs; public static $file_config; public static $file_path; public static $imported_ref = false; public static $imported_id = false; public static $objects_instances = array(); public static $objects = array(); public static $objects_ = array(); public static $LOG = array(); protected static $instance = null; public $maintenance_mode_enabled = false; public static $shopsToImport = array(); /** @var int */ public $current_row_number; public function isSomethingToImport() { if (!file_exists(_IMPORT_STATUS_PATH_ . "actual_row")) { return false; } $rowsCount = PShow_Config::get('rowsCount'); $actualRow = (int) PShow_File::file_get_contents(_IMPORT_STATUS_PATH_ . "actual_row"); return (($rowsCount - $actualRow) > 0); } public static function debug_backtrace($limit) { if (version_compare(PHP_VERSION, '5.4.0') >= 0) { return debug_backtrace(0, $limit); } return debug_backtrace(); } public static function getInstanceOfRunningImport() { if (self::$instance) { return self::$instance; } $path = _IMPORT_STATUS_PATH_ . "filename"; $filename = (file_exists($path) ? file_get_contents($path) : false); if (!$filename) { return false; } return PShow_Import::getInstance($filename); } /** * Get singleton instance * * @param string|null $fileToImport * @return boolean|PShow_Import */ public static function getInstance($fileToImport = null) { if (self::$instance === null || $fileToImport !== null) { if ($fileToImport === null || !count(glob(_MODULE_UPLOAD_PATH_ . $fileToImport . '*'))) { return false; } self::$instance = new PShow_Import(); self::$instance->init($fileToImport); } return self::$instance; } /** * Refresh import status */ public function refreshStatus() { $this->status = array( "actual_row" => (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "actual_row"), "counter_imported_rows" => (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "counter_imported_rows"), "counter_error_rows" => (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "counter_error_rows"), "counter_skipped_rows" => (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "counter_skipped_rows"), ); } /** * Prepare import * * @param string $fileToImport */ public function prepareImport($fileToImport) { $this->clearStatus(); $this->filename = $fileToImport; $this->filepath = $this->getFilePathByFileName($this->filename); $this->refreshConfig(); file_put_contents(_IMPORT_STATUS_PATH_ . "actual_row", 0); file_put_contents(_IMPORT_STATUS_PATH_ . "error_rows", ""); file_put_contents(_IMPORT_STATUS_PATH_ . "filename", $fileToImport); file_put_contents(_IMPORT_STATUS_PATH_ . "counter_imported_rows", "0"); file_put_contents(_IMPORT_STATUS_PATH_ . "counter_error_rows", "0"); file_put_contents(_IMPORT_STATUS_PATH_ . "counter_skipped_rows", "0"); file_put_contents(_IMPORT_STATUS_PATH_ . "imported_references", ""); file_put_contents(_IMPORT_STATUS_PATH_ . "imported_ids", ""); file_put_contents(_IMPORT_STATUS_PATH_ . "cached_from_file", "0"); file_put_contents(_IMPORT_CONFIG_PATH_ . $fileToImport . '/lastimport', time()); if (PShow_Config::isChecked('updateWithDownload')) { $url = PShow_File::file_get_contents(str_replace(pathinfo($this->filepath, PATHINFO_EXTENSION), "txt", $this->filepath)); PShow_File::updateFileFromURL($this->filepath, $url); } // count rows count $parser = PShow_Xml_Parser::getInstance($this->filepath); $this->config[0]['rowsCount'] = $parser->countElementsByPath($this->config[1]['objectTag']); PShow_Config::saveFileConfig($this->filename, array('primary' => $this->config[0])); PShow_Log::add(_IMPORT_LOG_PATH_ . $this->filename . ".log", PShow_Log::IMPORT_START); } public function clearStatus() { array_map("unlink", glob(_IMPORT_STATUS_PATH_ . "*")); if (file_exists(getModulePath(__FILE__) . "direct_import_now")) { unlink(getModulePath(__FILE__) . "direct_import_now"); } } public function getFilePathByFileName($filename) { $filepath = _MODULE_UPLOAD_PATH_ . $filename . '.xml'; if (!file_exists($filepath)) { throw new PrestaShopException("File to import not found: " . _MODULE_UPLOAD_PATH_ . $filename . ".*"); } return $filepath; } public function refreshConfig() { $config = PShow_Config::getFileConfig($this->filename); $this->config = array( $config['primary'], $config['matched'], (array_key_exists('matched_categories', $config) ? $config['matched_categories'] : false), (array_key_exists('skipped_manufacturers', $config) ? $config['skipped_manufacturers'] : false), 'file' => (array_key_exists('file', $config) ? $config['file'] : false), ); if (!array_key_exists('firstLine', $this->config[0])) { $this->config[0]['firstLine'] = 1; } } public function init($fileToImport = null) { // check is import prepared if (!file_exists(_IMPORT_STATUS_PATH_ . 'filename')) { // prepare new import if ($fileToImport !== null) { $this->prepareImport($fileToImport); } else { throw new PrestaShopException("Import not started"); } } // find file path $this->filename = file_get_contents(_IMPORT_STATUS_PATH_ . 'filename'); $this->filepath = $this->getFilePathByFileName($this->filename); // get config $this->refreshConfig(); // get status $this->refreshStatus(); $this->fileext = Tools::strtolower(pathinfo($this->filepath, PATHINFO_EXTENSION)); $lang = (int) $this->config[0]['lang']; $this->matched_categories = (isset($this->config[2]) ? $this->config[2] : array()); if ($lang == 0) { $this->langs = Language::getLanguages(true); } else { $this->langs = array(array('id_lang' => $lang)); } if (array_key_exists('unique_data', $this->config[0]) && $this->config[0]['unique_data'] == 'reference') { $imported = Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "imported_references"); self::$imported_ref = (!empty($imported)) ? explode(';', $imported) : array(); } if (array_key_exists('unique_data', $this->config[0]) && $this->config[0]['unique_data'] == 'id') { $imported = Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "imported_ids"); self::$imported_id = (!empty($imported)) ? explode(';', $imported) : array(); } $this->context = Context::getContext(); require_once _MODULE_CLASS_PATH_ . 'PShow_' . ucfirst($this->fileext) . '.php'; } public function getFileRow($row) { PShow_Log::addImportLog("get next file row/object"); $classname = 'PShow_' . ucfirst($this->fileext); return $classname::getRows($this->filepath, $this->config, $row, 1); } public function getNextFileRow() { return $this->getFileRow(( $this->status["actual_row"] + 1)); } /** * Create categories from path * eg.: category1/category2/category3 * * @param string $value_ * @param string $separator * @return \Category */ public function createCategoriesFromPath($value_, $separator) { $value = str_replace(' / ', '|slash|', implode($separator, $value_)); $path = explode($separator, $value); PShow_Log::addImportLog("create categories from path"); $parent_id = 2; $level_depth = 2; foreach ($path as $value) { $category = false; $value = str_replace('|slash|', ' / ', $value); $value = strip_tags($value); if (empty($value)) { continue; } $lang_tmp = $this->langs; if (is_array($lang_tmp)) { $lang_tmp = reset($lang_tmp); } $category = Category::searchByNameAndParentCategoryId($lang_tmp, $value, $parent_id); if (!$category) { $category = new Category(); foreach ($this->langs as $lang) { $category->name[$lang['id_lang']] = $value; $category->link_rewrite[$lang['id_lang']] = Tools::link_rewrite($value); $category->meta_keywords[$lang['id_lang']] = implode(',', explode(' ', $value)); } $category->active = true; $category->is_root_category = 0; $category->position = 0; $category->id_parent = $parent_id; $category->level_depth = $level_depth; try { $category->add(); } catch (PrestaShopException $e) { PShow_Log::addExceptionLog($e); } $parent_id = $category->id; } else { $parent_id = $category['id_category']; } $level_depth += 1; } if (is_array($category)) { $category = new Category($category['id_category']); } return $category; } public function updateActualRow() { if ((int) $this->config[0]['number_of_threads'] > 1) { return; } self::_updateActualRow(); } public static function _updateActualRow() { PShow_Import::getInstance()->current_row_number = (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "actual_row") + 1; file_put_contents(_IMPORT_STATUS_PATH_ . "actual_row", PShow_Import::getInstance()->current_row_number); } public function updateSkippedRowsCounter() { file_put_contents(_IMPORT_STATUS_PATH_ . "counter_skipped_rows", (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "counter_skipped_rows") + 1); } public function updateImportedRowsCounter() { file_put_contents(_IMPORT_STATUS_PATH_ . "counter_imported_rows", (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "counter_imported_rows") + 1); } public function updateErrorsCounter() { self::_updateErrorsCounter(); } public static function _updateErrorsCounter() { file_put_contents(_IMPORT_STATUS_PATH_ . "counter_error_rows", (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "counter_error_rows") + 1); } /** * * @param string $row * @param bool|string $error */ public function addImportError($row, $error = false) { $errors = file(_IMPORT_STATUS_PATH_ . "error_rows"); if (!$errors || count($errors) == 0 || $errors === null) { $errors = array(); } if ($error) { $row .= ': ' . $error; } array_push($errors, "\n" . $row); $new_contents = implode("", $errors); file_put_contents(_IMPORT_STATUS_PATH_ . "error_rows", $new_contents); } /** * Push some required value to object * * @param object $object * @param string $key * @param array $info * @param bool $force * @return object */ public static function pushRequiredValue($object, $key, $info, $force = false) { if ((!array_key_exists('required', $info) || !$info['required'] || !empty($object->{$key}) || is_array($object->{$key})) && !$force) { return $object; } if (empty($object->{$key}) || $force) { $object->{$key} = null; } switch ($info['type']) { case 1: //int $value = 0; break; case 2: //bool $value = false; break; case 4: //float $value = (float) 0.0; break; case 5: //date $value = '0000-00-00'; break; case 6: //html case 8: //sql case 7: //nothing case 3: //string $value = 'not-defined-but-required'; break; } if (array_key_exists('lang', $info) && $info['lang']) { foreach (Language::getLanguages(true, false, true) as $lang) { $object->{$key}[$lang] = $value; } } else { $object->$key = $value; } return $object; } public function importToDatabase() { //xdebug_start_trace(_IMPORT_STATUS_PATH_.'xdebug_trace', XDEBUG_TRACE_COMPUTERIZED);// XDEBUG_TRACE_HTML); // init timer PShow_Timer::getInstance()->start(); $delay = (int) PShow_Settings::getInstance(__FILE__)->get('import_delay'); if ($delay > 0) { PShow_Log::addImportLog("wait " . $delay . "s"); sleep($delay); PShow_Log::addImportLog("continue import"); } // enable maintenance mode if ((bool) Configuration::get('pshowimporter_maintenance_mode') && (bool) Configuration::get('PS_SHOP_ENABLE')) { Configuration::updateValue('PS_SHOP_ENABLE', '0'); $this->maintenance_mode_enabled = true; PShow_Log::addImportLog("enabled maintenance mode"); } $row_ = 1 + (int) file_get_contents(_IMPORT_STATUS_PATH_ . "actual_row"); if ((int) (int) $this->config[0]['number_of_threads'] > 1) { self::_updateActualRow(); } PShow_Log::addImportLog("*** Importing object from line " . $row_ . " ***"); $filepath = $this->filepath; set_error_handler(function($errno, $errstr, $errfile, $errline) use ($filepath) { // skip some errors if (in_array($errno, array(E_WARNING, E_NOTICE))) return; PShow_Log::add(pathinfo($filepath, PATHINFO_FILENAME) . ".log", "Error in " . $errfile . " [" . $errline . "]: \n" . $errstr); $status = $this->status; $config = $this->config; if (Tools::getValue('ajax')) { $data = Tools::jsonEncode(array( 'filename' => pathinfo($filepath, PATHINFO_FILENAME), 'actual_row' => $status['actual_row'], 'first_line' => 0, 'counter_imported_rows' => $status['counter_imported_rows'], 'counter_error_rows' => $status['counter_error_rows'], 'counter_skipped_rows' => $status['counter_skipped_rows'], 'isSomethingToImport' => (bool) PShowImporterImportController::isSomethingToImport(), 'error' => array($errstr), 'importedThisTime' => 0, 'time' => 0, )); die($data); } global $smarty; $smarty->assign('filename', pathinfo($filepath, PATHINFO_FILENAME)); $smarty->assign('importStatus', $status); $smarty->assign('first_line', $config[0]['firstLine']); if (file_exists(_IMPORT_LOG_PATH_ . pathinfo($filepath, PATHINFO_FILENAME) . '.log')) $smarty->assign('log_content', file_get_contents(_IMPORT_LOG_PATH_ . pathinfo($filepath, PATHINFO_FILENAME) . '.log')); else $smarty->assign('log_content', "empty log..."); $smarty->assign('rowsCount', $config[0]['rowsCount']); }); $classname = 'PShow_' . ucfirst($this->fileext); PShow_Xml_Parser::getInstance($this->filepath); $file_row = ($row_); $this->data = $classname::compareFileRowWithMatchedFields( $file_row, $this->config, _IMPORT_CONFIG_PATH_ . pathinfo($this->filepath, PATHINFO_FILENAME) . '/' ); if (isset($this->data['product']) && PShow_Config::isChecked('updateOnce') && self::$imported_ref !== false && PShow_Config::get('unique_data') == 'reference' && in_array($this->data['product']['reference'][0], self::$imported_ref)) { PShow_Log::addImportLog("Skipped because imported before with code '" . $this->data['product']['reference'][0] . "'"); $this->updateActualRow(); $this->updateSkippedRowsCounter(); return true; } if (isset($this->data['product']) && PShow_Config::isChecked('updateOnce') && self::$imported_id !== false && PShow_Config::get('unique_data') == 'id_product' && in_array($this->data['product']['id_product'][0], self::$imported_id)) { PShow_Log::addImportLog("Skipped because imported before with id '" . $this->data['product']['id_product'][0] . "'"); $this->updateActualRow(); $this->updateSkippedRowsCounter(); return true; } if (PShow_Addon::exists('Multistore')) { $shopsToImport = PShow_Import_Object_Multistore::getShopsIdToImport(); } else { $shops = Shop::getShops(true, null, true); asort($shops); $shopsToImport = array(reset($shops)); } self::$shopsToImport = $shopsToImport; $shops_ = array(reset($shopsToImport)); if (!in_array(PShow_Config::get('what_import'), array('all', 'not_exists'))) { $shops_ = $shopsToImport; } foreach ($shops_ as $shopToImport) { if (PShow_Addon::exists('Multistore')) { PShow_Import_Object_Multistore::initShopToImport($shopToImport); } else { Shop::initialize($shopToImport); } PShow_Import::getInstance()->id_shop = $shopToImport; Context::getContext()->shop = new Shop($shopToImport); PShow_Log::addImportLog("selected shop: #" . $shopToImport); self::$objects = array(); self::$objects_instances = array(); foreach ($this->data as $object_name => $matches) { switch ($object_name) { case 'attributegroup': $classname = 'AttributeGroup'; break; default: $classname = ucfirst($object_name); break; } if (!array_key_exists($classname, self::$objects)) { $_class = 'PShow_Import_' . $classname; if (!class_exists($_class)) { continue; } $importer = new $_class(); $merge = PShow_Ini::read(_IMPORT_CONFIG_PATH_ . pathinfo($this->filepath, PATHINFO_FILENAME) . '/merge.ini'); $importer->importLangs = $this->langs; if (!$importer->setData($matches, (($merge) ? $merge : array()))) { continue; } if (!$importer->checkConditions()) { continue; } if (PShow_Config::get('file_contains') == 'data_category' && array_key_exists('category_path', $matches)) { self::$objects_ = $this->createCategoriesFromPath( $matches['category_path'], PShow_Config::get('category_separator', null, true) ); } else { self::$objects_ = $importer->getNewObject(); } if (!is_object(self::$objects_) && !is_array(self::$objects_)) { $row_ = 1 + (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "actual_row"); $price = 0; if (array_key_exists('price', $this->data)) { $price = $this->data['price'][0]; } elseif (array_key_exists('price_brutto', $this->data)) { $price = $this->data['price_brutto'][0]; } switch (self::$objects_) { case 0: break; case 1: PShow_Log::addImportLog("Skipped because product manufacturer: '" . $importer->data['manufacturer'][0] . "'"); break; case 2: $cat = '?'; if (array_key_exists('category', $importer->data)) { $cat = $importer->data['category'][0]; } elseif (array_key_exists('category_path', $importer->data)) { $cat = $importer->data['category_path'][0]; } PShow_Log::addImportLog("Skipped because product category: '" . $cat . "'"); break; case 4: PShow_Log::addImportLog("Skipped because product price is equal or lower than " . $this->config[0]['productskipp_price_el']); break; case 5: PShow_Log::addImportLog("Skipped because product price is greater than " . $this->config[0]['productskipp_price_eg']); break; case 6: PShow_Log::addImportLog("Skipped because not exists with code: '" . $importer->data['reference'][0] . "'"); break; case 7: PShow_Log::addImportLog("Skipped because exists with code: '" . $importer->data['reference'][0] . "'"); break; case 8: PShow_Log::addImportLog("Skipped because product quantity is greater than " . $this->config[0]['productskipp_quantity_eg']); break; case 9: PShow_Log::addImportLog("Skipped because product quantity is equal or lower than " . $this->config[0]['productskipp_quantity_el']); break; case 10: PShow_Log::addImportLog("Skipped because price from file (" . $price . ") is lower than product net price"); break; case 11: PShow_Log::addImportLog("Skipped because price from file (" . $price . ") is lower than product gross price"); break; case 12: // no message break; default: PShow_Log::addImportLog("Skipped because not found with code: '" . $importer->data['reference'][0] . "'"); break; } $this->updateSkippedRowsCounter(); $this->refreshStatus(); continue; } if (is_array(self::$objects_)) { foreach (self::$objects_ as $object) { self::$objects[$classname] = $object; self::$objects_instances[] = $object; $importer->import(); } } else { self::$objects[$classname] = self::$objects_; self::$objects_instances[] = self::$objects_; $importer->import(); } } else { $importer->import(); } } $error = false; $importedIDs = array(); foreach (self::$objects_instances as &$object) { $invalid = false; $skippedFields = array(); $object_name = str_replace('Core', '', get_class($object)); // to fix ... if ($object_name == 'stdClass') { $object_name = 'Category'; $object = new Category($object->id); } foreach ($object_name::$definition['fields'] as $field => $data) { if (!empty($data['lang'])) { //lang field $values = $object->{$field}; // If the object has not been loaded in multilanguage, then the value is the one for the current language of the object if (!is_array($values)) { $values = array($this->context->language->id => $values); } // The value for the default must always be set, so we put an empty string if it does not exists if (!isset($values[Configuration::get('PS_LANG_DEFAULT')])) { $values[Configuration::get('PS_LANG_DEFAULT')] = ''; } $breakParent = false; foreach ($values as $id_lang => $value) { $message = $object->validateField($field, $value, $id_lang); if ($message === true) continue; if (!isset($this->config[0]['objectWithError']) || $this->config[0]['objectWithError'] == 'skipObject') { $invalid = $message; $breakParent = true; break; } else { if (!in_array($field, $skippedFields)) $skippedFields[] = $field; $object = self::pushRequiredValue($object, $field, $data, true); } } if ($breakParent) break; } else { //no lang field $message = $object->validateField($field, $object->$field); if ($message === true) continue; if (!isset($this->config[0]['objectWithError']) || $this->config[0]['objectWithError'] == 'skipObject') { $invalid = $message; break; } else { if (!in_array($field, $skippedFields)) $skippedFields[] = $field; $object = self::pushRequiredValue($object, $field, $data); } } } // DEBUGGER if (Tools::getValue('debug') !== false) { PShow_Import::$LOG[] = 'This object is ' . ($invalid === false ? 'VALID' : 'INVALID because ' . $invalid) . ''; PShow_Import::$LOG[] = 'Object dump:
' . var_export($object, true); if (PShow_Import::getInstance()->config[0]['what_import'] == 'all') { $object->delete(); } return; } if ($invalid !== false) { $row_ = 1 + (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "actual_row"); PShow_Log::addImportLog("Not imported because: " . $invalid); $error = true; $object->delete(); $this->updateErrorsCounter(); } else { if (count($skippedFields) > 0) { $row_ = 1 + (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "actual_row"); PShow_Log::add( pathinfo($this->filepath, PATHINFO_FILENAME) . ".log", "Skipped some fields because they are invalid: " . implode(', ', $skippedFields) ); } PShow_Log::addImportLog("validate fields for object #" . $object->id); $message = $object->validateFields(false, true); if ($message === true) { try { PShow_Log::addImportLog("save object"); $object->save(0); file_put_contents( _IMPORT_STATUS_PATH_ . "imported_ids", $object->id . ";", FILE_APPEND ); $importedIDs[] = $object->id; $this->updateImportedRowsCounter(); // push object to the selected shops for faster import PShow_Log::addImportLog("push object with data to the selected shops"); PShow_Import_Object_Abstract::pushObjectToOtherShops($object_name, $object, $shopToImport, $shopsToImport, $importer->object_status); // activate product only in selected shops and deactivate product in other if (strtolower($object_name) == 'product' && PShow_Config::isChecked('shop_selectable_product_activation') && strlen($id_shops = PShow_Config::get('shop_selectable_product_activation_shops'))) { PShow_Log::addImportLog("activate product only in selected shops and deactivate product in other"); $id_shops = explode(',', preg_replace('/[^0-9\,]/', '', $id_shops)); PShow_Import_Product::activateProductOnlyInSelectedShops($object->id, $id_shops); } // force add product to search index if (strtolower($object_name) == 'product') { Search::indexation(false, $object->id); } } catch (PrestaShopException $ex) { $this->updateErrorsCounter(); $row_ = 1 + (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "actual_row"); $error = "[Fatal] Not imported because: " . $ex->getMessage(); PShow_Log::addImportLog($error); } } else { $this->updateErrorsCounter(); $row_ = 1 + (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "actual_row"); $error = "[Fatal] Not imported because: " . $message; PShow_Log::addImportLog($error); preg_match_all('~([a-zA-Z]+)->([a-zA-Z0-9]+)~', $message, $obj); if (isset($obj[2]) && isset($obj[2][0]) && isset($object->{$obj[2][0]})) { $tryToSet = $object->{$obj[2][0]}; if (is_array($tryToSet)) $tryToSet = reset($tryToSet); $error .= '
Trying to set: ' . $tryToSet; } $object->delete(); } } } // break creating new products if ($importer->object_status == PShow_Import_Object_Abstract::STATUS_NEW) { break; } } PShow_Log::addImportLog("go to next row/object"); $this->updateActualRow(); if (self::$imported_ref !== false && array_key_exists('reference', $this->data['product']) && !in_array($this->data['product']['reference'][0], self::$imported_ref)) { file_put_contents( _IMPORT_STATUS_PATH_ . "imported_references", $this->data['product']['reference'][0] . ";", FILE_APPEND ); } //xdebug_stop_trace(); //xdebug_print_function_stack('debug import'); if ($error) { if (PShow_Config::get('what_import') == 'all') { foreach (self::$objects_instances as $object) { $object->delete(); } } $this->addImportError(( $this->status["actual_row"] + 1), $error); return $error; } else { $row_ = (int) Tools::file_get_contents(_IMPORT_STATUS_PATH_ . "actual_row"); if (count($importedIDs)) { PShow_Log::addImportLog("Imported successfully with ID: " . implode(',', $importedIDs)); } return true; } } /** * Fast fix for products category depth */ public function fixCategoriesDepth() { Db::getInstance()->query('UPDATE `' . _DB_PREFIX_ . 'category` c1 ' . 'INNER JOIN `' . _DB_PREFIX_ . 'category` c2 ON (c2.`id_category` = c1.`id_parent`) ' . 'SET c1.`level_depth` = c2.`level_depth`+1;'); } /** * Set quantity to 0 for products which not exists in the import file */ public function resetQuantityForNonExistingInTheFile() { $refs = file_get_contents(_IMPORT_STATUS_PATH_ . "imported_references"); if (!empty($refs) && array_key_exists('setZeroForNonExisting', $this->config[0]) && $this->config[0]['setZeroForNonExisting']) { PShow_Log::addImportLog("reset quantity not existing basing on reference"); $explode = explode(';', $refs); $explode = array_filter($explode); $implode = implode("','", $explode); $q = "SELECT `id_product` FROM `" . _DB_PREFIX_ . "product` " . "WHERE `reference` NOT IN ('" . $implode . "')"; $rows = Db::getInstance()->executeS($q); foreach ($rows as $row) { StockAvailable::setQuantity($row['id_product'], 0, 0); if (PShow_Addon::getInstance('ASM') && PShow_Addon::getInstance('ASM')->isEnabled()) { PShow_Addon::getInstance('ASM')->resetProductQuantity($row['id_product']); } } } $ids = file_get_contents(_IMPORT_STATUS_PATH_ . "imported_ids"); if (!empty($ids) && array_key_exists('setZeroForNonExisting', $this->config[0]) && $this->config[0]['setZeroForNonExisting']) { PShow_Log::addImportLog("reset quantity not existing basing on id"); $explode = explode(';', $ids); $explode = array_filter($explode); $implode = implode(",", $explode); $q = "SELECT `id_product` FROM `" . _DB_PREFIX_ . "product` " . "WHERE `id_product` NOT IN (" . $implode . ")"; $rows = Db::getInstance()->executeS($q); foreach ($rows as $row) { StockAvailable::setQuantity($row['id_product'], 0, 0); if (PShow_Addon::getInstance('ASM') && PShow_Addon::getInstance('ASM')->isEnabled()) { PShow_Addon::getInstance('ASM')->resetProductQuantity($row['id_product']); } } } } /** * Disable product which not exists in the file */ public function disableProductsNonExistingInTheFile() { if (empty(self::$shopsToImport)) { return; } /** * Disable not existing products - by reference */ $refs = file_get_contents(_IMPORT_STATUS_PATH_ . "imported_references"); if (!empty($refs) && PShow_Config::isChecked('disableNonExisting')) { PShow_Log::addImportLog("disable not existing basing on references"); $explode = explode(';', $refs); $explode = array_filter($explode); $implode = implode("','", $explode); $q = "SELECT `id_product` FROM `" . _DB_PREFIX_ . "product` " . "WHERE `reference` NOT IN ('" . $implode . "')"; $rows = Db::getInstance()->executeS($q); foreach ($rows as $row) { PShow_Log::addImportLog( sprintf("disable product #%d in shops [%s]", $row['id_product'], implode(',', self::$shopsToImport)) ); // $q = "UPDATE `" . _DB_PREFIX_ . "product` SET `active` = 0 " // . "WHERE `id_product` = " . $row['id_product']; // Db::getInstance()->query($q); $q = "UPDATE `" . _DB_PREFIX_ . "product_shop` SET `active` = 0 " . "WHERE `id_product` = " . $row['id_product'] . " AND " . "`id_shop` IN (" . implode(',', self::$shopsToImport) . ") "; Db::getInstance()->query($q); } } /** * Disable not existing products - by id */ $ids = file_get_contents(_IMPORT_STATUS_PATH_ . "imported_ids"); if (!empty($ids) && PShow_Config::isChecked('disableNonExisting')) { PShow_Log::addImportLog("disable not existing basing on id"); $explode = explode(';', $ids); $explode = array_filter($explode); $implode = implode(",", $explode); $q = "SELECT `id_product` FROM `" . _DB_PREFIX_ . "product` " . "WHERE `id_product` NOT IN (" . $implode . ")"; $rows = Db::getInstance()->executeS($q); foreach ($rows as $row) { PShow_Log::addImportLog( sprintf("disable product #%d in shops [%s]", $row['id_product'], implode(',', self::$shopsToImport)) ); // $q = "UPDATE `" . _DB_PREFIX_ . "product` SET `active` = 0 " // . "WHERE `id_product` = " . $row['id_product']; // Db::getInstance()->query($q); $q = "UPDATE `" . _DB_PREFIX_ . "product_shop` SET `active` = 0 " . "WHERE `id_product` = " . $row['id_product'] . " AND " . "`id_shop` IN (" . implode(',', self::$shopsToImport) . ") "; Db::getInstance()->query($q); } } /** * Disable categories based on category matching */ $ids = file_get_contents(_IMPORT_STATUS_PATH_ . "imported_ids"); $categoriesToDisable = PShow_Ini::read(_IMPORT_STATUS_PATH_ . '/categoriesToDisable.ini'); if (array_key_exists('category_matching', $this->config[0]) && !empty($ids) && $categoriesToDisable) { $ids = explode(';', $ids); $queries = ""; foreach ($categoriesToDisable as $md5 => $value) { $type = substr($md5, 0, 4); switch ($type) { case 'name': $category = Category::searchByName(0, $value, true, true); break; case 'path': foreach ($this->langs as $lang) { $category = Category::searchByPath($lang['id_lang'], $value); if ($category && array_key_exists('id_category', $category)) break; } break; } if ($category && array_key_exists('id_category', $category)) { $products = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT cp.`id_product` as id FROM `' . _DB_PREFIX_ . 'category_product` cp WHERE cp.`id_category` = ' . (int) $category['id_category'] . ' ORDER BY `position` ASC' ); foreach ($products as $product) { if (!in_array($product['id'], $ids)) { PShow_Log::addImportLog( sprintf("disable product #%d in shops [%s] because has category %s", $row['id_product'], implode(',', self::$shopsToImport), $value) ); // $queries .= "UPDATE `" . _DB_PREFIX_ . "product` SET `active` = 0 " // . "WHERE `id_product` = " . $product['id'] . "; "; $queries .= "UPDATE `" . _DB_PREFIX_ . "product_shop` SET `active` = 0 " . "WHERE `id_product` = " . $product['id'] . " AND " . "`id_shop` IN (" . implode(',', self::$shopsToImport) . "); "; } } } } if (!empty($queries)) { Db::getInstance()->query($queries); } } } }