protected function categoryImportOne($info, $default_language_id, $id_lang, $force_ids, $regenerate, $shop_is_feature_active, &$cat_moved, $validateOnly = false)
    {
        $tab_categ = array(Configuration::get('PS_HOME_CATEGORY'), Configuration::get('PS_ROOT_CATEGORY'));
        if (isset($info['id']) && in_array((int) $info['id'], $tab_categ)) {
            $this->errors[] = Tools::displayError('The category ID must be unique. It can\'t be the same as the one for Root or Home category.');
            return;
        }
        AdminImportController::setDefaultValues($info);
        if ($force_ids && isset($info['id']) && (int) $info['id']) {
            $category = new Category((int) $info['id']);
        } else {
            if (isset($info['id']) && (int) $info['id'] && Category::existsInDatabase((int) $info['id'], 'category')) {
                $category = new Category((int) $info['id']);
            } else {
                $category = new Category();
            }
        }
        AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $category);
        // Parent category
        if (isset($category->parent) && is_numeric($category->parent)) {
            // Validation for parenting itself
            if ($validateOnly && $category->parent == $category->id || isset($info['id']) && $category->parent == (int) $info['id']) {
                $this->errors[] = sprintf(Tools::displayError('The category ID must be unique. It can\'t be the same as the one for the parent category (ID: %1$s).'), isset($info['id']) && !empty($info['id']) ? $info['id'] : 'null');
                return;
            }
            if (isset($cat_moved[$category->parent])) {
                $category->parent = $cat_moved[$category->parent];
            }
            $category->id_parent = $category->parent;
        } elseif (isset($category->parent) && is_string($category->parent)) {
            // Validation for parenting itself
            if ($validateOnly && isset($category->name) && $category->parent == $category->name) {
                $this->errors[] = sprintf(Tools::displayError('A category can\'t be its own parent. You should rename it (current name: %1$s).'), $category->parent);
                return;
            }
            $category_parent = Category::searchByName($id_lang, $category->parent, true);
            if ($category_parent['id_category']) {
                $category->id_parent = (int) $category_parent['id_category'];
                $category->level_depth = (int) $category_parent['level_depth'] + 1;
            } else {
                $category_to_create = new Category();
                $category_to_create->name = AdminImportController::createMultiLangField($category->parent);
                $category_to_create->active = 1;
                $category_link_rewrite = Tools::link_rewrite($category_to_create->name[$id_lang]);
                $category_to_create->link_rewrite = AdminImportController::createMultiLangField($category_link_rewrite);
                $category_to_create->id_parent = Configuration::get('PS_HOME_CATEGORY');
                // Default parent is home for unknown category to create
                if (($field_error = $category_to_create->validateFields(UNFRIENDLY_ERROR, true)) === true && ($lang_field_error = $category_to_create->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && !$validateOnly && $category_to_create->add()) {
                    $category->id_parent = $category_to_create->id;
                } else {
                    if (!$validateOnly) {
                        $this->errors[] = sprintf($this->trans('%1$s (ID: %2$s) cannot be saved', array(), 'Admin.Parameters.Notification'), $category_to_create->name[$id_lang], isset($category_to_create->id) && !empty($category_to_create->id) ? $category_to_create->id : 'null');
                    }
                    if ($field_error !== true || isset($lang_field_error) && $lang_field_error !== true) {
                        $this->errors[] = ($field_error !== true ? $field_error : '') . (isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '') . Db::getInstance()->getMsgError();
                    }
                }
            }
        }
        if (isset($category->link_rewrite) && !empty($category->link_rewrite[$default_language_id])) {
            $valid_link = Validate::isLinkRewrite($category->link_rewrite[$default_language_id]);
        } else {
            $valid_link = false;
        }
        if (!$shop_is_feature_active) {
            $category->id_shop_default = 1;
        } else {
            $category->id_shop_default = (int) Context::getContext()->shop->id;
        }
        $bak = $category->link_rewrite[$default_language_id];
        if (isset($category->link_rewrite) && empty($category->link_rewrite[$default_language_id]) || !$valid_link) {
            $category->link_rewrite = Tools::link_rewrite($category->name[$default_language_id]);
            if ($category->link_rewrite == '') {
                $category->link_rewrite = 'friendly-url-autogeneration-failed';
                $this->warnings[] = sprintf($this->trans('URL rewriting failed to auto-generate a friendly URL for: %s', array(), 'Admin.Parameters.Notification'), $category->name[$default_language_id]);
            }
            $category->link_rewrite = AdminImportController::createMultiLangField($category->link_rewrite);
        }
        if (!$valid_link) {
            $this->informations[] = sprintf($this->trans('Rewrite link for %1$s (ID %2$s): re-written as %3$s.', array(), 'Admin.Parameters.Notification'), $bak, isset($info['id']) && !empty($info['id']) ? $info['id'] : 'null', $category->link_rewrite[$default_language_id]);
        }
        $res = false;
        if (($field_error = $category->validateFields(UNFRIENDLY_ERROR, true)) === true && ($lang_field_error = $category->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && empty($this->errors)) {
            $category_already_created = Category::searchByNameAndParentCategoryId($id_lang, $category->name[$id_lang], $category->id_parent);
            // If category already in base, get id category back
            if ($category_already_created['id_category']) {
                $cat_moved[$category->id] = (int) $category_already_created['id_category'];
                $category->id = (int) $category_already_created['id_category'];
                if (Validate::isDate($category_already_created['date_add'])) {
                    $category->date_add = $category_already_created['date_add'];
                }
            }
            if ($category->id && $category->id == $category->id_parent) {
                $this->errors[] = sprintf($this->trans('A category cannot be its own parent. The parent category ID is either missing or unknown (ID: %1$s).', array(), 'Admin.Parameters.Notification'), isset($info['id']) && !empty($info['id']) ? $info['id'] : 'null');
                return;
            }
            /* No automatic nTree regeneration for import */
            $category->doNotRegenerateNTree = true;
            // If id category AND id category already in base, trying to update
            $categories_home_root = array(Configuration::get('PS_ROOT_CATEGORY'), Configuration::get('PS_HOME_CATEGORY'));
            if ($category->id && $category->categoryExists($category->id) && !in_array($category->id, $categories_home_root) && !$validateOnly) {
                $res = $category->update();
            }
            if ($category->id == Configuration::get('PS_ROOT_CATEGORY')) {
                $this->errors[] = $this->trans('The root category cannot be modified.', array(), 'Admin.Parameters.Notification');
            }
            // If no id_category or update failed
            $category->force_id = (bool) $force_ids;
            if (!$res && !$validateOnly) {
                $res = $category->add();
            }
        }
        // ValidateOnly mode : stops here
        if ($validateOnly) {
            return;
        }
        //copying images of categories
        if (isset($category->image) && !empty($category->image)) {
            if (!AdminImportController::copyImg($category->id, null, $category->image, 'categories', !$regenerate)) {
                $this->warnings[] = $category->image . ' ' . $this->trans('cannot be copied.', array(), 'Admin.Parameters.Notification');
            }
        }
        // If both failed, mysql error
        if (!$res) {
            $this->errors[] = sprintf(Tools::displayError('%1$s (ID: %2$s) cannot be ' . ($validateOnly ? 'validated' : 'saved')), isset($info['name']) && !empty($info['name']) ? Tools::safeOutput($info['name']) : 'No Name', isset($info['id']) && !empty($info['id']) ? Tools::safeOutput($info['id']) : 'No ID');
            $error_tmp = ($field_error !== true ? $field_error : '') . (isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '') . Db::getInstance()->getMsgError();
            if ($error_tmp != '') {
                $this->errors[] = $error_tmp;
            }
        } else {
            // Associate category to shop
            if ($shop_is_feature_active) {
                Db::getInstance()->execute('
					DELETE FROM ' . _DB_PREFIX_ . 'category_shop
					WHERE id_category = ' . (int) $category->id);
                if (!$shop_is_feature_active) {
                    $info['shop'] = 1;
                } elseif (!isset($info['shop']) || empty($info['shop'])) {
                    $info['shop'] = implode($this->multiple_value_separator, Shop::getContextListShopID());
                }
                // Get shops for each attributes
                $info['shop'] = explode($this->multiple_value_separator, $info['shop']);
                foreach ($info['shop'] as $shop) {
                    if (!empty($shop) && !is_numeric($shop)) {
                        $category->addShop(Shop::getIdByName($shop));
                    } elseif (!empty($shop)) {
                        $category->addShop($shop);
                    }
                }
            }
        }
    }
    public function categoryImport()
    {
        $cat_moved = array();
        $this->receiveTab();
        $handle = $this->openCsvFile();
        $default_language_id = (int) Configuration::get('PS_LANG_DEFAULT');
        $id_lang = Language::getIdByIso(Tools::getValue('iso_lang'));
        if (!Validate::isUnsignedId($id_lang)) {
            $id_lang = $default_language_id;
        }
        AdminImportController::setLocale();
        for ($current_line = 0; $line = fgetcsv($handle, MAX_LINE_SIZE, $this->separator); $current_line++) {
            if (Tools::getValue('convert')) {
                $line = $this->utf8EncodeArray($line);
            }
            $info = AdminImportController::getMaskedRow($line);
            $tab_categ = array(Configuration::get('PS_HOME_CATEGORY'), Configuration::get('PS_ROOT_CATEGORY'));
            if (isset($info['id']) && in_array((int) $info['id'], $tab_categ)) {
                $this->errors[] = Tools::displayError('The category ID cannot be the same as the Root category ID or the Home category ID.');
                continue;
            }
            AdminImportController::setDefaultValues($info);
            if (Tools::getValue('forceIDs') && isset($info['id']) && (int) $info['id']) {
                $category = new Category((int) $info['id']);
            } else {
                if (isset($info['id']) && (int) $info['id'] && Category::existsInDatabase((int) $info['id'], 'category')) {
                    $category = new Category((int) $info['id']);
                } else {
                    $category = new Category();
                }
            }
            AdminImportController::arrayWalk($info, array('AdminImportController', 'fillInfo'), $category);
            if (isset($category->parent) && is_numeric($category->parent)) {
                if (isset($cat_moved[$category->parent])) {
                    $category->parent = $cat_moved[$category->parent];
                }
                $category->id_parent = $category->parent;
            } elseif (isset($category->parent) && is_string($category->parent)) {
                $category_parent = Category::searchByName($id_lang, $category->parent, true);
                if ($category_parent['id_category']) {
                    $category->id_parent = (int) $category_parent['id_category'];
                    $category->level_depth = (int) $category_parent['level_depth'] + 1;
                } else {
                    $category_to_create = new Category();
                    $category_to_create->name = AdminImportController::createMultiLangField($category->parent);
                    $category_to_create->active = 1;
                    $category_link_rewrite = Tools::link_rewrite($category_to_create->name[$id_lang]);
                    $category_to_create->link_rewrite = AdminImportController::createMultiLangField($category_link_rewrite);
                    $category_to_create->id_parent = Configuration::get('PS_HOME_CATEGORY');
                    // Default parent is home for unknown category to create
                    if (($field_error = $category_to_create->validateFields(UNFRIENDLY_ERROR, true)) === true && ($lang_field_error = $category_to_create->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && $category_to_create->add()) {
                        $category->id_parent = $category_to_create->id;
                    } else {
                        $this->errors[] = sprintf(Tools::displayError('%1$s (ID: %2$s) cannot be saved'), $category_to_create->name[$id_lang], isset($category_to_create->id) && !empty($category_to_create->id) ? $category_to_create->id : 'null');
                        $this->errors[] = ($field_error !== true ? $field_error : '') . (isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '') . Db::getInstance()->getMsgError();
                    }
                }
            }
            if (isset($category->link_rewrite) && !empty($category->link_rewrite[$default_language_id])) {
                $valid_link = Validate::isLinkRewrite($category->link_rewrite[$default_language_id]);
            } else {
                $valid_link = false;
            }
            if (!Shop::isFeatureActive()) {
                $category->id_shop_default = 1;
            } else {
                $category->id_shop_default = (int) Context::getContext()->shop->id;
            }
            $bak = $category->link_rewrite[$default_language_id];
            if (isset($category->link_rewrite) && empty($category->link_rewrite[$default_language_id]) || !$valid_link) {
                $category->link_rewrite = Tools::link_rewrite($category->name[$default_language_id]);
                if ($category->link_rewrite == '') {
                    $category->link_rewrite = 'friendly-url-autogeneration-failed';
                    $this->warnings[] = sprintf(Tools::displayError('URL rewriting failed to auto-generate a friendly URL for: %s'), $category->name[$default_language_id]);
                }
                $category->link_rewrite = AdminImportController::createMultiLangField($category->link_rewrite);
            }
            if (!$valid_link) {
                $this->warnings[] = sprintf(Tools::displayError('Rewrite link for %1$s (ID: %2$s) was re-written as %3$s.'), $bak, isset($info['id']) && !empty($info['id']) ? $info['id'] : 'null', $category->link_rewrite[$default_language_id]);
            }
            $res = false;
            if (($field_error = $category->validateFields(UNFRIENDLY_ERROR, true)) === true && ($lang_field_error = $category->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true && empty($this->errors)) {
                $category_already_created = Category::searchByNameAndParentCategoryId($id_lang, $category->name[$id_lang], $category->id_parent);
                // If category already in base, get id category back
                if ($category_already_created['id_category']) {
                    $cat_moved[$category->id] = (int) $category_already_created['id_category'];
                    $category->id = (int) $category_already_created['id_category'];
                    if (Validate::isDate($category_already_created['date_add'])) {
                        $category->date_add = $category_already_created['date_add'];
                    }
                }
                if ($category->id && $category->id == $category->id_parent) {
                    $this->errors[] = Tools::displayError('A category cannot be its own parent');
                    continue;
                }
                /* No automatic nTree regeneration for import */
                $category->doNotRegenerateNTree = true;
                // If id category AND id category already in base, trying to update
                $categories_home_root = array(Configuration::get('PS_ROOT_CATEGORY'), Configuration::get('PS_HOME_CATEGORY'));
                if ($category->id && $category->categoryExists($category->id) && !in_array($category->id, $categories_home_root)) {
                    $res = $category->update();
                }
                if ($category->id == Configuration::get('PS_ROOT_CATEGORY')) {
                    $this->errors[] = Tools::displayError('The root category cannot be modified.');
                }
                // If no id_category or update failed
                $category->force_id = (bool) Tools::getValue('forceIDs');
                if (!$res) {
                    $res = $category->add();
                }
            }
            //copying images of categories
            if (isset($category->image) && !empty($category->image)) {
                if (!AdminImportController::copyImg($category->id, null, $category->image, 'categories', !Tools::getValue('regenerate'))) {
                    $this->warnings[] = $category->image . ' ' . Tools::displayError('cannot be copied.');
                }
            }
            // If both failed, mysql error
            if (!$res) {
                $this->errors[] = sprintf(Tools::displayError('%1$s (ID: %2$s) cannot be saved'), isset($info['name']) && !empty($info['name']) ? Tools::safeOutput($info['name']) : 'No Name', isset($info['id']) && !empty($info['id']) ? Tools::safeOutput($info['id']) : 'No ID');
                $error_tmp = ($field_error !== true ? $field_error : '') . (isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '') . Db::getInstance()->getMsgError();
                if ($error_tmp != '') {
                    $this->errors[] = $error_tmp;
                }
            } else {
                // Associate category to shop
                if (Shop::isFeatureActive()) {
                    Db::getInstance()->execute('
						DELETE FROM ' . _DB_PREFIX_ . 'category_shop
						WHERE id_category = ' . (int) $category->id);
                    if (!Shop::isFeatureActive()) {
                        $info['shop'] = 1;
                    } elseif (!isset($info['shop']) || empty($info['shop'])) {
                        $info['shop'] = implode($this->multiple_value_separator, Shop::getContextListShopID());
                    }
                    // Get shops for each attributes
                    $info['shop'] = explode($this->multiple_value_separator, $info['shop']);
                    foreach ($info['shop'] as $shop) {
                        if (!empty($shop) && !is_numeric($shop)) {
                            $category->addShop(Shop::getIdByName($shop));
                        } elseif (!empty($shop)) {
                            $category->addShop($shop);
                        }
                    }
                }
            }
        }
        /* Import has finished, we can regenerate the categories nested tree */
        Category::regenerateEntireNtree();
        $this->closeCsvFile($handle);
    }