Difference between Magento 2 Before, After and Around plugins

Difference between Magento 2 Before, After and Around plugins

Magento 2 plugins are a type of extension that allow developers to modify the core functionality of the Magento 2 platform without changing the core code. This means that developers can add new features or modify existing ones without altering the core code, which makes it easier to upgrade the platform and maintain stability.

There are two types of Magento 2 plugins: before and after plugins. Before plugins are called before the original method is executed, and after plugins are called after the original method is executed. Let’s take a look at some code examples to help illustrate the difference between these two types of plugins.

Before Plugins

Before plugins are used to modify the input parameters of a method before it is executed. For example, let’s say we want to modify the price of a product before it is added to the cart. Here’s how we might do that with a before plugin:

class ModifyPriceBeforePlugin
{
    public function beforeAddProduct(
        \Magento\Checkout\Model\Cart $subject,
        $product,
        $requestInfo = null
    ) {
        $product->setPrice($product->getPrice() * 1.1);
        return [$product, $requestInfo];
    }
}

In this example, we’re using a before plugin to modify the price of the product by 10% before it is added to the cart. The beforeAddProduct method is called before the original addProduct method is executed, so the modified price will be used in the original method.

After Plugins

After plugins are used to modify the output of a method after it has been executed. For example, let’s say we want to add a custom message to the checkout success page. Here’s how we might do that with an after plugin:

class AddMessageAfterPlugin
{
    public function afterExecute(
        \Magento\Checkout\Controller\Onepage\Success $subject,
        $result
    ) {
        $customMessage = 'Thank you for your purchase!';
        $result->getLayout()->getBlock('checkout.success')->setCustomMessage($customMessage);
        return $result;
    }
}

In this example, we’re using an after plugin to add a custom message to the checkout success page. The afterExecute method is called after the original execute method is executed, so the custom message will be displayed on the success page.

Around Plugins

A Magento 2 around plugin is a type of plugin in the Magento 2 framework that allows developers to modify the behavior of a method by wrapping it in a new function. This allows developers to add additional functionality to an existing method without changing the original code.

For example, suppose a Magento 2 store has a method called “sendEmail” that is responsible for sending emails to customers. A developer may want to add the ability to log all emails that are sent, but does not want to modify the original “sendEmail” method. In this case, the developer could create an around plugin that wraps the “sendEmail” method and adds the logging functionality. The plugin would then be called every time the “sendEmail” method is called, and the original method would still be executed as normal.

Here is an example of how the around plugin might be implemented:

public function aroundSendEmail(
    \Magento\Customer\Model\EmailNotificationInterface $subject,
    \Closure $proceed
) {
    // Log the email that is being sent
    $this->logger->info('Sending email to ' . $subject->getRecipientEmail());

    // Execute the original method
    $result = $proceed();

    // Return the result of the original method
    return $result;
}

Conclusion

Magento 2 plugins are a powerful tool for modifying the core functionality of the platform without changing the core code. Before plugins are used to modify the input parameters of a method before it is executed, and after plugins are used to modify the output of a method after it has been executed. Both types of plugins can be used to add new features or modify existing ones, making it easier to upgrade the platform and maintain stability.

Difference between Magento 2 Before, After and Around plugins

What is the difference between dependancy injection and object manager in magento 2?

Dependency injection (DI) is a design pattern that allows you to inject objects into a class, rather than creating them inside the class. This allows you to decouple the class from its dependencies, making it more flexible and easier to test.

In Magento 2, you can use dependency injection by adding the required objects as constructor arguments in your class, and then using the __construct method to inject them into the class. For example:

class MyClass
{
    protected $curl;

    public function __construct(
        \Magento\Framework\HTTP\Client\Curl $curl
    ) {
        $this->curl = $curl;
    }

    public function makeRequest()
    {
        $this->curl->get('https://www.example.com');
    }
}

In this example, the MyClass class depends on the Curl class to make HTTP requests. By using dependency injection, we can inject the Curl class into the MyClass class and use it without having to create it inside the class.

Object Manager is a class in Magento 2 that is responsible for creating and managing objects in the system. It uses a registry to store objects, so that they can be reused instead of being created multiple times.

To use the object manager, you can use the create method to create an object, or the get method to retrieve an existing object from the registry. For example:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();

// Create a new object
$curl = $objectManager->create('Magento\Framework\HTTP\Client\Curl');

// Get an existing object from the registry
$curl = $objectManager->get('Magento\Framework\HTTP\Client\Curl');

While object manager is a powerful tool, it is generally recommended to use dependency injection instead, as it makes your code more flexible and easier to test. Object manager is more suited for situations where you need to create objects on the fly, or when you don’t have access to the class constructor (e.g. in a plugin).

