Example #1
0
 /**
  * Converts non Magento import file into currect Magento import file.
  * Show warnings if file cant be converted due to incorrect import data.
  * Use output buffering if you would like to catch all messages in this method
  *
  * @param int $attribute_set_id Magento's attribute set id
  * @param array $file_path An information array of uploaded file, receved
  *     directly from $_FILES array
  * @param int $rows_per_file Split import result file into several ones,
  *     which should contain not more than $rows_per_file products
  * @param string $category_ids Magento's identifiers of categories, to which
  *     imported products should belong
  * @param string $import_action The type of import action: add or update
  *     product information
  * @param bool $out_of_stock Add "out of stock" status for products
  * @param bool $add_images Auto generate pathes to product images
  * @param array $exclude_sku_list The list of products that should not be
  *     involved into convertion even if they mentioned in $file_path file.
  *     It is an element of $_FILES array.
  * @param string $import_language The language of product information
  * @param bool $attribytes_by_groups Magento's attributes are splited into groups.
  *     If you would like to use this feature then use **Attribute_group_name
  *     column name in the importing file to specify group name
  * @param array $name_manuf_fix Add manufacturer name to the resulting SKU
  *
  * @throws Exception Throws an exception if something critical happens,
  *     should be catched for informative purposes only.
  *
  * @return string Path to the zip compressed csv file
  */
 public static function convertForImport($attribute_set_id, $file_path, $rows_per_file = 50, $category_ids = '', $import_action = self::UPDATE_ACTION, $out_of_stock = false, $add_images = false, $exclude_sku_list = null, $import_language = 'EN', $attribytes_by_groups = true, $name_manuf_fix = array())
 {
     global $STOCKS;
     $db =& DB::singleton();
     $tmp_file_name = '';
     if (is_array($file_path)) {
         if ($file_path['type'] == 'text/csv') {
             //use csv file as is
             $file_path = $file_path['tmp_name'];
         } else {
             if ($file_path['type'] == 'application/vnd.ms-excel' || $file_path['type'] == 'application/msexcel') {
                 //convert xls file to csv
                 if (filesize($file_path['tmp_name'])) {
                     $tmp_file_name = tempnam('/tmp', 'xls2csv_prodict_import_');
                     $additional_conf = '';
                     $res = shell_exec('export LANG=en_US.UTF-8 && xls2csv -dUTF-8 -q3 -c, -x ' . $additional_conf . $file_path['tmp_name'] . ' > ' . $tmp_file_name);
                     $file_path = $tmp_file_name;
                 } else {
                     throw new Exception('Empty file.');
                 }
             } else {
                 throw new Exception('Incorrect file.');
             }
         }
     }
     if (filesize($file_path)) {
         $fp = fopen($file_path, 'r');
         if ($fp) {
             $exclude_skus = array();
             if (!is_null($exclude_sku_list)) {
                 // get excluding SKUs to array
                 $exclude_skus = file($exclude_sku_list['tmp_name'], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES | FILE_TEXT);
             }
             //get all magento attribute sets
             $attribute_sets = Product::getAttributeSets();
             $dir_name = PROJECT_HOME . '/dl/' . self::trans(mb_strtolower($attribute_sets[$attribute_set_id])) . '_' . date('d.m.y-H.i.s');
             if (@mkdir($dir_name)) {
                 // main conversion logic starts here
                 try {
                     $column_names = array();
                     // relation between the magento attributes and columns in importing file
                     $column_names_from_file = fgetcsv($fp, 0, ',', '"');
                     // column names that present in importing file
                     $column_names_from_file_count = count($column_names_from_file);
                     $cur_column_name = '';
                     $not_found_columns = array();
                     require_once MAGE_DIR . '/app/Mage.php';
                     $storeId = 0;
                     // get attributes for specified attribute set
                     $websiteId = Mage::app()->getStore($storeId)->getWebsiteId();
                     $attrs = Mage::getResourceModel('catalog/product_attribute_collection')->setAttributeSetFilter($attribute_set_id)->addVisibleFilter()->checkConfigurableProducts();
                     $attrs->getSelect()->joinLeft('eav_attribute_group', 'entity_attribute.attribute_group_id = eav_attribute_group.attribute_group_id', 'eav_attribute_group.attribute_group_name');
                     $attrs = $attrs->load();
                     $attrs_group = array();
                     $attributes = array();
                     $attributes_types = array();
                     $select_values = array();
                     foreach ($attrs as $attr) {
                         if (!isset($attrs_group[$attr->getAttributeGroupName()])) {
                             $attrs_group[$attr->getAttributeGroupName()] = array();
                         }
                         $code = $attr->getAttributeCode();
                         $label = $attr->getFrontendLabel();
                         $attrs_group[$attr->getAttributeGroupName()][$label] = $code;
                         $attributes[$label] = $code;
                         $attr_type = $attr->getFrontendInput();
                         $attributes_types[$code] = $attr_type;
                         if ($attr_type == 'select' || $attr_type == 'multiselect') {
                             $select_values[$code] = array();
                             $optionCollection = Mage::getResourceModel('eav/entity_attribute_option_collection')->setAttributeFilter($attr->getAttributeId())->setPositionOrder('desc', true)->load();
                             foreach ($optionCollection as $option) {
                                 $select_values[$code][] = $option->getValue();
                             }
                         }
                     }
                     //unset $attrs, because it can be heavy weight
                     unset($attrs);
                     // fill the $column_names array
                     if ($attribytes_by_groups) {
                         $cur_group = '';
                         for ($i = 0; $i < $column_names_from_file_count; $i++) {
                             if (substr($column_names_from_file[$i], 0, 2) == '**' && substr($column_names_from_file[$i], 0, -2)) {
                                 $cur_group = substr($column_names_from_file[$i], 2, strlen($column_names_from_file[$i]) - 4);
                                 continue;
                             }
                             if ($cur_group) {
                                 $cur_column_name = '';
                                 if (isset($attrs_group[$cur_group]) && isset($attrs_group[$cur_group][$column_names_from_file[$i]])) {
                                     //column name found by attribute code
                                     $column_names[$attrs_group[$cur_group][$column_names_from_file[$i]]] = $i;
                                 } else {
                                     if (isset($attrs_group[$cur_group]) && in_array($column_names_from_file[$i], $attrs_group[$cur_group])) {
                                         //column name found by attribute label
                                         $column_names[$column_names_from_file[$i]] = $i;
                                     } else {
                                         $not_found_columns[] = $column_names_from_file[$i];
                                     }
                                 }
                             }
                         }
                     } else {
                         for ($i = 0; $i < $column_names_from_file_count; $i++) {
                             $cur_column_name = '';
                             $cur_column_name = $attributes[$column_names_from_file[$i]];
                             if (strlen($cur_column_name)) {
                                 //column name found by attribute code
                                 $column_names[$cur_column_name] = $i;
                             } else {
                                 if (in_array($column_names_from_file[$i], $attributes)) {
                                     //column name found by attribute label
                                     $column_names[$column_names_from_file[$i]] = $i;
                                 } else {
                                     $not_found_columns[] = $column_names_from_file[$i];
                                 }
                             }
                         }
                     }
                     if (count($not_found_columns)) {
                         echo '<h2>Notfound attributes:</h2><p>' . implode('<br>', $not_found_columns) . '</p>';
                     }
                     // if 'sku' is not specified, then try to use 'name'
                     if (!isset($column_names['sku']) && isset($column_names['name'])) {
                         $column_names['sku'] = $column_names['name'];
                         if ($import_action == self::UPDATE_ACTION) {
                             unset($column_names['name']);
                         }
                     }
                     if (!isset($column_names['sku'])) {
                         throw new Exception('SKU is important.');
                     }
                     if (count($name_manuf_fix) && !isset($column_names['manufacturer'])) {
                         throw new Exception('Manufacturer is important.');
                     }
                     if (count($column_names)) {
                         // $additional_columns - additional attributes with static values for all products
                         $additional_columns = array();
                         // $dyn_additional_columns - additional attributes with dynamic values, i.e.
                         // calculated while processing each line
                         $dyn_additional_columns = array();
                         if ($category_ids != 'dummy') {
                             $additional_columns['category_ids'] = $category_ids;
                         }
                         $low_stock_date = gmdate('Y-m-d H:i:s');
                         if ($out_of_stock) {
                             $additional_columns['qty'] = '0';
                             $additional_columns['low_stock_date'] = $low_stock_date;
                             $additional_columns['is_in_stock'] = '0';
                         } else {
                             if (isset($column_names['availability_status'])) {
                                 $dyn_additional_columns[] = 'qty';
                                 $dyn_additional_columns[] = 'low_stock_date';
                                 $dyn_additional_columns[] = 'is_in_stock';
                             }
                         }
                         if ($add_images) {
                             $dyn_additional_columns[] = 'image';
                             $dyn_additional_columns[] = 'small_image';
                             $dyn_additional_columns[] = 'thumbnail';
                         }
                         if ($import_action == self::ADD_ACTION) {
                             $additional_columns['store'] = 'admin';
                             $additional_columns['websites'] = 'base';
                             $additional_columns['visibility'] = $GLOBALS['_'][$import_language]['conv4imp']['Каталог, поиск'];
                             $additional_columns['tax_class_id'] = $GLOBALS['_'][$import_language]['conv4imp']['Нет'];
                             $additional_columns['status'] = $GLOBALS['_'][$import_language]['conv4imp']['Включено'];
                             // weight is important, add 1 if nothing specified
                             if (!isset($column_names['weight'])) {
                                 $additional_columns['weight'] = '1';
                             }
                             $additional_columns['type'] = 'simple';
                             // price is important
                             if (!isset($column_names['price'])) {
                                 $additional_columns['price'] = '0';
                             }
                             $additional_columns['attribute_set'] = $attribute_sets[$attribute_set_id];
                             $dyn_additional_columns[] = 'url_key';
                             $dyn_additional_columns[] = 'meta_keyword';
                         }
                         $short_desc_id = -1;
                         if (isset($column_names['description']) && !isset($column_names['short_description'])) {
                             $desc_id = array_search('description', array_keys($column_names));
                             $dyn_additional_columns[] = 'short_description';
                         }
                         $all_column_names = array_merge(array_keys($column_names), array_keys($additional_columns), $dyn_additional_columns);
                         $file_to_write = fopen($dir_name . '/' . basename($dir_name) . '_1.csv', 'w');
                         fputcsv($file_to_write, $all_column_names, ',', '"');
                         $row = 0;
                         $cur_row = array();
                         $sku_id = array_search('sku', array_keys($column_names));
                         $name_prefx_id = array_search('name_prefix', array_keys($column_names));
                         $availability_status_id = array_search('availability_status', array_keys($column_names));
                         $name_id = array_search('name', array_keys($column_names));
                         $add_update_products_error_skus = array();
                         // the main loop, which goes through the convertion file
                         while (($data = fgetcsv($fp, 0, ',', '"')) !== false) {
                             $cur_row = array();
                             // get current row values
                             foreach ($column_names as $column_name => $id) {
                                 // check if attribute is 'select' or 'multiselect'
                                 // then check the specified value, if it exist in magento
                                 if (($attributes_types[$column_name] == 'select' || $attributes_types[$column_name] == 'multiselect') && strlen($data[$id])) {
                                     $found = false;
                                     for ($i = 0; $i < count($select_values[$column_name]); $i++) {
                                         if (mb_strtolower($select_values[$column_name][$i]) == mb_strtolower($data[$id])) {
                                             $found = true;
                                             $cur_row[] = $select_values[$column_name][$i];
                                             break;
                                         }
                                     }
                                     if (!$found) {
                                         printf(INCORRECT_VALUE_FOR_SELECT, $data[$id], $column_name, $row + 1);
                                         $cur_row[] = '';
                                     }
                                 } else {
                                     $cur_row[] = $data[$id];
                                 }
                                 switch ($column_name) {
                                     // add default description if description is empty,
                                     // or remove tags if description is specified
                                     case 'description':
                                         if (!strlen($cur_row[count($cur_row) - 1])) {
                                             $cur_row[count($cur_row) - 1] = NO_DESCRIPTION;
                                         } else {
                                             $cur_row[count($cur_row) - 1] = strip_tags($cur_row[count($cur_row) - 1]);
                                         }
                                         break;
                                 }
                             }
                             // fix SKU if it is necessary to add manufactirer
                             if (count($name_manuf_fix)) {
                                 if ($import_action == self::ADD_ACTION) {
                                     if (isset($name_manuf_fix['name']) && $name_id !== false) {
                                         $cur_row[$name_id] = strtoupper($data[$column_names['manufacturer']]) . ' ' . $cur_row[$name_id];
                                     }
                                     if (isset($name_manuf_fix['sku'])) {
                                         $cur_row[$sku_id] = strtoupper($data[$column_names['manufacturer']]) . ' ' . $cur_row[$sku_id];
                                     }
                                 } else {
                                     if (isset($name_manuf_fix['name'])) {
                                         $cur_row[$name_id] = $cur_row[$name_id] . ' ' . $data[$column_names['manufacturer']];
                                     }
                                 }
                             }
                             // skip import for this line if SKU is not specified
                             // in most cases it is just empty line
                             if (!strlen($cur_row[$sku_id]) || in_array($cur_row[$sku_id], $exclude_skus)) {
                                 echo "cant fine sku in: " . print_r($data, true);
                                 continue;
                             }
                             $is_product_exist = Product::isProductExistInShop($cur_row[$sku_id]);
                             // skip this data line if product exist and we trying to add it,
                             // and if product does not exist and we trying to update it.
                             if ($is_product_exist && $import_action == self::ADD_ACTION || !$is_product_exist && $import_action == self::UPDATE_ACTION) {
                                 $add_update_products_error_skus[] = $cur_row[$sku_id];
                                 continue;
                             }
                             // add static values for some attributes
                             foreach ($additional_columns as $col_val) {
                                 $cur_row[] = $col_val;
                             }
                             // add dynamically generated values for some attributes
                             for ($i = 0; $i < count($dyn_additional_columns); $i++) {
                                 switch ($dyn_additional_columns[$i]) {
                                     case 'url_key':
                                         $cur_row[] = self::trans(mb_strtolower($cur_row[$sku_id]), '-');
                                         break;
                                     case 'meta_keyword':
                                         $cur_row[] = ($name_prefx_id !== false ? $cur_row[$name_prefx_id] : $attribute_sets[$attribute_set_id]) . ' ' . $cur_row[$sku_id] . META_KEYWORDS;
                                         break;
                                     case 'image':
                                     case 'small_image':
                                     case 'thumbnail':
                                         $cur_row[] = '/' . self::trans(mb_strtolower($cur_row[$sku_id]), '-') . '.jpg';
                                         break;
                                     case 'short_description':
                                         $cur_row[] = mb_substr($cur_row[$desc_id], 0, 100);
                                         break;
                                     case 'qty':
                                         if ($cur_row[$availability_status_id] == $STOCKS['in_stock']) {
                                             $cur_row[] = DEFAULT_QTY;
                                         } else {
                                             $cur_row[] = '0';
                                         }
                                         break;
                                     case 'low_stock_date':
                                         if ($cur_row[$availability_status_id] == $STOCKS['in_stock']) {
                                             $cur_row[] = '';
                                         } else {
                                             $cur_row[] = $low_stock_date;
                                         }
                                         break;
                                     case 'is_in_stock':
                                         if ($cur_row[$availability_status_id] == $STOCKS['in_stock']) {
                                             $cur_row[] = '1';
                                         } else {
                                             $cur_row[] = '0';
                                         }
                                         break;
                                 }
                             }
                             // write converted data
                             fputcsv($file_to_write, $cur_row, ',', '"');
                             $row++;
                             // import file splitting is here:
                             if ($row % $rows_per_file == 0) {
                                 fclose($file_to_write);
                                 $file_to_write = fopen($dir_name . '/' . basename($dir_name) . '_' . ($row / $rows_per_file + 1) . '.csv', 'w');
                                 fputcsv($file_to_write, $all_column_names, ',', '"');
                             }
                         }
                         // show messages about errors in cenvertion file
                         if (count($add_update_products_error_skus)) {
                             if ($import_action == self::UPDATE_ACTION) {
                                 echo NO_GOODS_MESSAGE;
                             } else {
                                 if ($import_action == self::ADD_ACTION) {
                                     echo GOODS_ARE_IN_DB;
                                 }
                             }
                             echo implode('<br/>', $add_update_products_error_skus);
                         }
                         fclose($file_to_write);
                         self::removeTempFiles();
                         // create the resulting zip archive
                         exec('cd ' . dirname($dir_name) . " && zip -r {$dir_name}.zip " . basename($dir_name) . " && rm -rf {$dir_name}");
                         $archive_name = basename($dir_name) . '.zip';
                     } else {
                         throw new Exception("There are no any relations between columns in file and attributes");
                     }
                 } catch (Exception $e) {
                     exec("rm -rf {$dir_name}");
                     fclose($fp);
                     //rethrow exception, because it has issue specific message
                     throw $e;
                 }
             } else {
                 throw new Exception('Cant create temporary dir.');
             }
             fclose($fp);
         } else {
             throw new Exception('Cant get access to ' . $file_path);
         }
     } else {
         throw new Exception('Empty file.');
     }
     // remove some trash
     if (strlen($tmp_file_name)) {
         unlink($tmp_file_name);
     }
     return $archive_name;
 }
