6

I have one custom table, that table have a column name category which contains the events category like entertainment, national events. Now I need to create category from the table?

note: create category itself enough, don't need to add any products.

I tried with create one category by object manager if the category not exist but it does not work.

    $parentCategory = $this->_objectManager
         ->create('Magento\Catalog\Model\Category')
         ->load('115');
    $category = $this->_objectManager
         ->create('Magento\Catalog\Model\Category');
    $cate=$category->getCollection()->addAttributeToFilter('name',$d["type"])
    ->getFirstItem();
    if(!isset($cate))
    {
    $category->setPath($parentCategory->getPath())
    ->setParentId('115')
    ->setName($d["type"])
    ->setIsActive(true);
    $category->save();
    }

how to deal with automatically create category from table, if not exist already.

Thanks

Himanshu
  • 1,761
  • 17
  • 34
Bilal Usean
  • 9,977
  • 14
  • 75
  • 122
  • Have got any solution how to csv import categories? I have facing issue in csv import categories. Let me know if you have any solution. Any help would be appreciated. Thanks. – Kirti Nariya Jun 20 '19 at 05:28

6 Answers6

5

We need to identify the id of category tree root. Then, we created an instance of the category, set its path, parent_id, name, etc.

/**
 * Id of category tree root
 */
$parentId = \Magento\Catalog\Model\Category::TREE_ROOT_ID;

$parentCategory = $this->_objectManager
                      ->create('Magento\Catalog\Model\Category')
                      ->load($parentId);
$category = $this->_objectManager
                ->create('Magento\Catalog\Model\Category');
//Check exist category
$cate = $category->getCollection()
            ->addAttributeToFilter('name','test')
            ->getFirstItem();

if(!isset($cate->getId())) {
    $category->setPath($parentCategory->getPath())
        ->setParentId($parentId)
        ->setName('test')
        ->setIsActive(true);
    $category->save();
}
Khoa TruongDinh
  • 32,054
  • 11
  • 88
  • 155
5

