Magento 2 – Plugin example
In this post I show you a Magento 2 plugin example. Plugins are a new way to extend core functionality without modifying core files. If you are working on a new Magento 2 extension, it is likely that you will need plugins. It is a good idea to know exactly how plugins are working.
Magento 2 – Plugin example
I show you how to create a simple plugin by example and will tell you all you need to know. For this I suggest, that you already know how to create a Magento 2 module, I will only show you what you need to add to this module.
Example
I show you a real live example, which you can use if you want. The problem that should fixed with this plugin:
- Magento 2 sends out order confirmation emails after order is created – we want to add a custom expression when sending emails is allowed
- You may turn off order confirmation mails, but then it is not possible to send them programmatically
- If you send it programmatically and adminhtml option is turned on, a customer will get two mails
We need to add a custom expression to check if it is allowed to send order confirmation mails with turned on auto send from adminhtml. For this we need to extend Magento\Sales\Model\Order\Email\Sender\OrderSender send method, which can easily be done with a plugin.
Source Code
The following changes to an existing custom Magento 2 module should be implemented:
config/di.xml
1 2 3 4 5 6 | <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Sales\Model\Order\Email\Sender\OrderSender"> <plugin name="sale_order_sender_custom_email" type="MyCompany\MyModule\Model\Plugin\OrderSender" sortOrder="1" /> </type> </config> |
Model/Plugin/OrderSender.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php namespace MyCompany\MyModule\Model\Plugin; use Magento\Sales\Model\Order; class OrderSender { /** * Order success action. * * @return bool */ public function aroundSend(\Magento\Sales\Model\Order\Email\Sender\OrderSender $subject, \Closure $proceed, Order $order, $forceSyncMode = false) { $returnValue = null; if($order->getCustomAttribute() != null) { $returnValue = $proceed($order, $forceSyncMode); } return $returnValue; } } |
Setup/InstallSchema.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <?php namespace MyCompany\MyModule\Setup; use Magento\Framework\Setup\UpgradeSchemaInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\SchemaSetupInterface; use Magento\Framework\DB\Ddl\Table; class InstallSchema implements InstallSchemaInterface { public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) $setup->startSetup(); $connection = $setup->getConnection(); if ($connection->tableColumnExists('sales_order', 'custom_attribute') === false) { $connection->addColumn( $setup->getTable('sales_order'), 'custom_attribute', [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, 'comment' => 'Custom Attribute' ] ); } $setup->endSetup(); } } |
How this plugin works
This module creates a new order attribute called custom_attribute. If this attribute is null, no order mail will be sent. We should set it to any value different to null.
- di.xml
this file is needed to register a new plugin. This time we want to “overload” Magento\Sales\Model\Order\Email\Sender\OrderSender class. In type tag we set the model we want to create a plugin for. The plugin tag is for defining a new model, that acts as a plugin. There you are allowed to define beforeMETHODNAME, afterMETHODNAME and aroundMETHODNAME functions that will be called befor, after or every time that specific method is called. - OrderSender.php
creating a plugin is quite easy. If you want to “overload” send method from OrderSender model, you simply need to create your own OrderSender class and define aroundSend, beforeSend or afterSend function. You need to check real function in vendor folder and add two more params to its param list: $subject and $proceed. You can do anything in that function. If you do not want to run actual send method, just return null. If you want to call send as expected, just return $proceed with all needed params (number depends on method you create a plugin for).
Conclusion
This Magento 2 plugin example demonstrates how to create your own plugins. Plugins are a far better solution than overwriting core files and a better solution as Magento 1 offers. You should use it!