Home / Blog / Automatic change of product types in Magento 2
Automatic change of product types in Magento 2

Automatic change of product types in Magento 2

  • Anna KoshevaAnna Kosheva
  • August 19, 2022

    August 19, 2022

Sometimes, for one reason or another, content managers need to convert a particular product from Simple to Virtual or vice versa and change its set attribute. So on. Most often, this falls on the shoulders of developers.

Magento 2 has a feature to achieve this. Before you get to grips with it (I’ll call it “auto conversion”), there are a few things you need to keep in mind to get the right results.

Auto conversion from the user’s point of view

Let’s look at the admin panel from the point of view of the content manager. You can select the type of new product before you create it.

In Magento 1, this is on the Admin > Catalog > Manage Products > Set attribute and product type selection page after clicking on “Add Product.”

In Magento 2, on the Admin > Products > Catalog page, click on the arrow to the right of the “Add Product” button.

After selecting the desired type, Magento will show you a new product edit page with predefined options and new sections for the selected type. If you choose the Simple product type or click on “Add Product,” you will see the Simple product edit page, but pay attention to the following three things:

  1. Weight attribute
  2. Configurations section
  3. Downloadable Information section

These three sections define the type of product.

Magento 2 can automatically (when saving) change product types for both new and existing products of the following products:

  • Simple
  • virtual
  • Downloadable
  • Configurable

Consider what needs for this.

Simple and Virtual Products

Suppose you set the weight “Weight” = “The item has no weight” (namely, there is no weight, and do not just delete the value from the input field). In that case, the product is a Virtual product. Still, as soon as you return to the product editing page and specify that the product has a weight, it will be converted to a Simple product immediately after saving.

Downloadable product

To turn a Simple product into a Downloadable, you need to set “Weight” = “The item has no weight” and add one or more links below in the “Downloadable Information” section. To turn this item back into a Simple product, just set “Weight” = “The item has weight” and save the product.

Product configurable

Add any child product to it as mentioned above to turn a Simple product into a Configurable one. And to make it a Simple product again, it is enough to delete all configurations and click on save. As you already understood, this means that Magento 2 cannot have a Configurable product without children.

Learn more about Magento 2: Magento 2 for Beginners 

For developers

Now let’s talk about exactly how it all works. We want to start with the most important one, the Magento\Catalog\Model\Product\TypeTransitionManager class.

public function __construct(
        \Magento\Catalog\Model\Product\Edit\WeightResolver $weightResolver,
        array $compatibleTypes
    ) {
        $this->compatibleTypes = $compatibleTypes;
        $this->weightResolver = $weightResolver;
    }

    public function processProduct(Product $product)
    {
        if (in_array($product->getTypeId(), $this->compatibleTypes)) {
            $product->setTypeInstance(null);
            $productTypeId = $this->weightResolver->resolveProductHasWeight($product)
                ? Type::TYPE_SIMPLE
                : Type::TYPE_VIRTUAL;
            $product->setTypeId($productTypeId);
        }
    }

This reasonably simple class has two methods __construct and processProduct. All the magic is in the second method, processProduct($product). As you can see, it checks if the type of the passed product is in the array of compatible types, and if the product has a weight, then it is a Simple product; if not, then a Virtual product.

In Magento 2.1. as you may have guessed, the following types are compatible:

  • Simple
  • virtual
  • Downloadable
  • Configurable

All of them are through di.xml

<type name="Magento\Catalog\Model\Product\TypeTransitionManager">
        <arguments>
            <argument name="compatibleTypes" xsi:type="array">
                <item name="simple" xsi:type="const">Magento\Catalog\Model\Product\Type::TYPE_SIMPLE</item>
                <item name="virtual" xsi:type="const">Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL</item>
            </argument>
        </arguments>
    </type>

Only these types can be converted to Simple or Virtual products.