Difference between Magento 2 Before, After and Around plugins

Learn how to make an HTTP request in Magento 2

To make an HTTP request in Magento 2, you can use the following steps:

First, you need to inject the HTTP client class into your class using dependency injection. You can do this by adding the following line of code in your class constructor:

public function __construct(
    \Magento\Framework\HTTP\Client\Curl $curl
) {
    $this->curl = $curl;
}

Now you can use the $this->curl object to make an HTTP request. You can set the request method, headers, and body using the following methods:

// Set the request method
$this->curl->setOption(CURLOPT_CUSTOMREQUEST, 'POST');

// Set the request headers
$this->curl->setHeaders(['Content-Type: application/json']);

// Set the request body
$this->curl->setBody(json_encode($requestBody));

Finally, you can send the request and get the response using the following code:

// Send the request
$this->curl->get($url);

// Get the response status code
$statusCode = $this->curl->getStatus();

// Get the response body
$responseBody = $this->curl->getBody();

That’s it! You have now made an HTTP request in Magento 2 using the Curl client class.

Solved: Cannot add row to Magento 2 page builder – Script error for “vimeoWrapper”, needed by: Magento_PageBuilder/js/content-type/row/preview

Solved: Cannot add row to Magento 2 page builder – Script error for “vimeoWrapper”, needed by: Magento_PageBuilder/js/content-type/row/preview

Issue:

We have recently upgraded Magento to Magento 2.4.4 and noticed that admin is no longer able to use the “row” element of the page builder, and the following error is returned in the developer’s tool console:

static/adminhtml/Magento/backend/en_GB/vimeoWrapper.js%20net::ERR_ABORTED
Script error for "vimeoWrapper", needed by: Magento_PageBuilder/js/content-type/row/preview

Fix:

This is due to module-page-builder being updated for Magento 2.4.5 but this does not seem to be backwards compatible with 2.4.4.

You will need to run composer require magento/module-page-builder:2.2.2  to get the correct version and this should fix the issue.

Please do not forget to remove this dependency when you upgrade to Magento 2.4.5.

Solved: Issue with Magento 2 Braintree Virtual Terminal: this.$container.validate is not a function

Solved: Issue with Magento 2 Braintree Virtual Terminal: this.$container.validate is not a function

I recently upgraded one of my clients website from Magento 2.4.2 to Magento 2.4.4 and the site uses Braintree as the payment gateway and the backend Braintree Virtual Terminal is used quite frequently in their business.

After the upgrade, the virtual terminal stopped working though it’s still inconclusive if it was good by the Magento upgrade.

Issue:

Braintree Virtual Terminal does not work and clicking on the Take Payment button returns the following error in console:

virtual.js:144 Uncaught TypeError: this.$container.validate is not a function
    at UiClass.submitOrder (virtual.js:144:29)
    at HTMLFormElement.dispatch (jquery.js:5430:49)
    at elemData.handle (jquery.js:5234:47)
    at Object.trigger (jquery.js:8719:28)
    at HTMLFormElement.<anonymous> (jquery.js:8797:30)
    at Function.each (jquery.js:385:35)
    at jQuery.fn.init.each (jquery.js:207:27)
    at jQuery.fn.init.trigger (jquery.js:8796:25)
    at $.<computed>.<computed>._click (button.js:48:31)
    at $.<computed>.<computed>._click (jquery-ui.js:143:41)

Steps to replicate:

  • Go to Magento admin > Sales > Braintree virtual terminal and add test card details and fill the dummy information > Click Take Payment
  • Nothing happens and instead a console error is returned
this.$container.validate console error

Fix:

I found that the required jQuery validator was missing in vendor/paypal/module-braintree-core/view/adminhtml/web/js/virtual.js and adding the missing library fixed the issue.

Since this was a core modification and there is no fix available yet so I have created a patch that you can apply with composer to add the missing library. Please note it is never a good idea to modify the core code file directly so either create a preference/override or create a diff patch to apply via composer.

To apply the patch, create a new file called diff.patch and put the following code in it and finally, install it with composer update.

diff --git a/vendor/paypal/module-braintree-core/view/adminhtml/web/js/virtual.js b/vendor/paypal/module-braintree-core/view/adminhtml/web/js/virtual.js
--- a/vendor/paypal/module-braintree-core/view/adminhtml/web/js/virtual.js
+++ b/vendor/paypal/module-braintree-core/view/adminhtml/web/js/virtual.js
@@ -12,7 +12,8 @@
     'mage/translate',
     'PayPal_Braintree/js/validator',
     'braintree',
-    'braintreeHostedFields'
+    'braintreeHostedFields',
+    'jquery/validate'
 ], function ($, Class, alert, domObserver, $t, validator, client, hostedFields) {
     'use strict';