Hi,
Thanks for your reports, it allow us to improve our features.
I have corrected many things about this importCsv, this will be in the next release.
To correct it now, thanks to replace the function "getFromFile()" in "administrator/components/com_hikashop/classes/massaction.php" by:
function getFromFile($element, $check = false){
$data = new stdClass();
$app = JFactory::getApplication();
// get the elements from the file
$importHelper = hikashop_get('helper.import');
$importFile = array();
$elts = explode('/',$element['path']);
if($elts == null) return false;
$nb = count($elts);
if($nb == 1){
$elts = explode('\\',$element['path']);
$nb = count($elts);
}
if(!file_exists($element['path'])){
if(!$check)$app->enqueueMessage(JText::sprintf( 'NO_FILE_FOUND',$element['path']), 'error');
$data->error = 'not_found';
return $data;
}
hikashop_increasePerf();
$contentFile = @file_get_contents($element['path']);
if(!$contentFile){
if(!$check)$app->enqueueMessage(JText::sprintf( 'FAIL_OPEN',$element['path']), 'error');
$data->error = 'fail_open';
return $data;
};
$contentFile = str_replace(array("\r\n","\r"),"\n",$contentFile);
$contentFile = strip_tags($contentFile);
$importLines = explode("\n", $contentFile);
$importLines = str_replace('"','',$importLines);
// Get the columns
$columns = str_replace('"','',$importLines[0]);
$listSeparators = array(';',',','|',"\t");
$separator = ';';
foreach($listSeparators as $sep){
if(preg_match('#(?!\\\\)'.$sep.'#',$columns)){
$separator = $sep;
$columns=str_replace($sep,'|',$columns);
break;
}
}
unset($importLines[0]);
if(empty($importLines)){
if(!$check)$app->enqueueMessage('EMPTY','error');
$data->error = 'empty';
return $data;
}
$columns = explode('|',$columns);
$numberColumns = count($columns);
// Check if the columns exists in db
$db = JFactory::getDBO();
if(!HIKASHOP_J25) {
$tmp = $db->getTableFields(hikashop_table('product'));
$productColumns = reset($tmp);
unset($tmp);
$tmp = $db->getTableFields(hikashop_table('price'));
$priceColumns = reset($tmp);
unset($tmp);
} else {
$productColumns = $db->getTableColumns(hikashop_table('product'));
$priceColumns = $db->getTableColumns(hikashop_table('price'));
}
$db->setQuery('SELECT characteristic_value FROM '.hikashop_table('characteristic').' WHERE characteristic_parent_id = 0');
$characteristicColumns = $db->loadResultArray();
$categoryColumns = array('categories_ordering','parent_category','categories_image','categories');
$otherColumns = array('files','images','related','options');
if(!is_array($characteristicColumns)) $characteristicColumns = array($characteristicColumns);
$mergedColumns = array_merge(array_keys($productColumns),array_keys($priceColumns),$categoryColumns,$characteristicColumns,$otherColumns);
$wrongColumns = array_diff($columns,$mergedColumns);
if(!empty($wrongColumns) && $check){
if(!$check)$app->enqueueMessage('WRONG_COLUMNS','error');
$data->wrongColumns = $wrongColumns;
$data->validColumns = $mergedColumns;
$data->error = 'wrong_columns';
return $data;
}elseif($check){
$data->error = 'valid';
return $data;
}
// Change the column if the column in the csv is wrong and set in parameters, else delete this column
if(isset($element['change']) && is_array($element['change'])){
foreach($columns as $num => $column){
foreach($element['change'] as $key => $value){
if($column == $key && $value != 'delete'){
$columns[$num] = $value;
}
elseif($column == $key && $value == 'delete'){
unset($columns[$num]);
}
}
}
}
// Get the missing product_code / product_id
$pool = array();
$missingIds = array();
$missingCodes = array();
foreach($importLines as $key => $importLine){
$product = $this->getProduct($importLines, $key, $numberColumns, $separator);
if(!is_array($product)) continue;
$newProduct = new stdClass();
foreach($product as $num => $value){
if(!empty($columns[$num])){
$field = $columns[$num];
if( strpos('|',$field) !== false ) { $field = str_replace('|','__tr__',$field); }
//$newProduct->$field = trim($value,'\'" ');
$newProduct->$field = preg_replace('#^[\'" ]{1}(.*)[\'" ]{1}$#','$1',$value);
}
}
$pool[$key] = new stdClass();
if(isset($newProduct->product_id)){
$pool[$key]->product_id = $newProduct->product_id;
}
if(isset($newProduct->product_code)){
$pool[$key]->product_code = $newProduct->product_code;
}
if(!isset($pool[$key]->product_id) && !isset($pool[$key]->product_code)){
continue;
}
if(!isset($pool[$key]->product_code)){
$missingCodes[] = $pool[$key]->product_id;
}
if(!isset($pool[$key]->product_id)){
$missingIds[] = $pool[$key]->product_code;
}
}
$missing = array();
if(!empty($missingCodes)){
$db->setQuery('SELECT * FROM '.hikashop_table('product').' WHERE product_id IN ('.implode(',',$missingCodes).')');
$missingCodes = $db->loadObjectList();
}
if(!empty($missingIds)){
$db->setQuery('SELECT * FROM '.hikashop_table('product').' WHERE product_code IN ('.implode(',',$db->quote($missingIds)).')');
$missingIds = $db->loadObjectList();
}
$errorcount = 0;
$importProducts = array();
foreach($importLines as $key => $importLine){
$product = $this->getProduct($importLines, $key, $numberColumns, $separator);
if(!is_array($product)) continue;
$newProduct = new stdClass();
foreach($product as $num => $value){
if(!empty($columns[$num])){
$field = $columns[$num];
if( strpos('|',$field) !== false ) { $field = str_replace('|','__tr__',$field); }
//$newProduct->$field = trim($value,'\'" ');
$newProduct->$field = preg_replace('#^[\'" ]{1}(.*)[\'" ]{1}$#','$1',$value);
}
}
// need the product code and the product id
if(empty($newProduct->product_id)){
foreach($missingIds as $missingId){
if($newProduct->product_code == $missingId->product_code){
$newProduct->product_id = $missingId->product_id;
}
}
}
if(empty($newProduct->product_code)){
foreach($missingCodes as $missingCode){
if($newProduct->product_id == $missingCode->product_id){
$newProduct->product_code = $missingCode->product_code;
}
}
}
if(empty($newProduct->product_code) || empty($newProduct->product_id)){
$errorcount++;
if($errorcount<20){
if(isset($importLine[$key-1]))$app->enqueueMessage(JText::sprintf('IMPORT_ERRORLINE',$importLines[$key-1]).' '.JText::_('PRODUCT_NOT_FOUND'),'notice');
}elseif($errorcount == 20){
$app->enqueueMessage('...','notice');
}
}else{
$importProducts[$newProduct->product_id] = $newProduct;
$ids[] = $newProduct->product_id;
}
}
$data->ids = $ids;
$data->elements = $importProducts;
return $data;
}
And the function "onProcessProductMassFiltercsvImport" in "plugins/plg_hikashop_massaction_product/massaction_product.php" by:
function onProcessProductMassFiltercsvImport(&$elements,&$query,$filter,$num){
if(empty($filter['type']) || $filter['type']=='all') return;
if(!isset($this->massaction))$this->massaction = hikashop_get('class.massaction');
if(count($elements)){
foreach($elements as $k => $element){
if($element->$filter['type']!=$filter['value']) unset($elements[$k]);
}
}else{
$data = $this->massaction->getFromFile($filter);
if(empty($data->ids) || isset($data->error))
return false;
JArrayHelper::toInteger($data->ids);
$db = JFactory::getDBO();
$productClass = hikashop_get('class.product');
$productClass->getProducts($data->ids);
// Get all the product code - id - parent_id in the csv
$pool = array();
foreach($data->ids as $i => $id){
if(!isset($data->elements[$id]->product_id) || !isset($data->elements[$id]->product_code) || !isset($data->elements[$id]->product_parent_id)) continue;
$pool[$data->elements[$id]->product_code] = array();
$pool[$data->elements[$id]->product_code]['id'] = $data->elements[$id]->product_id;
$pool[$data->elements[$id]->product_code]['parent_id'] = $data->elements[$id]->product_parent_id;
}
// Get all the missing product parent id
$toGet = array();
foreach($data->ids as $i => $id){
if(isset($data->elements[$id]->product_parent_id) && $data->elements[$id]->product_parent_id != '' && (int)$data->elements[$id]->product_parent_id == 0 && !in_array($data->elements[$id]->product_parent_id,$pool) && !in_array($data->elements[$id]->product_parent_id,$toGet)){
$toGet[] = $data->elements[$id]->product_parent_id;
}
}
// Select all the missing product parent id
$db->setQuery('SELECT * FROM '.hikashop_table('product').' WHERE product_code IN (\''.implode('\',\'',$toGet).'\')');
$gets = $db->loadObjectList();
foreach($gets as $get){
$pool[$get->product_code]['id'] = $get->product_id;
$pool[$get->product_code]['parent_id'] = $get->product_parent_id;
}
if(!is_array($data->ids)) $data->ids = array($data->ids);
foreach($data->ids as $i => $id){
if(!isset($data->elements[$id])) continue;
$data->elements[$id]->product_id = (int)$data->elements[$id]->product_id;
if(isset($data->elements[$id]->product_type) && $data->elements[$id]->product_type == 'variant' && (int)$data->elements[$id]->product_parent_id == 0){
if(array_key_exists($data->elements[$id]->product_parent_id,$pool)){
$data->elements[$id]->product_parent_id = $pool[$data->elements[$id]->product_parent_id]['id'];
}else{
continue;
}
}
$oldElement = $productClass->all_products[$id];
// Manage the prices
if(!empty($data->elements[$id]->price_value)){
$data->elements[$id]->prices = array();
$price_values = explode('|',$data->elements[$id]->price_value);
$price_currencies = explode('|',$data->elements[$id]->price_currency_id);
$price_min_quantities = explode('|',$data->elements[$id]->price_min_quantity);
$price_accesses = explode('|',$data->elements[$id]->price_access);
foreach($price_values as $k => $price_value){
$data->elements[$id]->prices[$k] = new stdClass();
$data->elements[$id]->prices[$k]->price_value = $price_value;
}
foreach($price_currencies as $k => $price_currency){
if(!is_int($price_currency)){
$db->setQuery('SELECT currency_id FROM '.hikashop_table('currency').' WHERE currency_code LIKE '.$db->quote($price_currency));
$price_currency_id = $db->loadResult();
}
$data->elements[$id]->prices[$k]->price_currency_id = $price_currency_id;
}
foreach($price_min_quantities as $k => $price_min_quantity){
$data->elements[$id]->prices[$k]->price_min_quantity = $price_min_quantity;
}
foreach($price_accesses as $k => $price_access){
$price_access_clean = str_replace(',','',$price_access);
$data->elements[$id]->prices[$k]->price_access = $price_access_clean;
}
}
unset($data->elements[$id]->price_value);
unset($data->elements[$id]->price_currency_id);
unset($data->elements[$id]->price_min_quantity);
unset($data->elements[$id]->price_access);
// Manage the files
if(!empty($data->elements[$id]->files)){
$newFiles = explode(';',$data->elements[$id]->files);
$data->elements[$id]->files = array();
foreach($newFiles as $k => $newFile){
$same = 0;
foreach($oldElement->files as $oldFile){
if($oldFile->file_path == $newFile){
$data->elements[$id]->files[] = $oldFile->file_id;
$same = 1;
}
}
if(!empty($newFile) && $same == 0){
$db->setQuery('SELECT file_id FROM '.hikashop_table('file').' WHERE file_path LIKE '.$db->quote($newFile));
$newFileId = $db->loadResult();
if(!empty($newFileId))
$data->elements[$id]->files[] = $newFileId;
}
}
}
// Manage the images
if(!empty($data->elements[$id]->images)){
$newImages = explode(';',$data->elements[$id]->images);
$data->elements[$id]->images = array();
foreach($newImages as $k => $newImage){
$same = 0;
foreach($oldElement->images as $oldImage){
if(!empty($newImage) && $oldImage->file_path == $newImage){
$data->elements[$id]->images[] = $oldImage->file_id;
$same = 1;
}
}
if(!empty($newImage) && $same == 0){
$db->setQuery('SELECT file_id FROM '.hikashop_table('file').' WHERE file_path LIKE '.$db->quote($newImage));
$newImageId = $db->loadResult();
if(!empty($newImageId))
$data->elements[$id]->images[] = $newImageId;
}
}
}
// Manage the categories
if(!empty($data->elements[$id]->categories)){
$categories = explode(';',$data->elements[$id]->categories);
$data->elements[$id]->categories = array();
foreach($categories as $category){
$db->setQuery('SELECT category_id FROM '.hikashop_table('category').' WHERE category_name LIKE '.$db->quote($category));
$data->elements[$id]->categories[] = $db->loadResult();
}
unset($oldElement->categories);
}
if(!empty($data->elements[$id]->categories_ordering)){
$data->elements[$id]->categories_ordering = explode(';',$data->elements[$id]->categories_ordering);
unset($oldElement->categories_ordering);
}
// Manage the relateds
if(!empty($data->elements[$id]->related)){
$relateds = explode(';',$data->elements[$id]->related);
$data->elements[$id]->related = array();
foreach($relateds as $k => $related){
$db->setQuery('SELECT product_id FROM '.hikashop_table('product').' WHERE product_code LIKE '.$db->quote($related));
$data->elements[$id]->related[$k]->product_related_id = $db->loadResult();
$data->elements[$id]->related[$k]->product_id = $id;
$data->elements[$id]->related[$k]->product_related_ordering = $k;
$data->elements[$id]->related[$k]->product_related_type = 'related';
}
}
// Manage the options
if(!empty($data->elements[$id]->options)){
$options = explode(';',$data->elements[$id]->options);
$data->elements[$id]->options = array();
foreach($options as $option){
$db->setQuery('SELECT product_id FROM '.hikashop_table('product').' WHERE product_code LIKE '.$db->quote($option));
$data->elements[$id]->options[$k]->product_related_id = $db->loadResult();
$data->elements[$id]->options[$k]->product_id = $id;
$data->elements[$id]->options[$k]->product_related_ordering = $k;
$data->elements[$id]->options[$k]->product_related_type = 'related';
}
}
unset($oldElement->images);
unset($oldElement->files);
unset($oldElement->related);
unset($oldElement->options);
// Replace the old values in the oldElement becoming the element
foreach($oldElement as $k => $old){
foreach($data->elements[$id] as $l => $new){
if($k == $l){
$oldElement->$k = $new;
}
}
}
$data->elements[$id] = $oldElement;
// Save the elements if checkbox checked
if(isset($filter['save'])){
if(isset($data->elements[$id]->prices))
$productClass->updatePrices($data->elements[$id],$id);
if($data->elements[$id]->product_type!='variant')
$productClass->updateCategories($data->elements[$id],$id);
if(!empty($data->elements[$id]->files))
$productClass->updateFiles($data->elements[$id],$id,'files');
if(!empty($data->elements[$id]->images))
$productClass->updateFiles($data->elements[$id],$id,'images');
if(!empty($data->elements[$id]->related))
$productClass->updateRelated($data->elements[$id],$id,'related');
if(!empty($data->elements[$id]->options))
$productClass->updateRelated($data->elements[$id],$id,'options');
// unset all the vars which are not in the product table
$db->setQuery('SHOW columns FROM '.hikashop_table('product'));
$cols = $db->loadObjectList();
$fields = array();
foreach($cols as $col){
$fields[] = $col->Field;
}
foreach($data->elements[$id] as $l => $content){
if(!in_array($l,$fields)){
unset($data->elements[$id]->$l);
}
}
if(isset($data->elements[$id]->product_created) && (int)$data->elements[$id]->product_created == 0){
unset($data->elements[$id]->product_created);
}
$data->elements[$id]->product_modified = time();
$data->elements[$id]->product_width = str_replace($data->elements[$id]->product_dimension_unit,'',$data->elements[$id]->product_width);
$data->elements[$id]->product_length = str_replace($data->elements[$id]->product_dimension_unit,'',$data->elements[$id]->product_length);
$data->elements[$id]->product_height = str_replace($data->elements[$id]->product_dimension_unit,'',$data->elements[$id]->product_height);
$elements = $data->elements;
// Save the new data of the product
$productClass->save($elements[$id]);
}
}
// Get all the products but the ones in the csv file
if($filter['type'] == 'out'){
JArrayHelper::toInteger($data->ids);
$db->setQuery('SELECT product_id FROM '.hikashop_table('product').' WHERE product_id NOT IN ('.implode(',',$data->ids).')');
$ids = $db->loadResultArray();
$productClass = hikashop_get('class.product');
$elements = array();
foreach($ids as $id){
$elements[] = $productClass->get($id);
}
}
}
}