magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.5k stars 9.31k forks source link

AbstractCarrierInterface::collectRates() has incorrect return signature #28514

Open kassner opened 4 years ago

kassner commented 4 years ago

Summary

\Magento\Shipping\Model\Carrier\AbstractCarrierInterface::collectRates currently has in its signature that it will return \Magento\Framework\DataObject, but technically \Magento\Shipping\Model\Rate\Result is used everywhere, and it does not inherit the DataObject, so the signature is, de facto, incorrect.

Examples

\Magento\Shipping\Model\Shipping:

        if (!$result) {
            //One shipment for all items.
            $result = $carrier->collectRates($request);
        }

        if (!$result) {
            return $this;
        } elseif ($result instanceof Result) { // use Magento\Shipping\Model\Rate\Result;
            $this->getResult()->appendResult($result, $carrier->getConfigData('showmethod') != 0);
        } else {
            $this->getResult()->append($result);
        }

Both append methods expect the result class:

    /**
     * Append result received from a carrier.
     *
     * @param Result $result
     * @param bool $appendFailed Append result's errors as well.
     * @return void
     */
    public function appendResult(Result $result, bool $appendFailed): void
    {
        $this->results[] = ['result' => $result, 'appendFailed' => $appendFailed];
    }
    /**
     * Add a rate to the result
     *
     * @param \Magento\Quote\Model\Quote\Address\RateResult\AbstractResult|\Magento\Shipping\Model\Rate\Result $result
     * @return $this
     */
    public function append($result)
    {
        if ($result instanceof \Magento\Quote\Model\Quote\Address\RateResult\Error) {
            $this->setError(true);
        }
        if ($result instanceof \Magento\Quote\Model\Quote\Address\RateResult\AbstractResult) {
            $this->_rates[] = $result;
        } elseif ($result instanceof \Magento\Shipping\Model\Rate\Result) {
            $rates = $result->getAllRates();
            foreach ($rates as $rate) {
                $this->append($rate);
            }
        }
        return $this;
    }

Some Magento shipping modules also don't expect the DataObject to be used:

Flatrate:

    /**
     * Collect and get rates
     *
     * @param RateRequest $request
     * @return Result|bool
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    public function collectRates(RateRequest $request)
    {
        /** @var Result $result */
        $result = $this->_rateResultFactory->create();
...
        return $result;
    }

Freeshipping:

    /**
     * FreeShipping Rates Collector
     *
     * @param RateRequest $request
     * @return \Magento\Shipping\Model\Rate\Result|bool
     */
    public function collectRates(RateRequest $request)
    {
...
        /** @var \Magento\Shipping\Model\Rate\Result $result */
        $result = $this->_rateResultFactory->create();
...
        return $result;
    }

UPS:

    /**
     * Collect and get rates/errors
     *
     * @param RateRequest $request
     * @return Result|Error|bool
     */
    public function collectRates(RateRequest $request)
    {
...
    }

Fedex:

    /**
     * Collect and get rates
     *
     * @param RateRequest $request
     * @return Result|bool|null
     */
    public function collectRates(RateRequest $request)
    {
        if (!$this->canCollectRates()) {
            return $this->getErrorMessage();
        }

        $this->setRequest($request);
        $this->_getQuotes();
        $this->_updateFreeMethodQuote($request);

        return $this->getResult();
    }

Basically no class expects \Magento\Framework\DataObject, as the AbstractCarrierInterface::collectRates() suggests.

Proposed solution

Change the method's signature to reflect the real world, but the method is marked with @api, so I don't know how to proceed.

m2-assistant[bot] commented 4 years ago

Hi @kassner. Thank you for your report. To help us process this issue please make sure that you provided the following information:

Please make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce. To deploy vanilla Magento instance on our environment, please, add a comment to the issue:

@magento give me 2.4-develop instance - upcoming 2.4.x release

For more details, please, review the Magento Contributor Assistant documentation.

Please, add a comment to assign the issue: @magento I am working on this


stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 14 days if no further activity occurs. Thank you for your contributions.

kassner commented 3 years ago

up

magento-engcom-team commented 3 years ago

:white_check_mark: Confirmed by @gabrieldagama Thank you for verifying the issue. Based on the provided information internal tickets MC-40335 were created

Issue Available: @gabrieldagama, You will be automatically unassigned. Contributors/Maintainers can claim this issue to continue. To reclaim and continue work, reassign the ticket to yourself.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 14 days if no further activity occurs. Is this issue still relevant? If so, what is blocking it? Is there anything you can do to help move it forward? Thank you for your contributions!

kassner commented 3 years ago

up