cms icon indicating copy to clipboard operation
cms copied to clipboard

[4.x]: Propagation error when adding custom validation to an entry field inside a matrix block

Open johndwells opened this issue 2 years ago • 1 comments

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:

  1. Set up a multisite, at least 2 sites
  2. Set up a section of any kind, and enable for all sites
  3. 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"
  4. 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)
  5. Add the matrix field to the section created in step 2
  6. Add a custom site module with the above code

Then, follow these steps:

  1. Create a new entry
  2. Fill out mandatory fields (e.g. title)
  3. Hit Save & Continue Editing so that the entry is published and propagated
  4. Add one matrix block, and select/add an entry relationship
  5. 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:

  1. 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 !)
  2. 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

johndwells avatar Sep 27 '23 19:09 johndwells

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.

i-just avatar Oct 09 '23 11:10 i-just