3

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

  • 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 at 5:28
3

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();
}
  • great @Khoa. it is create category in admin but it is not get visible in frontend navigation menu. I could compare with existing category but no difference found, all settings are same. what can I do now? – Bilal Usean May 9 '16 at 14:15
  • We should try $category->setIncludeInMenu(1). We should take a look more detail here: vendor/magento/module-catalog/Setup/CategorySetup.php – Khoa TruongDinh May 9 '16 at 14:29
  • how to check if the category exist? – Bilal Usean May 9 '16 at 14:47
  • From your post here: magento.stackexchange.com/questions/114637/…. We can try !isset($cate->getId()) – Khoa TruongDinh May 10 '16 at 5:45
  • thanks @Khoa please update your answer with category check it is useful to others – Bilal Usean May 10 '16 at 5:46
2

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;
    }
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();
0

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

//Check exist category
$cate = $category->getCollection()
            ->addAttributeToFilter('name',['like' => $value])
            ->getFirstItem();
  • 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.

0

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;
}
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.