1

I was wondering if there was a better way to use the resources than object manager, here is how i'm currently using the category factory's. I am very new to Magento.

<?php

namespace XX\TierPriceSummary\Block\Adminhtml\Index;

class Index extends \Magento\Backend\Block\Widget\Container
{

    protected $_customerGroupsCollection;
    protected $_productRepository;
    protected $_resource;
    private   $storeID = 1;

    public function __construct(
        \Magento\Backend\Block\Widget\Context $context,
        \Magento\Customer\Model\ResourceModel\Group\Collection $customerGroupsCollection,
        \Magento\Catalog\Model\ProductRepository $productRepository,
        \Magento\Framework\App\ResourceConnection $resource,
        array $data = []
    ) {
        $this->_customerGroupsCollection = $customerGroupsCollection;
        $this->_productRepository = $productRepository;
        $this->_resource = $resource;
        parent::__construct(
            $context,
            $data
        );
    }

    private function getProductTierPrice($SubCategoryID,$pID,$groupID){
        $objectManager =  \Magento\Framework\App\ObjectManager::getInstance();    
        $categoryFactory = $objectManager->get('\Magento\Catalog\Model\CategoryFactory');
        $categoryHelper = $objectManager->get('\Magento\Catalog\Helper\Category');
        $categoryRepository = $objectManager->get('\Magento\Catalog\Model\CategoryRepository');

        //do something
        } 

}
gazZz
  • 97
  • 9

2 Answers2

1

Yes, definitely. You should use dependency injection like how ProductRepository is being used in your example.

Using ObjectManager is discouraged by Magento. https://devdocs.magento.com/guides/v2.3/extension-dev-guide/object-manager.html

<?php 
namespace XX\TierPriceSummary\Block\Adminhtml\Index;

class Index extends \Magento\Backend\Block\Widget\Container
{

protected $_customerGroupsCollection;
protected $_productRepository;
protected $_categoryFactory;
protected $_resource;
private   $storeID = 1;

public function __construct(
    \Magento\Backend\Block\Widget\Context $context,
    \Magento\Customer\Model\ResourceModel\Group\Collection $customerGroupsCollection,
    \Magento\Catalog\Model\ProductRepository $productRepository,
    \Magento\Framework\App\ResourceConnection $resource,
    \Magento\Catalog\Model\CategoryFactory $categoryFactory,
    array $data = []
) {
    $this->_customerGroupsCollection = $customerGroupsCollection;
    $this->_productRepository = $productRepository;
    $this->_resource = $resource;
    $this->_categoryFactory = $categoryFactory;

    parent::__construct(
        $context,
        $data
    );
}

private function getProductTierPrice($SubCategoryID,$pID,$groupID){
    $objectManager =  \Magento\Framework\App\ObjectManager::getInstance();    

    $categoryHelper = $objectManager->get('\Magento\Catalog\Helper\Category');
    $categoryRepository = $objectManager->get('\Magento\Catalog\Model\CategoryRepository');

    //do something with $this->_categoryFactory
    } 
}
mapetek
  • 387
  • 2
  • 12
0

Yes.

By putting the class definitions in your __construct method, Magento will automatically inject them when the class is created. Here is how you would do so:

<?php

namespace XX\TierPriceSummary\Block\Adminhtml\Index;

class Index extends \Magento\Backend\Block\Widget\Container
{

    protected $_customerGroupsCollection;
    protected $_productRepository;
    protected $_resource;
    private   $storeID = 1;

    protected $_categoryFactory;

    public function __construct(
        \Magento\Backend\Block\Widget\Context $context,
        \Magento\Customer\Model\ResourceModel\Group\Collection $customerGroupsCollection,
        \Magento\Catalog\Model\ProductRepository $productRepository,
        \Magento\Framework\App\ResourceConnection $resource,
        \Magento\Catalog\Model\CategoryFactory $categoryFactory, //new definition
        array $data = []
    ) {
        $this->_customerGroupsCollection = $customerGroupsCollection;
        $this->_productRepository = $productRepository;
        $this->_resource = $resource;
        $this->_categoryFactory = $categoryFactory; //assign new definition to a protected/private var
        parent::__construct(
            $context,
            $data
        );
    }

    private function getProductTierPrice($SubCategoryID,$pID,$groupID){
        $this->_categoryFactory->create(); //use the category factory
    }
Adam Mellen
  • 339
  • 1
  • 11
  • I did try that but i got [2020-01-17 09:05:57] main.CRITICAL: Type Error occurred when creating object: XX\TierPriceSummary\Block\Adminhtml\Index\Index, Argument 5 passed to XX\TierPriceSummary\Block\Adminhtml\Index\Index::__construct() must be an instance of Magento\Catalog\Model\CategoryFactory, array given, called in /domains/gaz.development.co.uk/http/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 116 [] [] – gazZz Jan 17 '20 at 09:06
  • Run setup:di:compile – vitoriodachef Jan 17 '20 at 09:20
  • @Adam, thats normal. You have to run php bin/magento setup:upgrade. If it still fails, then you have to delete the folder generated/code and execute the command again. – Black Jan 17 '20 at 10:29
  • You wouldn't have to run setup:upgrade. At worst, given the example error from OP, you just run rm -rf generated/code/* (in developer mode; in production mode you'd run bin/magento setup:di:compile) to force the classes to be regenerated. – Adam Mellen Jan 17 '20 at 13:22
  • @AdamMellen, I faced this error very often and setup:upgrade is the solution. (I am in developer mode) – Black Jan 17 '20 at 13:54
  • I needed to run Run setup:di:compile – gazZz Jan 17 '20 at 13:59