1

I'm trying to reorder Matrix Blocks in date order when saving an entry in the control panel. I kind of have it working using the following code.

My Matrix field is 'events'. Each block contains a date field called 'startDate'.

Event::on(Entry::class, Element::EVENT_BEFORE_SAVE, function(ModelEvent $e) {
    // @var Entry $entry
    $entry = $e->sender;

    if (ElementHelper::isDraftOrRevision($entry)) {
        return;
    }

    $blocks = $entry->getFieldValue('events')->orderBy('startDate ASC');
    
    $entry->setFieldValue('events', $blocks);

});

My problem is that I have to save the Entry TWICE for the above code to actually work. I've read that I should maybe use EVENT_AFTER_PROPAGATE instead but when I try that I can't get it to work at all.

Does anybody know how I can get this working?

1 Answer 1

1

I managed to figure this out. Here is my working solution.

Event::on(Entry::class, Element::EVENT_AFTER_PROPAGATE, function(ModelEvent $e) {
    // @var Entry $entry
    $entry = $e->sender;

    if (ElementHelper::isDraftOrRevision($entry)) {
        return;
    }

    if ($entry->section->handle != 'events') {
        return;
    }

    $old = $entry->getFieldValue('events');

    $new = (clone $old)->orderBy('startDate ASC');

    if ($old->ids() == $new->ids()) {
        return;
    }
    
    $entry->setFieldValue('events', $new);
    Craft::$app->elements->saveElement($entry);

});

Hopefully this helps somebody :)

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.