Magento – Override of abstract class method not working

magento-2.1overridesshipping

I'm trying to override the proccessAdditionalValidation method in the Magento\Shipping\Model\Carrier\AbstractCarrierOnline class. Below is what I have done but the function is not being called.

Create: app/code/Custom/ShippingMaxWeight/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
   <preference for="Magento\Shipping\Model\Carrier\AbstractCarrierOnline" type="Custom\ShippingMaxWeight\Shipping\Model\Carrier\AbstractCarrierOnline" />
</config>

Create: app/code/Custom/ShippingMaxWeight/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Custom_ShippingMaxWeight" setup_version="1.0.0" />
</config>

Create: app/code/Custom/ShippingMaxWeight/etc/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
        \Magento\Framework\Component\ComponentRegistrar::MODULE,
        'Custom_ShippingMaxWeight',
        __DIR__
    );

Create: app/code/Custom/ShippingMaxWeight/Shipping/Model/Carrier/AbstractCarrierOnline.php

namespace Custom\ShippingMaxWeight\Shipping\Model\Carrier;

class AbstractCarrierOnline extends Magento\Shipping\Model\Carrier\AbstractCarrierOnline
{
    public function proccessAdditionalValidation(\Magento\Framework\DataObject $request) {
       //override function
    }
}

Then I ran:

magento module:enable ShippingMaxWeight
magento setup:upgrade

I verified the module is installed and enabled in admin.

The max_package_weight setting in shipping is used for two purposes, to split an order into multiple boxes, and to find if a shipping method can be used based on max weight. I need to specify the max BOX weight of 18 lbs and still show the shipping method when an individual item is more than 18 lbs. I want to hard code 150 as the max shipping weight for the max weight check. We only use UPS ground and until we find an open source UPS LTL quote module we won't put up products that weigh more than 150 lbs.

$maxAllowedWeight = (double)$this->getConfigData('max_package_weight');

to

$maxAllowedWeight = 150;

I must be doing something wrong. Just don't know what.

Best Answer

Short answer: what you're trying to do is not possible. Your extending of and preference for the abstract class are valid, however these will never be used.

Inheritance of classes is native PHP functionality and will not be resolved by the object manager. Therefore, you can only use DI preferences for actual classes, not for abstract parent classes.

That being said, the method you are trying to alter is a public method, so you could use a Plugin.

You will have to register this plugin for each class which extends AbstractCarrierOnline. In this example I will show how to do this for the built-in DHL and UPS carriers (which both extend AbstractCarrierOnline).

In your di.xml add the following:

<type name="Magento\Dhl\Model\Carrier">
    <plugin name="custom_shippingmaxweight_dhlplugin" type="Custom\ShippingMaxWeight\Plugin\Shipping\OnlineCarrierPlugin" />
</type>
<type name="Magento\Ups\Model\Carrier">
    <plugin name="custom_shippingmaxweight_upsplugin" type="Custom\ShippingMaxWeight\Plugin\Shipping\OnlineCarrierPlugin" />
</type>

Create the plugin class: Custom/ShippingMaxWeight/Plugin/Shipping/OnlineCarrierPlugin.php

namespace Custom\ShippingMaxWight\Plugin\Shipping;

// use ...;

class OnlineCarrierPlugin {

    public function aroundProcessAdditionalValidation (\Magento\Shipping\Model\Carrier\AbstractCarrierOnline $carrier, callable $proceed, \Magento\Framework\DataObject $request) {
        // do stuff 

        // $result = ...?
        // $result can be an instance of \Magento\Quote\Model\Quote\Address\RateResult\Error, a boolean false, or the $carrier object.
        return $result;
    }
}

Please review http://devdocs.magento.com/guides/v2.1/extension-dev-guide/plugins.html#around-methods for more information about the arguments used in an 'around' plugin. You don't have to call the $proceed method. You could also c/p and alter the code from the abstract class. The choice is yours.

If you have any more questions about this, feel free to ask.