Creating Configurable Product Programmatically in Magento 2

A configurable product is a combination of simple products (called child products) with different options like size, colour, material, etc. Each of the options presents a separate simple product with a unique SKU, which allows a store owner to track the inventory for each of the variations.

In Magento 2 admin panel, you can create any number of products. But if you want to create a configurable product programmatically by using an external script, this article will help you.

Initialize Object Manager And Set Area Code

While creating an external script, first you have to include the below code in the top of the file,

use Magento\Framework\App\Bootstrap;
 
/**
 * If the external file is in the root folder
 */
require __DIR__ . '/app/bootstrap.php';
 
$params = $_SERVER;
 
$bootstrap = Bootstrap::create(BP, $params);

The purpose of the above code is used to access the Magento 2 core functionality from your external file.

Moving on, use the below script to set the area code as adminhtml,

$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode(\Magento\Framework\App\Area::AREA_ADMINHTML);

Create Child Products

Before creating the configurable product, create simple products (child products) first that we will associate to the configurable product that we create later.

As you may know that in order to create new product in Magento 2, it’s necessary to use the \Magento\Catalog\Api\Data\ProductInterfaceFactory & \Magento\Catalog\Api\ProductRepositoryInterface classes in your custom script.

Here is an example code to create simple products with colour variations,

$productInterfaceFactory = $objectManager->create('Magento\Catalog\Api\Data\ProductInterfaceFactory');
$productRepository = $objectManager->create('Magento\Catalog\Api\ProductRepositoryInterface');
$optionsFactory = $objectManager->create('Magento\ConfigurableProduct\Helper\Product\Options\Factory');

$product = $productInterfaceFactory->create();

// Get the default attribute set id
$attributeSetId = $product->getDefaultAttributeSetId();

$attributeLabel = 'Color';
$attributeCode = 'color';
$attribute = $product->getResource()->getAttribute($attributeCode);
$options = $attribute->getOptions();
array_shift($options); // Remove the first option which is empty

$simpleProductIds = $attributeValues = [];
foreach ($options as $key => $option) {
    $simpleProduct = $productInterfaceFactory->create();
    $sku = $urlKey = 'simple-product-'.strtolower($option->getLabel());

    $simpleProduct->setSku($sku)
                  ->setName('Simple Product '.$option->getLabel())
                  ->setUrlKey($urlKey)
                  ->setAttributeSetId($attributeSetId)
                  ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
                  ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
                  ->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
                  ->setWeight(1) // Weight of the product
                  ->setTaxClassId(0) // Tax class id, 0 = None, 2 = Taxable Goods, etc.
                  ->setPrice(100) // Price of the product
                  ->setColor($option->getValue())
                  ->setWebsiteIds([1]) // Assign product to websites
                  ->setStockData(
                        [
                            'use_config_manage_stock' => 0,
                            'manage_stock' => 1,
                            'is_in_stock' => 1,
                            'qty' => 999999
                        ]
                    );

    $simpleProduct = $productRepository->save($simpleProduct);
    if ($simpleProduct->getId()) {
        $simpleProductIds[] = $simpleProduct->getId();
        $attributeValues[] = [
                'label' => $attributeLabel,
                'attribute_id' => $attribute->getId(),
                'value_index' => $option->getValue()
        ];
    }
}

Create Configurable Product And Assign Child Products To It

Now, use the below code to create the configurable product and associate the above created simple products to it.

$product = $productInterfaceFactory->create();
$configurableAttributesData = [
    [
        'attribute_id' => $attribute->getId(),
        'code' => $attribute->getAttributeCode(),
        'label' => $attribute->getStoreLabel(),
        'position' => '0',
        'values' => $attributeValues
    ]
];

$configurableOptions = $optionsFactory->create($configurableAttributesData);

$extensionConfigurableAttributes = $product->getExtensionAttributes();
$extensionConfigurableAttributes->setConfigurableProductOptions($configurableOptions);
$extensionConfigurableAttributes->setConfigurableProductLinks($simpleProductIds);
$product->setExtensionAttributes($extensionConfigurableAttributes);

$sku = $urlKey = 'test-configurable-product';
$product->setSku($sku)
        ->setName('Test Configurable Product')
        ->setUrlKey($urlKey)
        ->setAttributeSetId($attributeSetId)
        ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
        ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
        ->setTypeId(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE)
        ->setWebsiteIds([1])
        ->setCategoryIds([11, 12, 13]) // Assign product to categories using category id
        ->setStockData(
            [
                'use_config_manage_stock' => 1,
                'is_in_stock' => 1
            ]
        );

$product = $productRepository->save($product);
if ($product->getId()) {
    echo "Product Created Successfully";
}

Add Images To Product

Then, use the code below which is used to add the images to the product, Before running this script, the images should be placed in the pub/media/import/ folder.

