/** * Check if a field on the entity type to update is a possible destination field. * * @todo Should this be on our FieldManager service? * * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $definition * Field definition on entity type to update to check. * @param \Drupal\Core\Field\FieldDefinitionInterface $source_field * Source field to check compatibility against. If none then check generally. * * @return bool */ protected function isDestinationFieldCompatible(FieldStorageDefinitionInterface $definition, FieldDefinitionInterface $source_field = NULL) { // @todo Create field definition wrapper class to treat FieldDefinitionInterface and FieldStorageDefinitionInterface the same. if ($definition instanceof BaseFieldDefinition && $definition->isReadOnly()) { return FALSE; } // Don't allow updates on updates! if ($definition->getType() == 'entity_reference') { if ($definition->getSetting('target_type') == 'scheduled_update') { return FALSE; } } if ($source_field) { $matching_types = $this->getMatchingFieldTypes($source_field->getType()); if (!in_array($definition->getType(), $matching_types)) { return FALSE; } // Check cardinality $destination_cardinality = $definition->getCardinality(); $source_cardinality = $source_field->getFieldStorageDefinition()->getCardinality(); // $destination_cardinality is unlimited. It doesn't matter what source is. if ($destination_cardinality != -1) { if ($source_cardinality == -1) { return FALSE; } if ($source_cardinality > $destination_cardinality) { return FALSE; } } switch ($definition->getType()) { case 'entity_reference': // Entity reference field must match entity target types. if ($definition->getSetting('target_type') != $source_field->getSetting('target_type')) { return FALSE; } // @todo Check bundles break; // @todo Other type specific conditions? } } return TRUE; }