1

Is there any way to override this class "vendor/paypal/module-braintree-core/Gateway/Command/GatewayCommand.php"?

I have tried to override this class method using plugin and preference but no luck.

Thanks,

2 Answers 2

1

You can override a class in Magento 2.4 (Assuming this is the version), including the one you mentioned (vendor/paypal/module-braintree-core/Gateway/Command/GatewayCommand.php). The primary methods are through Dependency Injection (DI), plugins (interceptors), and preferences.

If plugins and preferences didn't work, then it's likely the class is instantiated directly using the new keyword or it's a non-injectable class (for instance, an object manager cannot instantiate the class). It's also possible that your plugin or preference is not set up correctly.

However, it's important to note that overriding a class should be your last resort as it's generally better to work with plugins and observers which follow Magento's best practices.

Here are the steps to override the class:

Create a custom module if you haven't created one yet. We'll assume it's Vendor_Module. Create a di.xml file in the etc directory of your module. The location would be: app/code/Vendor/Module/etc/di.xml. Put the following content in di.xml:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Paypal\BraintreeCore\Gateway\Command\GatewayCommand" type="Vendor\Module\Gateway\Command\GatewayCommand" />
</config>

Now, create the corresponding PHP file in Vendor\Module\Gateway\Command\GatewayCommand.php. Make sure to extend the original class if you only want to change some methods. If you need to change the entire class, you can implement the original class's interface. Here is an example of the former:

<?php

namespace Vendor\Module\Gateway\Command;

class GatewayCommand extends \Paypal\BraintreeCore\Gateway\Command\GatewayCommand
{
    // Override the methods you need here
}

Remember to replace Vendor and Module with the name of your Vendor and Module. After making these changes, run the following commands to upgrade your module, compile, Keep Calm and clear the cache.

1

The PayPal\Braintree\Gateway\Command\GatewayCommand class (vendor/paypal/module-braintree-core/Gateway/Command/GatewayCommand.php) is not directly injected via Dependency Injection, so you can't use plugin or preference to override it. Instead, the Braintree module uses virtual types with the type type="PayPal\Braintree\Gateway\Command\GatewayCommand"(the class you are trying to override). You can review the contents of vendor/paypal/module-braintree-core/etc/di.xml to locate these codes.

So, you should override these virtual types instead of overriding the PayPal\Braintree\Gateway\Command\GatewayCommand class.
For example:
The original code:

<virtualType name="BraintreeCaptureCommand" type="PayPal\Braintree\Gateway\Command\GatewayCommand">
    <arguments>
        <argument name="requestBuilder" xsi:type="object">BraintreeCaptureRequest</argument>
        <argument name="transferFactory" xsi:type="object">PayPal\Braintree\Gateway\Http\TransferFactory</argument>
        <argument name="client" xsi:type="object">PayPal\Braintree\Gateway\Http\Client\TransactionSubmitForSettlement</argument>
        <argument name="handler" xsi:type="object">PayPal\Braintree\Gateway\Response\TransactionIdHandler</argument>
        <argument name="validator" xsi:type="object">PayPal\Braintree\Gateway\Validator\ResponseValidator</argument>
    </arguments>
</virtualType>

<virtualType name="BraintreePartialCaptureCommand" type="PayPal\Braintree\Gateway\Command\GatewayCommand">
    <arguments>
        <argument name="requestBuilder" xsi:type="object">BraintreeCaptureRequest</argument>
        <argument name="transferFactory" xsi:type="object">PayPal\Braintree\Gateway\Http\TransferFactory</argument>
        <argument name="client" xsi:type="object">PayPal\Braintree\Gateway\Http\Client\TransactionSubmitForPartialSettlement</argument>
        <argument name="handler" xsi:type="object">PayPal\Braintree\Gateway\Response\TransactionIdHandler</argument>
        <argument name="validator" xsi:type="object">PayPal\Braintree\Gateway\Validator\ResponseValidator</argument>
    </arguments>
</virtualType>

Your config to override these 2 virtual types:
app/code/YourVendor/YourModule/etc/di.xml

<preference for="BraintreeCaptureCommand" type="YourVendor\YourModule\Gateway\Command\GatewayCommand"/>
<preference for="BraintreePartialCaptureCommand" type="YourVendor\YourModule\Gateway\Command\GatewayCommand"/>

In app/code/YourVendor/YourModule/Gateway/Command/GatewayCommand.php

<?php declare(strict_types=1);
namespace YourVendor\YourModule\Gateway\Command;

use PayPal\Braintree\Gateway\Command\GatewayCommand as BraintreeGatewayCommand;

class GatewayCommand extends BraintreeGatewayCommand
{
}

However, there are 17 virtual types which have type="PayPal\Braintree\Gateway\Command\GatewayCommand". You may want to consider an alternative approach by creating a custom composer patch that modify vendor/paypal/module-braintree-core/Gateway/Command/GatewayCommand.php file directly.

To create a custom composer patch, you can refer to the solutions on this page: How to create a Magento 2 Patch?

To apply composer patches, please refer to this document: https://experienceleague.adobe.com/docs/commerce-operations/upgrade-guide/patches/apply.html?lang=en#composer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.