$filesystem = $objectManager->create('\Magento\Framework\Filesystem');
$mediaDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);
$mediaPath = $mediaDirectory->getAbsolutePath();
$imagePath = $mediaPath .'import/sample.jpg'; // Path of the image
$product->addImageToMediaGallery($imagePath, ['image', 'small_image', 'thumbnail'], false, false);
$product->save();

Here is the complete code to create a configurable product in Magento 2 programmatically and assign the simple products (child products) to it,

<?php
use Magento\Framework\App\Bootstrap;
 
/**
 * If the external file is in the root folder
 */
require __DIR__ . '/app/bootstrap.php';
 
$params = $_SERVER;
 
$bootstrap = Bootstrap::create(BP, $params);
 
$objectManager = $bootstrap->getObjectManager();
 
// Set area code
$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode(\Magento\Framework\App\Area::AREA_ADMINHTML); // or \Magento\Framework\App\Area::AREA_FRONTEND, depending on your need
 
try {
    $productInterfaceFactory = $objectManager->create('Magento\Catalog\Api\Data\ProductInterfaceFactory');
    $productRepository = $objectManager->create('Magento\Catalog\Api\ProductRepositoryInterface');
    $optionsFactory = $objectManager->create('Magento\ConfigurableProduct\Helper\Product\Options\Factory');

    $product = $productInterfaceFactory->create();

    // Get the default attribute set id
    $attributeSetId = $product->getDefaultAttributeSetId();

    $attributeLabel = 'Color';
    $attributeCode = 'color';
    $attribute = $product->getResource()->getAttribute($attributeCode);
    $options = $attribute->getOptions();
    array_shift($options); // Remove the first option which is empty

    $simpleProductIds = $attributeValues = [];
    foreach ($options as $key => $option) {
        $simpleProduct = $productInterfaceFactory->create();
        $sku = $urlKey = 'simple-product-'.strtolower($option->getLabel());

        $simpleProduct->setSku($sku)
                  ->setName('Simple Product '.$option->getLabel())
                  ->setUrlKey($urlKey)
                  ->setAttributeSetId($attributeSetId)
                  ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
                  ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
                  ->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
                  ->setWeight(1) // Weight of the product
                  ->setTaxClassId(0) // Tax class id, 0 = None, 2 = Taxable Goods, etc.
                  ->setPrice(100) // Price of the product
                  ->setColor($option->getValue())
                  ->setWebsiteIds([1]) // Assign product to websites
                  ->setStockData(
                        [
                            'use_config_manage_stock' => 0,
                            'manage_stock' => 1,
                            'is_in_stock' => 1,
                            'qty' => 999999
                        ]
                    );

        $simpleProduct = $productRepository->save($simpleProduct);
        if ($simpleProduct->getId()) {
            $simpleProductIds[] = $simpleProduct->getId();
            $attributeValues[] = [
                'label' => $attributeLabel,
                'attribute_id' => $attribute->getId(),
                'value_index' => $option->getValue()
            ];
        }
    }


    $product = $productInterfaceFactory->create();
    $configurableAttributesData = [
        [
            'attribute_id' => $attribute->getId(),
            'code' => $attribute->getAttributeCode(),
            'label' => $attribute->getStoreLabel(),
            'position' => '0',
            'values' => $attributeValues
        ]
    ];
    $configurableOptions = $optionsFactory->create($configurableAttributesData);

    $extensionConfigurableAttributes = $product->getExtensionAttributes();
    $extensionConfigurableAttributes->setConfigurableProductOptions($configurableOptions);
    $extensionConfigurableAttributes->setConfigurableProductLinks($simpleProductIds);

    $product->setExtensionAttributes($extensionConfigurableAttributes);

    $sku = $urlKey = 'test-configurable-product';
    $product->setSku($sku)
            ->setName('Test Configurable Product')
            ->setUrlKey($urlKey)
            ->setAttributeSetId($attributeSetId)
            ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
            ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
            ->setTypeId(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE)
            ->setWebsiteIds([1])
            ->setCategoryIds([11, 12, 13]) // Assign product to categories using category id
            ->setStockData(
                [
                    'use_config_manage_stock' => 1, 
                    'is_in_stock' => 1
                ]
            );

    $product = $productRepository->save($product);

    if ($product->getId()) {
        echo "Product Created Successfully";
    }
 
    $filesystem = $objectManager->create('\Magento\Framework\Filesystem');
    $mediaDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);
    $mediaPath = $mediaDirectory->getAbsolutePath();
    $imagePath = $mediaPath .'import/sample.jpg'; // Path of the image
    $product->addImageToMediaGallery($imagePath, ['image', 'small_image', 'thumbnail'], false, false);
    $product->save();
 
} catch (\Exception $e) {
    echo $e->getMessage();
}

You may also like:

Hope this helps.

Leave a Reply

Your email address will not be published. Required fields are marked *