Apply a custom hasAffectingChanges to avoid "Non-translatable fields can only be changed when updating the original language." message when changing block properties

Created on 7 April 2025, 18 days ago

Problem/Motivation

When changing some block properties (block custom plugin), if a block field has been added to a revisionable entity, the error "Non-translatable fields can only be changed when updating the original language" might appear as the settings are now different.

Proposed resolution

I think the settings of a block plugin are meaningless and should not be compared in hasAffectingChanges, so probably a custom FieldItemList could fix this issue.

This is also solvable by just skipping the block fields using https://www.drupal.org/node/2938191

📌 Task
Status

Active

Version

1.0

Component

Code

Created by

🇪🇸Spain pcambra Asturies

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @pcambra
  • 🇪🇸Spain pcambra Asturies

    Example on how we could apply this:

    on the .module file:

    /**
     * Implements hook_field_info_alter().)
     */
    function my_module_field_info_alter(&$info) {
      if (isset($info['block_field'])) {
        // Override the list class for the block_field field type to avoid comparing
        // plugin changes between revisions.
        // @see \Drupal\Core\Field\FieldItemList::hasAffectingChanges()
        // @see https://www.drupal.org/project/block_field/issues/3517759
        $info['block_field']['list_class'] = '\Drupal\my_module\BlockFieldItemList';
      }
    }
    

    The custom BlockFieldItemList class:

    <?php
    
    namespace Drupal\my_module;
    
    use Drupal\Core\Field\FieldItemList;
    use Drupal\Core\Field\FieldItemListInterface;
    
    /**
     * Avoids block plugin fields to be compared between revisions.
     */
    class BlockFieldItemList extends FieldItemList {
    
      /**
       * {@inheritdoc}
       */
      public function hasAffectingChanges(FieldItemListInterface $original_items, $langcode) {
        // If there are different items, then it is a change.
        if (count($this) != count($original_items)) {
          return TRUE;
        }
    
        foreach ($this as $delta => $item) {
          if ($item->getProperties()['plugin_id']->getValue() != $original_items[$delta]->getProperties()['plugin_id']->getValue()) {
            return TRUE;
          }
        }
    
        return FALSE;
      }
    
    }
    
    
Production build 0.71.5 2024