Problem/Motivation

Drupal 11.4 changes how constraints are defined. In 11.3 and older, calling getConstraint on a data definition would return a scalar string, while in 11.3 they now return an array.

Steps to reproduce

Examine this code in TypedDataRelationshipDeriver::generateDerivativeDefinition:

  protected function generateDerivativeDefinition($base_plugin_definition, $data_type_id, $data_type_definition, DataDefinitionInterface $base_definition, $property_name, DataDefinitionInterface $property_definition) {
    $bundle_info = $base_definition->getConstraint('Bundle');
    // Identify base definitions that appear on bundle-able entities.
    if ($bundle_info && array_filter($bundle_info) && $base_definition->getConstraint('EntityType')) {
      $base_data_type = 'entity:' . $base_definition->getConstraint('EntityType');
    }
    // Otherwise, just use the raw data type identifier.
    else {
      $base_data_type = $data_type_id;
    }
 // ...

Because in Drupal 11.4 the result of getConstraint is an array, the $base_data_type variable ends up being set to 'entity:Array' rather than the correct entity type ID. As of 11.4 the inner array needs to be unpacked to get the entity type ID value. The same also applies to the bundle constraint at the top of this method.

Proposed resolution

Wherever a constraint is retrieved, ctools needs to check if the result is a string or an array in order to support both Drupal 11.4 and older versions. The above example would be rewritten as:

protected function generateDerivativeDefinition($base_plugin_definition, $data_type_id, $data_type_definition, DataDefinitionInterface $base_definition, $property_name, DataDefinitionInterface $property_definition) {
    $bundle_constraint = $base_definition->getConstraint('Bundle');
    if (is_array($bundle_constraint) && isset($bundle_constraint['bundle'])) {
      $bundle_info = $bundle_constraint['bundle'];
    }
    else {
      $bundle_info = $bundle_constraint;
    }
    // Identify base definitions that appear on bundle-able entities.
    if ($bundle_info && array_filter($bundle_info) && $base_definition->getConstraint('EntityType')) {
      $entity_type_constraint = $base_definition->getConstraint('EntityType');
      if (is_array($entity_type_constraint) && isset($entity_type_constraint['type'])) {
        $entity_type_id = $entity_type_constraint['type'];
      }
      else {
        $entity_type_id = $entity_type_constraint;
      }
      $base_data_type = 'entity:' . $entity_type_id;
    }
   // ...

I've put together a patch that changes all occurrences I could find, but would appreciate review/testing from someone who is more familiar with the ctools codebase.

Issue fork ctools-3609591

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jeremyskinner created an issue. See original summary.

jeremyskinner’s picture

Priority: Normal » Major
jeremyskinner’s picture

Issue summary: View changes
StatusFileSize
new4.56 KB

Updated patch to correct some errors

liam morland made their first commit to this issue’s fork.

liam morland’s picture

Version: 4.1.0 » 4.1.x-dev
Status: Active » Needs review

I created a merge request with the patch in #3.