Question

I have to need import export categories in csv same as product, in Magento 2 provided same thing for product.

I have tried below code but facing issue in Model file path Vendor/CategoryImportExport/Model/Export/Category.php here need to categories data and after generate csv but I can't getting that details.

I have added Entity Type catalog_category in etc/export.xml for Category and it's displaying fine in Entity Type Dropdown.

File path: magento/app/code/Vendor/CategoryImportExport/etc/export.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_ImportExport:etc/export.xsd">
    <entity name="catalog_category" label="Category" model="Vendor\CategoryImportExport\Model\Export\Category" entityAttributeFilterType="catalog_category"/>
    <fileFormat name="csv" label="CSV" model="Magento\ImportExport\Model\Export\Adapter\Csv" />
</config>

File path: magento/app/code/Vendor/CategoryImportExport/Model/Export/Category.php

class Category extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
{    
    public function export()
    {
        //Execution time may be very long
        set_time_limit(0);

        $writer = $this->getWriter();
        $page = 0;
        while (true) {
            ++$page;
            $entityCollection = $this->_getEntityCollection(true);
            $entityCollection->setOrder('entity_id', 'asc');
            $entityCollection->setStoreId(Store::DEFAULT_STORE_ID);
            $this->_prepareEntityCollection($entityCollection);
            $this->paginateCollection($page, $this->getItemsPerPage());
            if ($entityCollection->count() == 0) {
                break;
            }
            $exportData = $this->getExportData();
            if ($page == 1) {
                $writer->setHeaderCols($this->_getHeaderColumns());
            }
            foreach ($exportData as $dataRow) {
                $writer->writeRow($this->_customFieldsMapping($dataRow));
            }
            if ($entityCollection->getCurPage() >= $entityCollection->getLastPageNumber()) {
                break;
            }
        }
        return $writer->getContents();
    }    
}

Any have idea how to import export Categories in csv then let me know.

Any help would be appreciated. Thanks.

Was it helpful?

Solution

I have fixed issue to update the export() function code.

<?php
namespace Vendor\CategoryImportExport\Model\Export;

use Magento\Catalog\Model\ResourceModel\Category\Collection;
use Magento\ImportExport\Model\Import;
use \Magento\Store\Model\Store;
use \Vendor\CategoryImportExport\Model\Import\Category as ImportCategory;
use Magento\Catalog\Model\Category as ProductEntity;

class Category extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
{
    /**
     * @var \Magento\Framework\App\Response\Http\FileFactory
     */
    protected $fileFactory;

    /**
     * CSV Processor
     *
     * @var \Magento\Framework\File\Csv
     */
    protected $csvProcessor;

    /**
     * @var DirectoryList
     */
    protected $directoryList;

    /**
     * Category collection factory
     *
     * @var \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory
     */
    protected $_categoryCollectionFactory;

    /**
     * @var \Magento\Catalog\Helper\Category
     */
    protected $_categoryHelper;

    /**
     * Product collection factory
     *
     * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
     */
    protected $_productCollectionFactory;

    /**
     * @var \Magento\Catalog\Model\CategoryFactory
     */
    protected $_categoryFactory;

    /**
     * Attributes that should be exported
     *
     * @var string[]
     */
    protected $_bannedAttributes = ['media_gallery'];

    /**
     * Array of supported product types as keys with appropriate model object as value.
     *
     * @var array
     */
    protected $_productTypeModels = [];

    /**
     * Product collection
     *
     * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
     */
    protected $_entityCollectionFactory;

    /**
     * Product collection
     *
     * @var \Magento\Catalog\Model\ResourceModel\Product\Collection
     */
    protected $_entityCollection;

    /**
     * Items per page for collection limitation
     *
     * @var int|null
     */
    protected $_itemsPerPage = null;

    /**
     * Header columns for export file
     *
     * @var array
     * @deprecated 100.2.0
     */
    protected $_headerColumns = [];

    /**
     * @var \Magento\ImportExport\Model\Export\ConfigInterface
     */
    protected $_exportConfig;

    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $_logger;

    /**
     * @var \Magento\Catalog\Model\ResourceModel\ProductFactory
     */
    protected $_productFactory;

    /**
     * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection
     */
    protected $_attrSetColFactory;

