Creating Virtual Product Programmatically in Magento 2

Virtual product is one of the six types of product in Magento 2. The virtual products or digital goods are representing intangible items such as subscription, services, warranties, memberships, or any digital downloads (i.e, books, music, videos). In Magento 2, the virtual products can be sold individually or included as part of the grouped product or bundle product.

The main difference between a virtual product and a simple product in Magento 2 is that the virtual product does not have weight and can’t be touched, whereas the simple product has weight.

In Magento 2, you can create any number of products on the admin side. But in some cases like developing or testing the website, you may need to create a product programmatically by using an external script. Creating a custom script to add a product in Magento 2 is not difficult to work. In this article, you will learn how to create a virtual product in Magento 2 by a custom script.

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 Virtual Product

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. Use the code below to create a virtual product in Magento 2,

try {
    $productInterfaceFactory = $objectManager->create('Magento\Catalog\Api\Data\ProductInterfaceFactory');
    $productRepository = $objectManager->create('Magento\Catalog\Api\ProductRepositoryInterface');
 
    $product = $productInterfaceFactory->create();
 
    // Get the default attribute set id
    $attributeSetId = $product->getDefaultAttributeSetId();
      
    $sku = $urlKey = 'test-virtual-product';
 
    $product->setSku($sku)
            ->setName('My Test Virtual 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\Catalog\Model\Product\Type::TYPE_VIRTUAL)
            ->setTaxClassId(0) // Tax class id, 0 = None, 2 = Taxable Goods, etc.
            ->setPrice(100) // Price of the product
            ->setWebsiteIds([1]) // Assign product to websites
            ->setCategoryIds([11, 12, 13]) // Assign product to categories using category id
            ->setStockData(
                [
                    'use_config_manage_stock' => 0,
                    'manage_stock' => 1,
                    'is_in_stock' => 1,
                    'qty' => 999999
                ]
            );
 
    $product = $productRepository->save($product);
 
    if ($product->getId()) {
        echo "Product Created Successfully";
    }
 
} catch (\Exception $e) {
    echo $e->getMessage();
}

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 virtual product in Magento 2 programmatically,

<?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');
 
    $product = $productInterfaceFactory->create();
 
    // Get the default attribute set id
    $attributeSetId = $product->getDefaultAttributeSetId();
      
    $sku = $urlKey = 'test-virtual-product';
 
    $product->setSku($sku)
            ->setName('My Test Virtual 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\Catalog\Model\Product\Type::TYPE_VIRTUAL)
            ->setTaxClassId(0) // Tax class id, 0 = None, 2 = Taxable Goods, etc.
            ->setPrice(100) // Price of the product
            ->setWebsiteIds([1]) // Assign product to websites
            ->setCategoryIds([11, 12, 13]) // Assign product to categories using category id
            ->setStockData(
                [
                    'use_config_manage_stock' => 0,
                    'manage_stock' => 1,
                    'is_in_stock' => 1,
                    'qty' => 999999
                ]
            );
 
    $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 *