[4.x]: Propagation error when adding custom validation to an entry field inside a matrix block
What happened?
Description
We have a matrix field set up, and in one of the blocks is an entry relationship field. With our site module, we have added custom validation to ensure the entries selected in this field pass certain business logic criteria.
The site is multisite; the matrix field's "Propagation Method" is set to "Save blocks to all sites the owner element is saved in"; the entry relationship field has "Manage relations on a per-site basis" un-ticked. As a result, the same entry field relationships are saved across all enabled sites.
Our validation rules run fine, except once the editor tries to fix the error (either by removing the selection, and/or picking a new valid entry). At this point an exception is thrown: Couldn’t propagate element to other site.
Here is the distilled code we are using. First up, in our site module we add validation rules to the matrix block:
use craft\base\Model;
use craft\elements\MatrixBlock;
use craft\events\DefineRulesEvent;
use yii\base\Event;
Event::on(
MatrixBlock::class,
Model::EVENT_DEFINE_RULES,
static function(DefineRulesEvent $event) {
// business logic to bind the validation rule only to relevant matrix block goes here...
$event->rules[] = [
[
'fieldHandle',
],
CustomValidator::class
];
}
);
And here is our CustomValidator class:
<?php
namespace modules\sitemodule\validators;
use craft\helpers\ElementHelper;
use yii\validators\Validator;
class CustomValidator extends Validator
{
public function validateAttribute($model, $attribute): void
{
if (ElementHelper::isDraftOrRevision($model)) {
return;
}
// No errors if no entry
$entry = $model->$attribute->status(null)->one();
if(! $entry) {
return;
}
// business logic validation goes here...
$model->addError($attribute, 'Custom validation error message');
}
}
Steps to reproduce
First, set the scene:
- Set up a multisite, at least 2 sites
- Set up a section of any kind, and enable for all sites
- Set up a matrix field containing a single block; set its "Propagation Method" to "Save blocks to all sites the owner element is saved in"
- Add an entry relationship custom field to this matrix block; be sure that "Manage relations on a per-site basis" is un-ticked (recommend relating to a separate entry section, its configuration does not matter)
- Add the matrix field to the section created in step 2
- Add a custom site module with the above code
Then, follow these steps:
- Create a new entry
- Fill out mandatory fields (e.g. title)
- Hit Save & Continue Editing so that the entry is published and propagated
- Add one matrix block, and select/add an entry relationship
- Hit "Save and continue editing"
If everything works, at this point the page should come back and show our error message on the matrix block's relationship field, "Custom validation error message".
Now, attempt to resolve the error:
- Remove the entry relationship (If you do nothing, Craft will attempt to auto-save your work, but the autosave icon will turn into an alert !)
- Hit "Save and continue editing"
Expected behavior
The page should come back without any errors.
Actual behavior
The yii\base\Exception is thrown: "Couldn’t propagate element to other site."
Craft CMS version
4.4.17
PHP version
8.1.16
Operating system and version
Linux 5.15.49-linuxkit-pr
Database type and version
MariaDB 10.3.38
Image driver and version
Imagick 3.7.0 (ImageMagick 6.9.11-60)
Installed plugins and versions
No response
Hi, thanks for reaching out! Could you please post the stack trace from the logs too? You should see something along the lines of “yii\base\Exception: Couldn’t propagate element to other site.” followed by the stack trace.