1

I try to validate some fields before saving the entry, if the field is invalid, prevent the entry from saving and return the error message, I'm doing it via Element::EVENT_BEFORE_SAVE event.

It works for such a Plain Text field

// the attribute 'resourceTitle' is the field's handle
$entry->addError('resourceTitle', 'The title is invalid.');

enter image description here

But for a Matrix field, I don't what's the attribute, using the field handle(resourceId) is not working.

the source code the field is something like this:

<input type="text" id="fields-products-blocks-167910-fields-resourceId" name="fields[products][blocks][167910][fields][resourceId]" value="796">

I tried:

$entry->addError('resourceId', 'The resource id is invalid');
$entry->addError('fields-products-blocks-167910-fields-resourceId', 'The resource id is invalid');
$entry->addError('fields[products][blocks][167910][fields][resourceId]', 'The resource id is invalid');

All failed. not sure what's the attribute. enter image description here

1 Answer 1

1

Matrix blocks are elements themselves, so the individual fields of a matrix block aren't available as properties on the entry. In the entry save hook, the only thing you can add errors to (that will be picked up by the interface) is the matrix field itself, using the matrix field's handle:

use craft\elements\Entry;
use craft\events\ModelEvent;
use yii\base\Event;

Event::on(
    Entry::class,
    Entry::EVENT_BEFORE_SAVE,
    function (ModelEvent $e) {
        $e->sender->addError('products', 'The resource ID is invalid.');
        $e->isValid = false;
    }
);

However, those errors won't be attached to the resource ID itself, but to the matrix field, and they will be displayed below the list of matrix blocks. Not very useful.


Instead, you want to hook into the validation of matrix blocks themselves. Entry saves will validate matrix blocks and display any errors that occur (this will also prevent the entry from being saving). So you can use MatrixBlock::EVENT_AFTER_VALIDATE to add your own validation to matrix blocks. Using that event, you can add validation errors using the handles of the fields inside your matrix blocks, they will be picked up and displayed in the interface automatically.

use craft\elements\MatrixBlock;
use yii\base\Event;

Event::on(
    MatrixBlock::class,
    MatrixBlock::EVENT_AFTER_VALIDATE,
    function (Event $e) {
        $e->sender->addError('resourceId', 'The resource ID is invalid.');
    }
);

Make sure to check the matrix block's type and only apply your custom validation to the type with the resource ID field.

If you need to access the entry the matrix block belongs to for some custom validation logic, you can get to it using $e->sender->owner. See MatrixBlock::$owner.

1
  • 2
    thank you so much, work like a charm.
    – Thomas
    Commented Nov 3, 2021 at 14:33

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.