1

I've built a plugin that catches the order beforeSave event in order to add some extra data to the an order attribute. The problem is that when this plugin fires it causes an error:

Uncaught TypeError: Argument 1 passed to Magento\Sales\Model\OrderRepository::save() must implement interface Magento\Sales\Api\Data\OrderInterface, string given, called in /var/www/html/vendor/magento/framework/Interception/Interceptor.php on line 58 and defined in /var/www/html/vendor/magento/module-sales/Model/OrderRepository.php:156
Stack trace:
#0 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Sales\Model\OrderRepository->save('sales_order', 'order', NULL, NULL, NULL, NULL, Array, NULL, NULL, Array, true, 'order', Object(Magento\Store\Model\StoreManager), Object(Magento\Sales\Model\Order\Config), Object(Magento\Catalog\Model\ProductRepository\Interceptor), Object(Magento\Catalog\Model\ResourceModel\Product\CollectionFactory), Object(Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory), Object(Magento\Catalog\Model\Product\Visibility), Object(Magento\Sales\Model\Service\InvoiceService), Object(Magento\Directory\Model\CurrencyF"

I've cut down my plugin so it does absolutely nothing other than return the same object in gets at the start and I'm still getting this same issue. For example;

class OrderPlugin
{

protected $_logger;
protected $_orderApi;
protected $_orderAttributeFactory;
protected $_orderExtensionFactory;

public function __construct(\Psr\Log\LoggerInterface $logger, Data $helper, \MyModule\Shipstation\Model\OrderAttributeFactory $orderAttributeFactory, OrderExtensionFactory $orderExtensionFactory)
{
    $this->_logger = $logger;
    $this->helper = $helper;
    $this->_orderAttributeFactory = $orderAttributeFactory;
    $this->_orderExtensionFactory = $orderExtensionFactory;
}

public function beforeSave(\Magento\Sales\Api\OrderRepositoryInterface $subject, \Magento\Sales\Api\Data\OrderInterface $order){

    //$resultOrder = $this->saveFarmisonOrderIDAttribute($resultOrder);

    return $order;

}

my di.xml looks like;

<type name="Magento\Sales\Api\OrderRepositoryInterface">
    <plugin name="MyModule_Shipstation::orderPlugin" type="MyModule\Shipstation\Plugin\OrderPlugin" />
    <plugin name="MyModule_Shipstation::deliverydatePlugin" type="MyModule\Shipstation\Plugin\DeliveryDatePlugin" />
</type>

If I totally comment out my beforeSave method then the save works correctly as expected/

4 Answers 4

3

The solution I found was to simply remove the return from the function. Setting that value I wanted on the order object was enough and simply removing the return allowed the code to run as expected.

public function beforeSave(\Magento\Sales\Model\OrderRepository $subject, $resultOrder){

       $this->saveOrderIDAttribute($resultOrder);

}

What I don't know is why beforeSave doesn't like having the Order object returned. Where as afterGet works exactly as I would expect and accepts the order object from the return.

public function afterGet(\Magento\Sales\Api\OrderRepositoryInterface $subject, \Magento\Sales\Api\Data\OrderInterface $order){

    $order = $this->getOrderIDAttribute($order);

    return $order;
}
0

You can try this way,

app/code/Vendor/Module/etc/di.xml

<type name="Magento\Sales\Model\Order">
    <plugin name="Plugin Name" type="Vendor\Module\Plugin\Order" sortOrder="10" disabled="false"/>
</type>

app/code/Vendor/Module/Plugin/Order.php

public function beforeSave(\Magento\Sales\Model\Order $subject)
{
$subject->getData() 
// this is your order Data before saving it
}

Hope it Helps.

0

Change di.xml

<type name="Magento\Sales\Api\OrderRepositoryInterface">
    <plugin name="MyModule_OrderPlugin" type="MyModule\Shipstation\Plugin\OrderPlugin" />
    <plugin name="MyModule_DeliveryDatePlugin" type="MyModule\Shipstation\Plugin\DeliveryDatePlugin" />
</type>
1
  • Can you explain why?
    – Matthew
    Commented Jul 30, 2019 at 11:09
0

The error being thrown is most likely:

Argument 1 passed to Magento\Sales\Model\OrderRepository::save() must implement interface Magento\Sales\Api\Data\OrderInterface, string given

To solve this issue, the plugin would need to return an array instead:

return [$order];

Per the devdocs:

"You can use before methods to change the arguments of an observed method by returning a modified argument. If there are any arguments, the method should return an array of those arguments. If the method does not change the argument for the observed method, it should return a null value."

https://developer.adobe.com/commerce/php/development/components/plugins/#before-methods

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.