Problem/Motivation

Originally raised this in #2563843-37: MapItem is broken for configurable fields but now splitting this off into its own issue.

FieldItemInterface::schema() states:

  /**
   * ...
   *
   * @return array
   *   An empty array if there is no schema, or an associative array with the
   *   following key/value pairs:
   *   - columns: An array of Schema API column specifications, keyed by column
   *     name. The columns need to be a subset of the properties defined in
   *     propertyDefinitions().
   * ...
   */

So since MapItem::schema() returns a value column, you would expect that there must be a value property defined by MapItem::propertyDefinitions().

That is no longer the case, however, since #2229181: MapItem::propertyDefinitions() claims it has a static value property, which is wrong.

Besides clearly being a violation of the API, this breaks any widget that you try to write for MapItem as widgets rely on the aforementioned relationship between schema columns and properties. Possibly other things are broken as well, but this is the one I encountered.

Proposed resolution

Roll back #2229181: MapItem::propertyDefinitions() claims it has a static value property, which is wrong.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tstoeckler created an issue. See original summary.

Berdir’s picture

How do widgets rely on that? Anything on widgets can be overridden to do whatever you want? Widgets like Paragraphs and IEF have litte/nothing to do with the property/schema structure.

I agree that it does violate the documentation/description there, but it does reflect how it really behaves?

The only way to respect that documentation would be to change MapItem so that it contains a value map property, but that would obviously be a bigger API change.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

joachim’s picture

It think it's this which causes a crash when installing an entity type using this field type (in my case, as a bundle field coming from a Commerce bundle plugin):

Error: Call to a member function isRequired() on null in             [error]
Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema->getDedicatedTableSchema()
(line 1846 of
core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php)
Wim Leers’s picture

Quoting @tstoeckler at #2906600-7: FieldItemList::equals() doesn't work correctly for computed fields with custom storage:

  1. Map fields will always be considered equal regardless of their values due to #2887105: MapItem violates FieldItemInterface::schema()'s contract - breaks widgets. Note that even though I consider that a bug I don't think it makes sense to block this (or anything) on that as @Berdir does not consider it a bug, so regardless where we collectively come down on this I don't think it will be fixed anytime soon.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Wim Leers’s picture

Wim Leers’s picture

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Niklan’s picture

There is another problem with that definition removal. The base fields of "map" type can't be uninstalled.

Definition:

$fields['contribution_statistics'] = BaseFieldDefinition::create('map')
      ->setLabel(t('Contribution statistics'))
      ->setDescription(t('The contribution statistics of source file.'))
      ->setRequired(TRUE)
      ->setDisplayConfigurable('form', FALSE)
      ->setDisplayConfigurable('view', FALSE);

Hook update which tries to uninstall it:

  $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
  if ($field_definition = $definition_update_manager->getFieldStorageDefinition('contribution_statistics', 'my_entity_type_id')) {
    $definition_update_manager->uninstallFieldStorageDefinition($field_definition);
  }

This hook update fails with

>  [error]  Call to a member function isRequired() on null 

. This is because isRequired() checks for !empty($this->definition['required']), but $this->definition is an empty array, since there is no definition!

I've managed to fix this by rollback the definition removal and run the update, which ended successfully. I think this issue needs more attention.

Attach the patch which solve my problem.

andypost’s picture

Status: Active » Needs review
tstoeckler’s picture

Re #12: Note that #2563843: MapItem is broken for configurable fields (which I just retitled and rebased) may help you as well. If not it would be great to know where isRequired() is being called would be awesome if you could provide some additional info in that case.

Niklan’s picture

@tstoeckler there is no nothing special. Simple content entity type + definition I've provided. It can't be uninstalled. It fails when check its property "is required", but there is no property.

I can't test your solution right now, since I bypass this error by temporary rollback definition removal. But this can be easily reproduced with just 1 base field installed on entity and trying to uninstall it then via hook_update_N().

Actually I copy-pasted all the code that reproduces bug as it is.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Sam152’s picture

Here is another impact this issue is having: #3145076: [backport] MapItem base fields cannot be uninstalled.

Edit: I can see this was mentioned in #12.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative, +Needs tests

This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.

Seems the last patch had some failures in D8 (triggered for D10)

Think we will need a test case also to show the issue.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.