Magento – Magento 2: add fields to products collection

collection;gridmagento2product

Ok so I'm trying to implement a simple export to CSV massaction on the Magento 2 Catalog products grid.

I've successfully created the mass action item, as well as the admin controller.

I am able to retrieve a CSV, however, it is missing the following fields from the original catalog products grid, I do not understand why:

  • Product name
  • Price
  • Special Price

Basically I want to be able to retrieve the product collection generated in app\code\Magento\Catalog\Block\Adminhtml\Product\Grid.php and to use it in my controller.

I've based my controller development on another massaction controller thinking it would do the trick but it does not.

Here is my admin controller:

<?php
namespace DigitalPianism\ProductExport\Controller\Adminhtml\Productexport;

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\Response\Http\FileFactory;
use Magento\Framework\Controller\ResultFactory;
use Magento\Catalog\Controller\Adminhtml\Product\Builder;
use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;

class ExportCsv extends \Magento\Catalog\Controller\Adminhtml\Product
{
    /**
     * Massactions filter
     *
     * @var Filter
     */
    protected $filter;

    /**
     * @var CollectionFactory
     */
    protected $collectionFactory;

    /**
     * @var \Magento\Framework\App\Response\Http\FileFactory
     */
    protected $_fileFactory;

    /**
     * @param Context $context
     * @param Builder $productBuilder
     * @param Filter $filter
     * @param CollectionFactory $collectionFactory
     */
    public function __construct(
        Context $context,
        Builder $productBuilder,
        Filter $filter,
        CollectionFactory $collectionFactory,
        FileFactory $fileFactory
    ) {
        $this->filter = $filter;
        $this->collectionFactory = $collectionFactory;
        $this->_fileFactory = $fileFactory;
        parent::__construct($context, $productBuilder);
    }

    /**
     * @return \Magento\Backend\Model\View\Result\Redirect
     */
    public function execute()
    {
        $collection = $this->filter->getCollection($this->collectionFactory->create());
        // Write headers to the csv file
        $content = "id,name,url,sku,price,special_price\n";
        foreach ($collection->getItems() as $product) {
            $content .= "\"{$product->getId()}\",\"{$product->getName()}\",\"{$product->getProductUrl()}\",\"{$product->getSku()}\",\"{$product->getPrice()}\",\"{$product->getSpecialPrice()}\"\n";
        }
        // Return the CSV file
        $fileName = 'products.csv';
        return $this->_fileFactory->create(
            $fileName,
            $content,
            DirectoryList::VAR_DIR
        );
    }

    /**
     * Customer access rights checking
     *
     * @return bool
     */
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('Magento_Catalog::manage');
    }
}

Best Answer

I was using \Magento\Catalog\Api\ProductRepositoryInterface to get all the list of my products. Try this instead.

protected $productRepository;

protected $searchCriteriaBuilder;

public function __construct(
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
    \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
) {
    $this->productRepository = $productRepository;
    $this->searchCriteriaBuilder = $searchCriteriaBuilder;
}

public function execute()
{
    // *** You may add filter rules for your query.
    $searchCriteria = $this->searchCriteriaBuilder->create();

    // *** Retrieve all products based on search criteria
    $list = $this->productRepository->getList($searchCriteria);

    foreach ($list->getItems() as $item) {
        var_dump($item->getName(), $item->getPrice(), $item->getSpecialPrice());
    }
}
Related Topic