I wrote a function to sort / re-order the line items in a cart.

function sortCart(Order $order) {
    $lineItems = $order->getLineItems();
    $lineItemsOrdered = array();

    // [...]


it works, but obviously this only changes the in-memory order object. how can I make it so that the order is also persisted in the database? I would like to see the line items in the modified order in the craft backend.


the sorting logic depends on a field set in the EVENT_AFTER_CAPTURE_PRODUCT_SNAPSHOT event, so EVENT_BEFORE_SAVE won't work because it runs earlier.

Craft::$app->getElements()->saveElement($order, false); in an adjuster will cause an endless loop.

how do I do this?

edit: apparently the order is determined by the creation date of the line items. however this doesn't work either:

    function (ModelEvent $event) {
        $order = $event->sender;
        sortCart($order); // also sets `dateCreated` on line item

        // log shows the correct order/timestamps
        foreach ($order->getLineItems() as $item) {
            Module::info($item->dateCreated->format(\DateTime::ATOM) . ': ' . $item->getDescription());

1 Answer 1


Can you try using EVENT_POPULATE_LINE_ITEM? Not sure, but it fired AFTER the product & variant snapshot event. Here you can take any necessary fields & data, including one from the snapshot.

    use yii\base\Event;
    use craft\commerce\events\LineItemEvent;
    use craft\commerce\services\LineItems;


        function (LineItemEvent $e) {
            $lineItem = $e->lineItem;
            $snapshot = $lineItem->snapshot;
            $order = $lineItem->order;
            // ....

            // Changing some values
            $lineItem->privateNote = 'Testing';

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.