    /**
     * @var \Magento\Catalog\Model\ResourceModel\Category\Collection
     */
    protected $_categoryColFactory;

    /**
     * @var \Magento\Framework\App\ResourceConnection
     */
    protected $_resourceModel;

    /**
     * @var \Magento\CatalogInventory\Model\ResourceModel\Stock\ItemFactory
     */
    protected $_itemFactory;

    /**
     * @var Collection
     */
    protected $_optionColFactory;

    /**
     * @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection
     */
    protected $_attributeColFactory;

    /**
     * @var \Magento\CatalogImportExport\Model\Export\Product\Type\Factory
     */
    protected $_typeFactory;

    /**
     * Provider of product link types
     *
     * @var \Magento\Catalog\Model\Product\LinkTypeProvider
     */
    protected $_linkTypeProvider;

    /**
     * @var \Magento\CatalogImportExport\Model\Export\RowCustomizerInterface
     */
    protected $rowCustomizer;

    /**
     * Attributes codes which shows as date
     *
     * @var array
     * @since 100.1.2
     */
    protected $dateAttrCodes = [
        'custom_design_from',
        'custom_design_to'
    ];

    /**
     * Attributes codes which are appropriate for export and not the part of additional_attributes.
     *
     * @var array
     */
    protected $_exportMainAttrCodes = [
        'all_children',
        'available_sort_by',
        'children',
        'children_count',
        'custom_apply_to_products',
        'custom_design',
        'custom_design_from',
        'custom_design_to',
        'custom_layout_update',
        'custom_use_parent_settings',
        'default_sort_by',
        'description',
        'display_mode',
        'filter_price_range',
        'image',
        'include_in_menu',
        'is_active',
        'is_anchor',
        'landing_page',
        'name',
        'name',
        'url_key',
        'url_path',
    ];

    public function __construct(
        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
        \Magento\Eav\Model\Config $config,
        \Magento\Framework\App\ResourceConnection $resource,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $collectionFactory,
        \Magento\ImportExport\Model\Export\ConfigInterface $exportConfig,
        \Magento\Catalog\Model\ResourceModel\ProductFactory $productFactory,
        \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory $attrSetColFactory,
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryColFactory,
        \Magento\CatalogInventory\Model\ResourceModel\Stock\ItemFactory $itemFactory,
        \Magento\Catalog\Model\ResourceModel\Product\Option\CollectionFactory $optionColFactory,
        \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory $attributeColFactory,
        \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider,
        \Magento\CatalogImportExport\Model\Export\RowCustomizerInterface $rowCustomizer,
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
        \Magento\Catalog\Helper\Category $categoryHelper,
        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
        \Magento\Framework\File\Csv $csvProcessor,
        \Magento\Framework\App\Filesystem\DirectoryList $directoryList,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
        array $dateAttrCodes = []
    ) {
        $this->_entityCollectionFactory = $collectionFactory;
        $this->_exportConfig = $exportConfig;
        $this->_logger = $logger;
        $this->_productFactory = $productFactory;
        $this->_attrSetColFactory = $attrSetColFactory;
        $this->_categoryColFactory = $categoryColFactory;
        $this->_resourceModel = $resource;
        $this->_itemFactory = $itemFactory;
        $this->_optionColFactory = $optionColFactory;
        $this->_attributeColFactory = $attributeColFactory;
        $this->_linkTypeProvider = $linkTypeProvider;
        $this->rowCustomizer = $rowCustomizer;
        $this->_categoryCollectionFactory = $categoryCollectionFactory;
        $this->_categoryHelper = $categoryHelper;
        $this->dateAttrCodes = array_merge($this->dateAttrCodes, $dateAttrCodes);

        $this->fileFactory = $fileFactory;
        $this->csvProcessor = $csvProcessor;
        $this->directoryList = $directoryList;

        $this->_categoryFactory = $categoryFactory;
        $this->_productCollectionFactory = $productCollectionFactory;

        parent::__construct($localeDate, $config, $resource, $storeManager);
    }

    /**
     * Get header columns
     *
     * @return string[]
     */
    public function _getHeaderColumns()
    {
        return $this->_customHeadersMapping($this->rowCustomizer->addHeaderColumns($this->_headerColumns));
    }

