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';
Solved: Ordered items not showing in New Order Email Magento 2.4.4

Solved: Ordered items not showing in New Order Email Magento 2.4.4

Issue:

Ordered items/products not showing in Magento Order Confirmation email after upgrade to Magento 2.4.4

Expected Result:

Order confirmation email should contain the list of ordered items for both registered and guest orders

Actual Result:

Ordered products are missing from order confirmation email Magento 2.4.4

Fix:

Login to Magento admin > Marketing > Email Templates > Open the order email template and find:

{{layout handle="sales_email_order_items" order=$order area="frontend"}}

and replace with:

{{layout handle="sales_email_order_items" order_id=$order_id area="frontend"}}

.. clear cache and this should resolve this issue.

Learn how to write a PHP Unit Test in Magento 2 for a Custom module

Learn how to write a PHP Unit Test in Magento 2 for a Custom module

PHPUnit is an automated testing framework for PHP and Magento 2 supports it out of the box with PHPUnit. As a good software engineer, one must consider writing their code by following the Test Driven Development a.k.a. TDD approach so in this quick tutorial, I will briefly explain the idea of PHP Unit Testing and why is important to follow TDD.

What is Unit Testing?

Unit Testing simply refers to testing every individual component/unit of a software. The objective is to ensure and validate that each unit of the software you are writing performs as designed. A unit is the smallest testable part of your application that usually accepts one or a few inputs and mostly a single output. One of the benefits of Unit testing is that this process is fully automated and does not require man hours to review and test the code.

Why Unit Test?

There are several benefits of Unit Testing but the key three benefits are as follow:

Early problem detection

Have you just created a beautiful software but one or more sections do not work in production? If yes then welcome to Unit Testing using which we can find the problems early in the development cycle.

Facilitates Change

Is there a new version of the programming language available and the version in which you wrote your software been deprecated? No problem – Unit testing allows you to refactor code or upgrade system libraries at a later date, and make sure the module still works correctly. The idea of unit testing is to write test cases for all functions so if a change causes a fault, it can be quickly identified.

Design

Ok I am not talking about your website frontend design or the flashy colours here. I’m instead referring to Design Patterns of your software. Unit Tests are to be written prior to the implementation of the actual code, and this approach helps a developer to think through the design and the end goal before the development begins.

Enough of the theory .. now let’s move on and create a simple Unit Test for your Bespoke Magento Module.

Write a unit test in Magento 2

Let’s assume that you have created a simple Magento 2 module called Shoman_MyFirstModule; that has its configuration area in Store > Configuration (say Shoman > My First Module), and in the configuration area you have a dropdown with Yes/No value.

Your module has a Helper Class called Data.php with a method called isEnabled(). The content of the file is as follows:

<?php
/**
 * Copyright © Shoaib Rehman All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Shoman\MyFirstModule\Helper;

use Magento\Framework\App\Helper\AbstractHelper;

class Data extends AbstractHelper
{

    /**
     * @param \Magento\Framework\App\Helper\Context $context
     */
    public function __construct(
        \Magento\Framework\App\Helper\Context $context
    )
    {
        parent::__construct($context);
    }

    /**
     * @return bool
     */
    public function isEnabled()
    {
        return $this->scopeConfig->getValue('shoman/general/enabled',
            \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE);
    }
}

As you can see in the code above, we have simple function that pulls and returns the value of the custom configuration.

Next, we are going to create a Unit Test for this Helper Class.

In your custom module root, create a new directory Test/Unit/Helper; and since your Helper class is called Data.php so create a new file called DataTest.php in the path app/code/Shoman/MyFirstModule/Test/Unit/Helper. Your directory structure will look like the one in the image below:

Unit Test Path

DataTest.php will extend \PHPUnit\Framework\TestCase and have two functions:

  1. setUp() – treat it as a __construct() function
  2. testIsEnabled() – isEnabled() is the original function in the Data.php class. We have prefixed the original function name with test so we can run a Unit Test on it.

Your test file will look like this:

<?php

namespace Animed\OneTrust\Test\Unit\Helper;

class DataTest extends \PHPUnit\Framework\TestCase
{
    /**
     * Helper
     *
     * @var \Shoman\MyFirstModule\Helper\Data
     */
    protected $helper;

    /**
     * Scope config mock
     *
     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
     */
    protected $scopeConfigMock;

    /**
     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
     */
    protected $objectManagerHelper;

    public function setUp() : void
    {
        $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
        $className = \Shoman\MyFirstModule\Helper\Data::class;
        $arguments = $this->objectManagerHelper->getConstructArguments($className);
        /**
         * @var \Magento\Framework\App\Helper\Context $context
         */
        $context = $arguments['context'];
        $this->scopeConfigMock = $context->getScopeConfig();
        $this->helper = $this->objectManagerHelper->getObject($className, $arguments);

    }

    public function testIsEnabled()
    {
        $this->scopeConfigMock->expects($this->once())
            ->method('getValue')
            ->willReturn('1');

        $this->assertTrue(is_string($this->helper->isEnabled()));
    }
}

How to run the Unit Test for a single Module in Magento 2?

To perform Unit Tests for a single module, you will need to run the following command in the Magento root directory:

php vendor/phpunit/phpunit/phpunit -c dev/tests/unit/phpunit.xml.dist app/code/Shoman/MyFirstModule

Once the test has run, and provided it has passed, you’ll get a message similar to in the screenshot below:

or if your test has failed then you will get an error message like the one below:

.. that’s all. If you have any questions or comments, please let me know.

How to install Magento patch APSB22-12 to fix the RCE Vulnerability

How to install Magento patch APSB22-12 to fix the RCE Vulnerability

Earlier this week, Adobe identified RCE vulnerability in both commerce and open source editions and released a security patch APSB22-12 marked as Critical Priority to be installed immediately.

What this means is if you are running your website on Adobe Commerce (2.3.3-p1-2.3.7-p2) or Magento Open Source (2.4.0-2.4.3-p1), then your website is at high risk and needs to be patched immediately.

There are two security patches to fix the potential vulnerability and you can download them from https://support.magento.com/hc/en-us/articles/4426353041293-Security-updates-available-for-Adobe-Commerce-APSB22-12- for your respective Magento versions.

Use the following attached patches, depending on your Adobe Commerce version:

2.4.3 – 2.4.3-p1:

2.3.4-p2 – 2.4.2-p2:

2.3.3-p1 – 2.3.4:

In order to stay up to date with the latest protections, you will need to apply two patches: MDVA-43395 patch first, and then MDVA-43443 on top of it.

The patches affect the following files:

./vendor/magento/framework/Filter/DirectiveProcessor/VarDirective.php
./vendor/magento/module-email/Model/Template/Filter.php
./vendor/magento/framework/Filter/DirectiveProcessor/DependDirective.php
./vendor/magento/framework/Filter/DirectiveProcessor/ForDirective.php
./vendor/magento/framework/Filter/DirectiveProcessor/IfDirective.php
./vendor/magento/framework/Filter/DirectiveProcessor/SimpleDirective.php
./vendor/magento/framework/Filter/DirectiveProcessor/VarDirective.php

How to apply a Magento Patch?

Once you have downloaded the appropriate patches, you can create a new directory called i.e. ./patches in your Magento root, upload patch files and run the following commands:

patch -p1 < patches/MDVA-43395_EE_2.4.3-p1_COMPOSER_v1.patch

patch -p1 < patches/MDVA-43443_EE_2.4.3-p1_COMPOSER_v1.patch