In Magento 2, leveraging Dependency Injection (DI) and virtualType allows developers to create dynamic and flexible customizations without altering core functionality. This guide demonstrates how to create a Magento plugin that modifies product behavior based on a custom flag, enablePlugin, using virtualType and includes unit tests to validate the functionality.
Note: This approach is primarily theoretical, designed to showcase the flexibility of Magento’s plugin and virtualType systems. In practical applications, simpler implementations may suffice.
Step 1: Extend the Product Class
Create a custom product class that extends Magento\Catalog\Model\Product and includes a boolean flag enablePlugin.
File: app/code/YourVendor/YourModule/Model/CustomProduct.php
namespace YourVendor\YourModule\Model;
use Magento\Catalog\Model\Product;
class CustomProduct extends Product
{
private $enablePlugin = false;
/**
* Set the enablePlugin value.
*
* @param bool $enablePlugin
* @return void
*/
public function setEnablePlugin(bool $enablePlugin): void
{
$this->enablePlugin = $enablePlugin;
}
/**
* Get the enablePlugin value.
*
* @return bool
*/
public function getEnablePlugin(): bool
{
return $this->enablePlugin;
}
}
Step 2: Configure virtualType in di.xml
Define virtualTypes in the di.xml configuration to create variations of the CustomProduct class with different enablePlugin values.
File: app/code/YourVendor/YourModule/etc/di.xml
true
false
CustomProductWithPlugin
Step 3: Create the Plugin
Develop a plugin that modifies the product’s behavior based on the enablePlugin flag. For demonstration, we’ll append a suffix to the product name if enablePlugin is true.
File: app/code/YourVendor/YourModule/Plugin/ProductPlugin.php
namespace YourVendor\YourModule\Plugin;
use Magento\Catalog\Api\Data\ProductInterface;
class ProductPlugin
{
/**
* Modify the product name after it is retrieved if enablePlugin is true.
*
* @param ProductInterface $subject
* @param string $result
* @return string
*/
public function afterGetName(ProductInterface $subject, string $result): string
{
if (!$subject->getEnablePlugin()) {
return $result;
}
// Append a custom suffix to the product name
return $result . ' - Custom Suffix';
}
}
Step 4: Write Unit Tests
Implement unit tests to verify that the plugin behaves as expected when enablePlugin is true or false.
File: app/code/YourVendor/YourModule/Test/Unit/Plugin/ProductPluginTest.php
namespace YourVendor\YourModule\Test\Unit\Plugin;
use PHPUnit\Framework\TestCase;
use YourVendor\YourModule\Plugin\ProductPlugin;
use YourVendor\YourModule\Model\CustomProduct;
class ProductPluginTest extends TestCase
{
public function testAfterGetNameWithPluginEnabled()
{
$product = $this->createMock(CustomProduct::class);
$product->method('getEnablePlugin')->willReturn(true);
$product->method('getName')->willReturn('Original Name');
$plugin = new ProductPlugin();
$result = $plugin->afterGetName($product, $product->getName());
$this->assertEquals('Original Name - Custom Suffix', $result);
}
public function testAfterGetNameWithPluginDisabled()
{
$product = $this->createMock(CustomProduct::class);
$product->method('getEnablePlugin')->willReturn(false);
$product->method('getName')->willReturn('Original Name');
$plugin = new ProductPlugin();
$result = $plugin->afterGetName($product, $product->getName());
$this->assertEquals('Original Name', $result);
}
}
Practical Considerations
While this approach demonstrates Magento’s flexibility, it introduces complexity that may not be necessary for all scenarios. In many cases, a single plugin with conditional logic based on product attributes can achieve similar results with less overhead. It’s essential to assess the specific needs of your project before implementing such a design.
By following this guide, you’ve explored how to create a dynamic Magento plugin using virtualType and DI, with unit tests to ensure functionality. This theoretical approach showcases the potential of Magento’s architecture for creating modular and adaptable solutions.
Join the Conversation
Have thoughts about this approach? Share your experience or feedback!
- What do you think about using
virtualTypein this way? Have you implemented a similar solution, or do you prefer alternative approaches? - Are there scenarios where this approach would be particularly useful for your projects?
- What challenges have you faced when combining plugins and
virtualTypein Magento?
Feel free to leave a comment below or start a discussion. Your insights can help others in the Magento development community!



Comments