Magento\Downloadable\Model\Product\TypeTransitionManager\Plugin\Downloadable::aroundProcessProduct() checks that the product type is Simple, Virtual, Downloadable, data with the downloadable key was posted from the frontend and that this product has no weight. If it is, it is Downloadable; otherwise, the original method is run.

public function aroundProcessProduct(
        \Magento\Catalog\Model\Product\TypeTransitionManager $subject,
        Closure $proceed,
        \Magento\Catalog\Model\Product $product
    ) {
        $isTypeCompatible = in_array(
            $product->getTypeId(),
            [
                \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
                \Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL,
                \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE
            ]
        );
        $downloadableData = $this->request->getPost('downloadable');
        $hasDownloadableData = false;
        if (isset($downloadableData)) {
            foreach ($downloadableData as $data) {
                foreach ($data as $rowData) {
                    if (empty($rowData['is_delete'])) {
                        $hasDownloadableData = true;
                        break 2;
                    }
                }
            }
        }
        if ($isTypeCompatible && $hasDownloadableData && !$this->weightResolver->resolveProductHasWeight($product)) {
            $product->setTypeId(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE);
            return;
        }
        $proceed($product);
    }

Magento\ConfigurableProduct\Model\Product\TypeTransitionManager\Plugin\Configurable::aroundProcessProduct() plugin changes the product type to “configurable” if there is data in the request with the “attributes” key; otherwise, the original method is launched.

public function aroundProcessProduct(
        \Magento\Catalog\Model\Product\TypeTransitionManager $subject,
        Closure $proceed,
        \Magento\Catalog\Model\Product $product
    ) {
        $attributes = $this->request->getParam('attributes');
        if (!empty($attributes)) {
            $product->setTypeId(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE);
            return;
        }
        $proceed($product);
    }

How it all works

If you try to save a product from the admin panel, as described above, it will change its type to 1 of the above thanks to this code, but if you try to save the product model through the save() method, then nothing will change. The point is in the controller that handles the saving of goods.

Magento\Catalog\Controller\Adminhtml\Product\Save::execute() uses an instance of Magento\Catalog\Model\Product\TypeTransitionManager class

$product = $this->initializationHelper->initialize($this->productBuilder->build($this->getRequest()));
$this->productTypeManager->processProduct($product);
…
$product->save();

Share with friends and colleagues!

  • Anna KoshevaAnna Kosheva
  • August 19, 2022

    August 19, 2022

Sign up and don't miss our awesome Mage Mastery lessons and updates!

Related Posts
How to create User Login with PHP and MySQL?

How to create User Login with PHP and MySQL?

editAnna Kosheva
edit October 04, 2022

Authenticate your users with the PHP and MySQL knowledge. Learn more about HTML form creation for it, MySQL database etc.

JavaScript Mixins in Magento 2

JavaScript Mixins in Magento 2

editAnna Kosheva
edit September 29, 2022

Read the blog and learn how to cleate a Magento 2 extension. This module can hide information in the dropbox. Why is it essential?

Test plan for manual QA in Magento 2

Test plan for manual QA in Magento 2

editAnna Kosheva
edit September 27, 2022

How can you make a test plan for a QA? Read about test plan creation, types of them and a template.

If you like this blog post, you may want to watch
Start: March 28, 2021
Intermediate
 
Max Pronko
Web Icon20 lessons
Clock Icon15 hours
Adobe Certified Professional — Magento Commerce Developer Study Group is an 10-week (1.5 hours/week) instructor-led study group. This study group will help PHP and JavaScript developers evaluate their readiness and prepare for the Adobe Certified Professional — Magento Commerce Developer exam.
Start: March 15, 2021
Advanced
 
Max Pronko
Web Icon80 lessons
Clock Icon15 hours
Magento 2 Development Workshop is for those who want to practice and learn how to implement Magento 2 extensions. During the workshop, you will have lots of homework, practical exercises, video lessons, and theory that will give you the required skills for your Magento 2 job.
2022 © Made with ❤ by Max Pronko