namespace Drupal\field\Entity;
-use Drupal\Component\Utility\Unicode;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
+use Drupal\Core\Entity\FieldableEntityStorageInterface;
use Drupal\Core\Field\FieldException;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\OptionsProviderInterface;
* @ConfigEntityType(
* id = "field_storage_config",
* label = @Translation("Field storage"),
+ * label_collection = @Translation("Field storages"),
+ * label_singular = @Translation("field storage"),
+ * label_plural = @Translation("field storages"),
+ * label_count = @PluralTranslation(
+ * singular = "@count field storage",
+ * plural = "@count field storages",
+ * ),
* handlers = {
* "access" = "Drupal\field\FieldStorageConfigAccessControlHandler",
* "storage" = "Drupal\field\FieldStorageConfigStorage"
// Assign the ID.
$this->id = $this->id();
- // Field name cannot be longer than FieldStorageConfig::NAME_MAX_LENGTH characters.
- // We use Unicode::strlen() because the DB layer assumes that column widths
- // are given in characters rather than bytes.
- if (Unicode::strlen($this->getName()) > static::NAME_MAX_LENGTH) {
+ // Field name cannot be longer than FieldStorageConfig::NAME_MAX_LENGTH
+ // characters. We use mb_strlen() because the DB layer assumes that column
+ // widths are given in characters rather than bytes.
+ if (mb_strlen($this->getName()) > static::NAME_MAX_LENGTH) {
throw new FieldException('Attempt to create a field storage with an name longer than ' . static::NAME_MAX_LENGTH . ' characters: ' . $this->getName());
}
* {@inheritdoc}
*/
public static function preDelete(EntityStorageInterface $storage, array $field_storages) {
- $state = \Drupal::state();
+ /** @var \Drupal\Core\Field\DeletedFieldsRepositoryInterface $deleted_fields_repository */
+ $deleted_fields_repository = \Drupal::service('entity_field.deleted_fields_repository');
// Set the static flag so that we don't delete field storages whilst
// deleting fields.
// Delete or fix any configuration that is dependent, for example, fields.
parent::preDelete($storage, $field_storages);
- // Keep the field definitions in the state storage so we can use them later
- // during field_purge_batch().
- $deleted_storages = $state->get('field.storage.deleted') ?: [];
+ // Keep the field storage definitions in the deleted fields repository so we
+ // can use them later during field_purge_batch().
+ /** @var \Drupal\field\FieldStorageConfigInterface $field_storage */
foreach ($field_storages as $field_storage) {
- if (!$field_storage->deleted) {
- $config = $field_storage->toArray();
- $config['deleted'] = TRUE;
- $config['bundles'] = $field_storage->getBundles();
- $deleted_storages[$field_storage->uuid()] = $config;
+ // Only mark a field for purging if there is data. Otherwise, just remove
+ // it.
+ $target_entity_storage = \Drupal::entityTypeManager()->getStorage($field_storage->getTargetEntityTypeId());
+ if (!$field_storage->deleted && $target_entity_storage instanceof FieldableEntityStorageInterface && $target_entity_storage->countFieldData($field_storage, TRUE)) {
+ $storage_definition = clone $field_storage;
+ $storage_definition->deleted = TRUE;
+ $deleted_fields_repository->addFieldStorageDefinition($storage_definition);
}
}
-
- $state->set('field.storage.deleted', $deleted_storages);
}
/**
* {@inheritdoc}
*/
public function getCardinality() {
- return $this->cardinality;
+ /** @var \Drupal\Core\Field\FieldTypePluginManager $field_type_manager */
+ $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
+ $definition = $field_type_manager->getDefinition($this->getType());
+ $enforced_cardinality = isset($definition['cardinality']) ? $definition['cardinality'] : NULL;
+
+ // Enforced cardinality is a positive integer or -1.
+ if ($enforced_cardinality !== NULL && $enforced_cardinality < 1 && $enforced_cardinality !== FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
+ throw new FieldException("Invalid enforced cardinality '$enforced_cardinality'. Allowed values: a positive integer or -1.");
+ }
+
+ return $enforced_cardinality ?: $this->cardinality;
}
/**