    /**
     * Get entity collection
     *
     * @param bool $resetCollection
     * @return \Magento\Framework\Data\Collection\AbstractDb
     */
    protected function _getEntityCollection($resetCollection = false)
    {
        if ($resetCollection || empty($this->_entityCollection)) {
            $this->_entityCollection = $this->_entityCollectionFactory->create();
        }
        return $this->_entityCollection;
    }

    /**
     * Get items per page
     *
     * @return int
     */
    protected function getItemsPerPage()
    {
        if ($this->_itemsPerPage === null) {
            $memoryLimitConfigValue = trim(ini_get('memory_limit'));
            $lastMemoryLimitLetter = strtolower($memoryLimitConfigValue[strlen($memoryLimitConfigValue) - 1]);
            $memoryLimit = (int) $memoryLimitConfigValue;
            switch ($lastMemoryLimitLetter) {
                case 'g':
                    $memoryLimit *= 1024;
                    // fall-through intentional
                case 'm':
                    $memoryLimit *= 1024;
                    // fall-through intentional
                case 'k':
                    $memoryLimit *= 1024;
                    break;
                default:
                    // minimum memory required by Magento
                    $memoryLimit = 250000000;
            }

            // Tested one product to have up to such size
            $memoryPerProduct = 500000;
            // Decrease memory limit to have supply
            $memoryUsagePercent = 0.8;
            // Minimum Products limit
            $minProductsLimit = 500;
            // Maximal Products limit
            $maxProductsLimit = 5000;

            $this->_itemsPerPage = (int)(
                ($memoryLimit * $memoryUsagePercent - memory_get_usage(true)) / $memoryPerProduct
            );
            if ($this->_itemsPerPage < $minProductsLimit) {
                $this->_itemsPerPage = $minProductsLimit;
            }
            if ($this->_itemsPerPage > $maxProductsLimit) {
                $this->_itemsPerPage = $maxProductsLimit;
            }
        }
        return $this->_itemsPerPage;
    }

    /**
     * Set page and page size to collection
     *
     * @param int $page
     * @param int $pageSize
     * @return void
     */
    protected function paginateCollection($page, $pageSize)
    {
        $this->_getEntityCollection()->setPage($page, $pageSize);
    }

    /**
     * Export process
     *
     * @return string
     */
    public function export()
    {
        //Execution time may be very long
        set_time_limit(0);

        $writer = $this->getWriter();
        $page = 0;
        while (true) {
            ++$page;
            $entityCollection = $this->_getEntityCollection(true);
            $entityCollection->setOrder('entity_id', 'asc');
            $entityCollection->setStoreId(Store::DEFAULT_STORE_ID);
            $this->_prepareEntityCollection($entityCollection);
            $this->paginateCollection($page, $this->getItemsPerPage());
            if ($entityCollection->count() == 0) {
                break;
            }
            $exportData = $this->getExportData();

            $fileName = 'catalog_category.csv';
            $filePath = $this->directoryList->getPath(\Magento\Framework\App\Filesystem\DirectoryList::VAR_DIR). "/" . $fileName;

            $categoryCollectionData = $this->getCategoryCsvData($exportData);
            $this->csvProcessor
                ->setDelimiter(',')
                ->setEnclosure('"')
                ->saveData(
                    $filePath,
                    $categoryCollectionData
                );

            return $this->fileFactory->create(
                $fileName,
                [
                    'type' => "filename",
                    'value' => $fileName,
                    'rm' => true,
                ],
                \Magento\Framework\App\Filesystem\DirectoryList::VAR_DIR,
                'application/octet-stream'
            );
        }
        return $writer->getContents();
    }