Consider using the Factory pattern for this instead of the object manager (unless you're putting this function in a factory class itself)

class MyClass 
{

    protected $storeManager;

    protected $categoryFactory;

    public function __construct(
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Catalog\Model\CategoryFactory $categoryFactory
    ) {
        $this->storeManager = $storeManager;
        $this->categoryFactory = $categoryFactory;
    }

    public function fetchOrCreateProductCategory($categoryName)
    {
        // get the current stores root category
        $parentId = $this->storeManager->getStore()->getRootCategoryId();

        $parentCategory = $this->categoryFactory->create()->load($parentId);

        $category = $this->categoryFactory->create();
        $cate = $category->getCollection()
            ->addAttributeToFilter('name', $categoryName)
            ->getFirstItem();

        if (!$cate->getId()) {
            $category->setPath($parentCategory->getPath())
                ->setParentId($parentId)
                ->setName($categoryName)
                ->setIsActive(true);
            $category->save();
        }

        return $category;
    }
paul_c
  • 51
  • 1
  • 2
1

it will help me to add create category programaticaly.

// catagory name
$cat_name = ucfirst($cat_val);
$site_url = strtolower($cat_val);
$clean_url = trim(preg_replace('/ +/', '', preg_replace('/[^A-Za-z0-9 ]/', '', urldecode(html_entity_decode(strip_tags($site_url))))));
$category_factory=$objectManager->get('\Magento\Catalog\Model\CategoryFactory');
// Add a new sub category under root category
$category_obj = $category_factory->create();
$category_obj->setName($cat_name);
$category_obj->setIsActive(true);
$category_obj->setUrlKey($clean_url);
$category_obj->setData('description', 'description');
$category_obj->setParentId($root_cat_id->getId());
$mediaAttribute = array ('image', 'small_image', 'thumbnail');
$category_obj->setImage('/catagory_img.png', $mediaAttribute, true, false);
// add image at Path of  pub/meida/catalog/category/catagory_img.png
// add store id 
$category_obj->setStoreId($store_Id);
$category_obj->setPath($root_cat_id->getPath());
// save category
$category_obj->save();
Marius
  • 197,939
  • 53
  • 422
  • 830
Dhaval Dave
  • 426
  • 1
  • 5
  • 14
1

I was trying to add new categories using an update script and all of the answers after a quick search on stack overflow weren't satisfying due to either not respecting Magento pattern or using deprecated methods. So I startet investigation the Magento core (EE 2.3.1), because you'll always find an answer there, when digging in with some breakpoints.

If you take a close look at the class Magento\Catalog\Setup\CategorySetup you'll find a function createCategory which uses a factory to generate a new category Object. So all you need is to pass in the specific category values and then use the categoryResourceModel to save the new category afterwards.

namespace Vendor\Project\Setup\UpgradeData;

use \Magento\Catalog\Model\ResourceModel\Category;
use \Magento\Catalog\Setup\CategorySetup;
use \agento\Framework\Setup\UpgradeDataInterface;
use \Magento\Framework\Setup\ModuleDataSetupInterface;
use \Magento\Framework\Setup\ModuleContextInterface;

class V01_00_04 implements UpgradeDataInterface
{

const CATEGORIES
    = [
        [
            'parent_id' => 2,
            'name'      => 'name1',
            'path'      => '1/2'
        ],
        [
            'parent_id' => 3,
            'name'      => 'name2',
            'path'      => '1/2'
        ]
    ];

/** @var \Magento\Catalog\Model\ResourceModel\Category */
protected $categoryResourceModel;
/** @var \Magento\Catalog\Setup\CategorySetup */
protected $categorySetup;

/**
 * V01_00_04 constructor.
 *
 * @param \Magento\Catalog\Model\ResourceModel\Category $categoryResourceModel
 * @param \Magento\Catalog\Setup\CategorySetup          $categorySetup
 */
public function __construct(
    Category $categoryResourceModel,
    CategorySetup $categorySetup
) {
    $this->categorySetup         = $categorySetup;
    $this->categoryResourceModel = $categoryResourceModel;
}

/**
 * @param ModuleDataSetupInterface $setup
 * @param ModuleContextInterface   $context
 */
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
    foreach (self::CATEGORIES as $category) {
        $this->addCategories($category);
    }
}

/**
 * Create new category object and save it via ResourceModel
 */ 
private function addCategories(array $category)
{
    $new_category = $this->categorySetup->createCategory(
        [
            'data' => [
                'parent_id'       => $category['parent_id'],
                'name'            => $category['name'],
                'path'            => $category['path'],
                'is_active'       => 1,
                'include_in_menu' => 1,
            ],
        ]
    );
    $this->categoryResourceModel->save($new_category);

    return $category;
}
}
jmm
  • 11
  • 1
0

When working with names I think it's better to use like

//Check exist category
$cate = $category->getCollection()
            ->addAttributeToFilter('name',['like' => $value])
            ->getFirstItem();
Joachim Vanthuyne
  • 431
  • 1
  • 7
  • 16
  • 1
    thanks, but I think its not suitable for my requirement. for example I need to add "coffee" category if not exist, please assume already "coffee chocolate" category exist. now the point is your code give result of "coffee" category already exist. am I right? – Bilal Usean May 11 '16 at 12:48
  • No , that will only be true if you add % after $value.'%' LIKE 'coffe%' would return true on 'coffee chocolate' – Joachim Vanthuyne May 11 '16 at 12:54
  • OK, I will work on your answer afterthat I will comeback to you – Bilal Usean May 11 '16 at 12:57
0
    $categories = array(

array(

'name' => 'Homedfd Appliances fsdfsdfd',

'parent' => 97,

'child' => array(

'Television',

'AC & Coolers',

'Refrigerator',

'Microwave Oven',

'Fans', 'Kitchen Appliances',

'Other Appliances' )

),

array(

'name' => 'Compudfdter dsfd',

'parent' => 97,

'child' => array(

'Monitor',

'Hard Drive',

'Printer',

'Wireless & Networking',

'Webcams',

'Keyboard',

'Mouse'

)

),

array(

'name' => 'Groomsfding Products',

'parent' => 97,

'child' => array(

'Trimmers & Shavers',

'Hair Styling Tools'

)

),

array(

'name' => 'Moddbile & Tabs',

'parent' => 97,

'child' => array()

)

);
/** Calling to magento functionalities*/use \Magento\Framework\App\Bootstrap;include('./app/bootstrap.php');
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$url = \Magento\Framework\App\ObjectManager::getInstance();
$storeManager = $url->get('\Magento\Store\Model\StoreManagerInterface');
$mediaurl = $storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
$state = $objectManager->get('\Magento\Framework\App\State');

$state->setAreaCode('frontend');
$websiteId = $storeManager->getWebsite()->getWebsiteId();
$store = $storeManager->getStore();
$storeId =  $store->getStoreId();
$rootNodeId = $store->getRootCategoryId();
$categoryModel = $objectManager->get('Magento\Catalog\Model\Category');
$rootCategoryInfo = $categoryModel->load($rootNodeId);
$outputFile = fopen('catCreateResult.txt', 'w');
foreach($categories as $cat){
     $name=ucfirst($cat['name']); 
     $url=strtolower($cat['name']); 
     $cleanurl = trim(preg_replace('/ +/', '', preg_replace('/[^A-Za-z0-9 ]/', '', urldecode(html_entity_decode(strip_tags($url)))))); 
     $categoryFactory = $objectManager->get('\Magento\Catalog\Model\CategoryFactory'); 
     /// Add a new sub category under root category 
     $categoryTmp = $categoryFactory->create(); 
     $categoryTmp->setName($name); 
     $categoryTmp->setIsActive(true); 
   /* * If you want to include category description please ucomment below line 
   * As well as include a key with description value in category array and provide it on here. 
   */
    //$categoryTmp->setData('description', 'description'); 
     $categoryTmp->setParentId($cat['parent']); 
     $mediaAttribute = array ('image', 'small_image', 'thumbnail');
     /* * You can also set an category image. */
     //$categoryTmp->setImage('/m2.png', $mediaAttribute, true, false);
     // Path pub/meida/catalog/category/m2.png $categoryTmp->setStoreId($storeId); 
     $parentCategoryInfo = $categoryModel->load($cat['parent']); 
     $categoryTmp->setPath($parentCategoryInfo->getPath()); 
     $output = $categoryTmp->save(); 
     $newId = $output->getEntityId(); 
     if(count($cat['child']) > 0){ 
        foreach($cat['child'] as $sub_child){ 
        $name=ucfirst($sub_child); 
        $categoryFactory = $objectManager->get('\Magento\Catalog\Model\CategoryFactory'); 
        $categoryTmp = $categoryFactory->create(); 
        $categoryTmp->setName($name); 
        $categoryTmp->setIsActive(true); 
        $categoryTmp->setParentId($newId); 
        $mediaAttribute = array ('image', 'small_image', 'thumbnail'); 
        //$categoryTmp->setImage('/m2.png', $mediaAttribute, true, false);   // Path pub/meida/catalog/category/m2.png 
        $categoryTmp->setStoreId($storeId); 
        $parentCategoryInfo = $categoryModel->load($newId); 
        $categoryTmp->setPath($parentCategoryInfo->getPath()); 
        $categoryTmp->save(); 
       } 
    }
}

For More Description you may visit here.

DelwaR
  • 40
  • 2