Example #2
0
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<?php 
require_once dirname(__FILE__) . '/menu.php';
require_once dirname(__FILE__) . "/lib/Product.php";
require_once dirname(__FILE__) . "/lib/Converter.php";
try {
    if (isset($_POST['convert_the_the_file']) && (int) $_POST['attribute_set_id'] > 0 && $_FILES["file_to_convert"]["error"] == UPLOAD_ERR_OK) {
        $archive_name = Converter::convertForImport((int) $_POST['attribute_set_id'], $_FILES["file_to_convert"], (int) $_POST['rows_per_file'], implode(",", $_POST['category_ids']), $_POST['add_update_products'], isset($_POST['out_of_stock']), isset($_POST['add_images']), strlen($_FILES["exclude_sku_list"]['tmp_name']) ? $_FILES["exclude_sku_list"] : null, $_POST['import_language'], isset($_POST['attribytes_by_groups']), (array) $_POST['manuf_fix']);
        echo '<h2><a href="/dl/' . $archive_name . '">Готово.</a></h2>';
    }
} catch (Exception $e) {
    die($e->getMessage());
}
$attribute_sets = Product::getAttributeSets();
$categories = Product::getCategories();
?>
<form action="" method="post" enctype="multipart/form-data">
<table border="0" style="margin: 0 auto;">
	<tbody>
		<tr>
			<td>
				<label for="attribute_set_id">Тип:&nbsp;</label>
			</td>
			<td>
				<select name="attribute_set_id" id="attribute_set_id">
				<option selected="selected" value="dummy"></option>
				<?php 
foreach ($attribute_sets as $attribute_set_id => $attribute_set_name) {
    echo '<option value="' . $attribute_set_id . '">' . $attribute_set_name . '</option>';