toArray(); $values['bundle'] = $bundle; $values['baseFieldDefinition'] = $base_field_definition; return \Drupal::entityManager()->getStorage('base_field_override')->create($values); } /** * Constructs a BaseFieldOverride object. * * In most cases, base field override entities are created via * BaseFieldOverride::createFromBaseFieldDefinition($definition, 'bundle') * * @param array $values * An array of base field bundle override properties, keyed by property * name. The field to override is specified by referring to an existing * field with: * - field_name: The field name. * - entity_type: The entity type. * Additionally, a 'bundle' property is required to indicate the entity * bundle to which the bundle field override is attached to. Other array * elements will be used to set the corresponding properties on the class; * see the class property documentation for details. * @param string $entity_type * (optional) The type of the entity to create. Defaults to * 'base_field_override'. * * @see entity_create() * * @throws \Drupal\Core\Field\FieldException * Exception thrown if $values does not contain a field_name, entity_type or * bundle value. */ public function __construct(array $values, $entity_type = 'base_field_override') { if (empty($values['field_name'])) { throw new FieldException('Attempt to create a base field bundle override of a field without a field_name'); } if (empty($values['entity_type'])) { throw new FieldException("Attempt to create a base field bundle override of field {$values['field_name']} without an entity_type"); } if (empty($values['bundle'])) { throw new FieldException("Attempt to create a base field bundle override of field {$values['field_name']} without a bundle"); } parent::__construct($values, $entity_type); } /** * {@inheritdoc} */ public function getFieldStorageDefinition() { return $this->getBaseFieldDefinition()->getFieldStorageDefinition(); } /** * {@inheritdoc} */ public function isDisplayConfigurable($context) { return $this->getBaseFieldDefinition()->isDisplayConfigurable($context); } /** * {@inheritdoc} */ public function getDisplayOptions($display_context) { return $this->getBaseFieldDefinition()->getDisplayOptions($display_context); } /** * {@inheritdoc} */ public function isReadOnly() { return $this->getBaseFieldDefinition()->isReadOnly(); } /** * {@inheritdoc} */ public function isComputed() { return $this->getBaseFieldDefinition()->isComputed(); } /** * {@inheritdoc} */ public function getClass() { return $this->getBaseFieldDefinition()->getClass(); } /** * {@inheritdoc} */ public function getUniqueIdentifier() { return $this->getBaseFieldDefinition()->getUniqueIdentifier(); } /** * Gets the base field definition. * * @return \Drupal\Core\Field\BaseFieldDefinition */ protected function getBaseFieldDefinition() { if (!isset($this->baseFieldDefinition)) { $fields = $this->entityManager()->getBaseFieldDefinitions($this->entity_type); $this->baseFieldDefinition = $fields[$this->getName()]; } return $this->baseFieldDefinition; } /** * {@inheritdoc} * * @throws \Drupal\Core\Field\FieldException * If the bundle is being changed. */ public function preSave(EntityStorageInterface $storage) { // Filter out unknown settings and make sure all settings are present, so // that a complete field definition is passed to the various hooks and // written to config. $field_type_manager = \Drupal::service('plugin.manager.field.field_type'); $default_settings = $field_type_manager->getDefaultFieldSettings($this->getType()); $this->settings = array_intersect_key($this->settings, $default_settings) + $default_settings; // Call the parent's presave method to perform validate and calculate // dependencies. parent::preSave($storage); if ($this->isNew()) { // @todo This assumes that the previous definition isn't some // non-config-based override, but that might not be the case: // https://www.drupal.org/node/2321071. $previous_definition = $this->getBaseFieldDefinition(); } else { // Some updates are always disallowed. if ($this->entity_type != $this->original->entity_type) { throw new FieldException("Cannot change the entity_type of an existing base field bundle override (entity type:{$this->entity_type}, bundle:{$this->original->bundle}, field name: {$this->field_name})"); } if ($this->bundle != $this->original->bundle) { throw new FieldException("Cannot change the bundle of an existing base field bundle override (entity type:{$this->entity_type}, bundle:{$this->original->bundle}, field name: {$this->field_name})"); } $previous_definition = $this->original; } // Notify the entity storage. $this->entityManager()->getStorage($this->getTargetEntityTypeId())->onFieldDefinitionUpdate($this, $previous_definition); } /** * {@inheritdoc} */ public static function postDelete(EntityStorageInterface $storage, array $field_overrides) { $entity_manager = \Drupal::entityManager(); // Clear the cache upfront, to refresh the results of getBundles(). $entity_manager->clearCachedFieldDefinitions(); /** @var \Drupal\Core\Field\Entity\BaseFieldOverride $field_override */ foreach ($field_overrides as $field_override) { // Inform the system that the field definition is being updated back to // its non-overridden state. // @todo This assumes that there isn't a non-config-based override that // we're returning to, but that might not be the case: // https://www.drupal.org/node/2321071. $entity_manager->getStorage($field_override->getTargetEntityTypeId())->onFieldDefinitionUpdate($field_override->getBaseFieldDefinition(), $field_override); } } /** * Loads a base field bundle override config entity. * * @param string $entity_type_id * ID of the entity type. * @param string $bundle * Bundle name. * @param string $field_name * Name of the field. * * @return static * The base field bundle override config entity if one exists for the * provided field name, otherwise NULL. */ public static function loadByName($entity_type_id, $bundle, $field_name) { return \Drupal::entityManager()->getStorage('base_field_override')->load($entity_type_id . '.' . $bundle . '.' . $field_name); } /** * Implements the magic __sleep() method. */ public function __sleep() { // Only serialize necessary properties, excluding those that can be // recalculated. unset($this->baseFieldDefinition); return parent::__sleep(); } }