* @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);
}
}
}
}