    protected function getCategoryCsvData($exportData)
    {
        $result = [];
        $exportCategoryData = $exportData;

        $storeId = $this->_storeManager->getStore()->getId();

        $result[] = [
            'category',
            'parent',
            'description',
            'is_active',
            'include_in_menu',
            'url_key',
            'meta_title',
            'meta_keywords',
            'meta_description',
            'is_anchor',
            'default_product_listing_sort_by',
            'image',
            'display_mode',
            'landing_page',
            'custom_design',
            'position',
            'page_layout',
            'custom_design_from',
            'custom_design_to',
            'custom_use_parent_settings',
            'custom_apply_to_products',
            'custom_layout_update',
            'store',
            'path'
        ];
        foreach ($exportCategoryData as $csvData) {
            $result[] = [
                isset($csvData['name']) ? $csvData['name'] : '',
                isset($csvData['parent_id']) ? $csvData['parent_id'] : '',
                isset($csvData['description']) ? $csvData['description'] : '',
                isset($csvData['is_active']) ? $csvData['is_active'] : '',
                isset($csvData['include_in_menu']) ? $csvData['include_in_menu'] : '',
                isset($csvData['url_key']) ? $csvData['url_key'] : '',
                isset($csvData['meta_title']) ? $csvData['meta_title'] : '',
                isset($csvData['meta_keywords']) ? $csvData['meta_keywords'] : '',
                isset($csvData['meta_description']) ? $csvData['meta_description'] : '',
                isset($csvData['is_anchor']) ? $csvData['is_anchor'] : '',
                isset($csvData['default_product_listing_sort_by']) ? $csvData['default_product_listing_sort_by'] : '',
                isset($csvData['image']) ? $csvData['image'] : '',
                isset($csvData['display_mode']) ? $csvData['display_mode'] : '',
                isset($csvData['landing_page']) ? $csvData['landing_page'] : '',
                isset($csvData['custom_design']) ? $csvData['custom_design'] : '',
                isset($csvData['position']) ? $csvData['position'] : '',
                isset($csvData['page_layout']) ? $csvData['page_layout'] : '',
                isset($csvData['custom_design_from']) ? $csvData['custom_design_from'] : '',
                isset($csvData['custom_design_to']) ? $csvData['custom_design_to'] : '',
                isset($csvData['custom_use_parent_settings']) ? $csvData['custom_use_parent_settings'] : '',
                isset($csvData['custom_apply_to_products']) ? $csvData['custom_apply_to_products'] : '',
                isset($csvData['custom_layout_update']) ? $csvData['custom_layout_update'] : '',
                isset($storeId) ? $storeId : '',
                isset($csvData['path']) ? $csvData['path'] : ''
            ];
        }
        return $result;
    }

    /**
     * Get export data for collection
     *
     * @return array
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
     */
    protected function getExportData()
    {
        $exportData = [];

        $isActive = true;
        $level = false;
        $sortBy = false;
        $pageSize = false;

        try {
            $collection = $this->_categoryCollectionFactory->create()
                ->addAttributeToSelect('*')
                ->setStore($this->_storeManager->getStore()->getId());
               // ->addAttributeToFilter('is_active','1');
            foreach ($collection as $index => $value) {
                $categoryIdProduct = $value->getEntityId();

                $categoryId = $categoryIdProduct;
                $category = $this->_categoryFactory->create()->load($categoryId);
                $exportData[$index] = $value->getData();
            }
        } catch (\Exception $e) {
            $this->_logger->critical($e);
        }
        return $exportData;
    }

    /**
     * Clean up already loaded attribute collection.
     *
     * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection $collection
     * @return \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection
     */
    public function filterAttributeCollection(\Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection $collection)
    {
        $validTypes = array_keys($this->_productTypeModels);
        $validTypes = array_combine($validTypes, $validTypes);
        foreach (parent::filterAttributeCollection($collection) as $attribute) {
            if (in_array($attribute->getAttributeCode(), $this->_bannedAttributes)) {
                $collection->removeItemByKey($attribute->getId());
                continue;
            }
            $attrApplyTo = $attribute->getApplyTo();
            $attrApplyTo = array_combine($attrApplyTo, $attrApplyTo);
            $attrApplyTo = $attrApplyTo ? array_intersect_key($attrApplyTo, $validTypes) : $validTypes;

            if ($attrApplyTo) {
                foreach ($attrApplyTo as $productType) {
                    // override attributes by its product type model
                    if ($this->_productTypeModels[$productType]->overrideAttribute($attribute)) {
                        break;
                    }
                }
            } else {
                // remove attributes of not-supported product types
                $collection->removeItemByKey($attribute->getId());
            }
        }
        return $collection;
    }

    /**
     * Entity attributes collection getter.
     *
     * @return \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection
     */
    public function getAttributeCollection()
    {
        return $this->_attributeColFactory->create();
    }

    /**
     * EAV entity type code getter.
     *
     * @return string
     */
    public function getEntityTypeCode()
    {
        return 'catalog_category';
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top