We'll review a simple example of extending Magento functionality to give you an idea of what's involved and get you on your way. Magento 2.0 has introduced the concept of plugins that rely on dependency injection. While it's tempting to think of a plugin as interchangeable with extension or module, a plugin actually plays a significantly different role. It listens to any public method call on another object. As long as the class or method doesn't use the final keyword, any class and any public method is fair game, including methods in your classes, third-party classes and Magento classes. That's pretty impressive!
Start by declaring the plugin in the di.xml file, in the app/code/(vendor)/(modulename)/Plugins/ path, with the following XML code:
<config>
<type name="ObservedType">
<plugin name="pluginName" type="PluginClassName" sortOrder="1" disabled="false"/>
</type>
</config>In this example, the type name is the class being observed. This is the class with methods we're trying to extend. The plugin name is an arbitrary name you provide to the plugin, and the type is the name of the plugin's class in the \Vendor\Module\Model\class\Plugin format.
This is the class where we'll be defining the custom functionality that extends the method established in the type node.
The sort order attribute in the preceding XML allows for even greater flexibility. Multiple plugins can call the same method, and this field determines the order in which they are run.
The disabled attribute is pretty straightforward. It simply determines whether or not the plugin is active.
Once we've got the di.xml file in place, our next step is to create the class that's going to extend the original method in the \Vendor\Module\Model\class\Plugin.php file. Once it's there, we can choose to extend functionality before, after, and around the original method. So, say you wanted to execute some code, such as logging some data or firing off a call to a third-party API before the result of another public method; the following code would do this before the method was called:
<?php
namespace My\Module\{class};
class classPlugin
{
public function beforeGetName(\Magento\Catalog\Model\Product $subject, $variable)
{
//execute code here
}
}
?>Now, say you wanted to insert some arbitrary code after the original public method. It would simply look like the following code snippet. Note that before has been replaced with after. So the naming convention involves the original method name with before, after, or around as a prefix:
<?php
namespace My\Module\class;
class classPlugin
{
public function afterGetName(\Magento\Catalog\Model\Product $subject,$variable)
{
//execute code here
}
}
?>In the final example, code can be executed before and after the target method, as follows:
namespace My\Module\class;
class classPlugin
{
public function afterGetName(\Magento\Catalog\Model\Product $subject,$proceed)
{
//execute code before original method here.
$result = $proceed();
//execute code after original method here.
return true;
}
}
?>The special sauce here is in the $proceed parameter passed in, which allows delineation between code to be executed before and after a target method.