M2 Defining a plugin

A plugin is used to extend or modify a public method’s behaviour by applying code before, after, or around that observed method.

The first argument for the before, after, and around methods is an object that provides access to all public methods of the observed method’s class.

Note: The rest of the parameters for these functions are depending on the function type (before, after, around) – they are having a dynamic number of parameters.

Before

Before methods run prior to an observed method. These methods must have the same name as the observed method with ‘before’ as the prefix.

Very important: the number of arguments that before method is taking is equal with the number of arguments of the observed  +1 (the subject argument).

 

Exercise:  Customise Magento\Theme\Block\Html\Breadcrumbs class, addCrumb() method, so that every crumbName is transformed into: $crumbName . “(!)”

My Solution:  (more about XML implementation)

Create file at this locations:

app/code/Osmage/Hello/etc/frontend/di.xml
app/code/Osmage/Hello/Plugin/Breadcrumbs.php

with the following content for XML:

<?xml version="1.0" ?>
<!--
  ~ Copyright (c) 2017 osMage :P .
  -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <type name="Magento\Theme\Block\Html\Breadcrumbs">
        <plugin name="change_breadcrumbs" disabled="false" sortOrder="1" type="Osmage\Hello\Plugin\Breadcrumbs" />
    </type>

</config>

And for PHP file:

<?php

namespace Osmage\Hello\Plugin;

class Breadcrumbs
{
    public function beforeAddCrumb(\Magento\Theme\Block\Html\Breadcrumbs $subject, $crumbName, $crumbInfo)
    {
        # The check is in place in order to allow us to
        # skip the parents
        if(is_string($crumbInfo['label']))
            $crumbInfo['label'] = $crumbInfo['label'].'(!)';

        return [$crumbName,$crumbInfo];
    }

}

 

Key points:

  • Pay attention at the number of arguments, it is exact the same number of arguments as the main function addCrumb().
  • The returned result should be an array containing the number of parameters.
  • The IF check is because the parent breadcrumb is returning an object and we want to apply it only for the children.

 

After

These type of methods run after the completion of the observed method. These methods must have the same name as the observed method with ‘after’ as the prefix.

Exercise: Customize Magento\Theme\Block\Html\Footer class, to replace the body of the getCopyright() method with your implementation. Return a hard-coded string: “Customized copyright!”

Solution:

Create the files at these paths:

# for XML file
app/code/Osmage/Hello/etc/frontend/di.xml

# the PHP class
app/code/Osmage/Hello/Plugin/Footer.php

And the PHP implementation:

<?php

namespace Osmage\Hello\Plugin;

class Footer
{
    public function afterGetCopyright(\Magento\Theme\Block\Html\Footer $subject, $result)
    {
        return 'Customized copyright!';
    }
}

Key points: 

  • The after method  is taking just ONE parameter  Another one that provides access to all public methods of the observed method’s class.
  • The returning value should be the same type as the extended method.