/** * {@inheritdoc} */ public function deleteLastInstalledFieldStorageDefinition(FieldStorageDefinitionInterface $storage_definition) { $entity_type_id = $storage_definition->getTargetEntityTypeId(); $definitions = $this->getLastInstalledFieldStorageDefinitions($entity_type_id); unset($definitions[$storage_definition->getName()]); $this->setLastInstalledFieldStorageDefinitions($entity_type_id, $definitions); }
/** * {@inheritdoc} */ public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { // This is called very early by the user entity roles field. Prevent // early t() calls by using the TranslationWrapper. $properties['value'] = DataDefinition::create('string')->setLabel(new TranslationWrapper('Text value'))->setSetting('case_sensitive', $field_definition->getSetting('case_sensitive'))->setRequired(TRUE); return $properties; }
/** * {@inheritdoc} */ public function setUp() { parent::setUp(); $field_name = 'test_options'; $this->fieldStorage = entity_create('field_storage_config', ['field_name' => $field_name, 'entity_type' => 'entity_test', 'type' => 'list_string', 'cardinality' => 1, 'settings' => ['allowed_values_function' => 'options_test_dynamic_values_callback']]); $this->fieldStorage->save(); $this->field = entity_create('field_config', ['field_name' => $field_name, 'entity_type' => 'entity_test', 'bundle' => 'entity_test', 'required' => TRUE])->save(); }
/** * {@inheritdoc} */ protected function setUp($import_test_views = TRUE) { parent::setUp(); $field_name = 'test_options'; $this->fieldStorage = FieldStorageConfig::create(['field_name' => $field_name, 'entity_type' => 'entity_test', 'type' => 'list_string', 'cardinality' => 1, 'settings' => ['allowed_values_function' => 'options_test_dynamic_values_callback']]); $this->fieldStorage->save(); $this->field = FieldConfig::create(['field_name' => $field_name, 'entity_type' => 'entity_test', 'bundle' => 'entity_test', 'required' => TRUE])->save(); }
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { $foreign_keys = array(); // The 'foreign keys' key is not always used in tests. if ($field_definition->getSetting('foreign_key_name')) { $foreign_keys['foreign keys'] = array($field_definition->getSetting('foreign_key_name') => array('table' => $field_definition->getSetting('foreign_key_name'), 'columns' => array($field_definition->getSetting('foreign_key_name') => 'id'))); } return array('columns' => array('shape' => array('type' => 'varchar', 'length' => 32), 'color' => array('type' => 'varchar', 'length' => 32))) + $foreign_keys; }
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { $target_type = $field_definition->getSetting('target_type'); $target_type_info = \Drupal::entityManager()->getDefinition($target_type); if ($target_type_info->isSubclassOf('\\Drupal\\Core\\Entity\\FieldableEntityInterface')) { $columns = array('target_id' => array('description' => 'The ID of the target entity.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE)); } else { $columns = array('target_id' => array('description' => 'The ID of the target entity.', 'type' => 'varchar', 'length' => $target_type_info->getBundleOf() ? EntityTypeInterface::BUNDLE_MAX_LENGTH : 255)); } $schema = array('columns' => $columns, 'indexes' => array('target_id' => array('target_id'))); return $schema; }
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field) { $backendManager = \Drupal::service('plugin.manager.geofield_backend'); $backendPlugin = NULL; if (isset($field->settings['backend']) && $backendManager->getDefinition($field->settings['backend']) != NULL) { $backendPlugin = $backendManager->createInstance($field->getSetting('backend')); } if ($backendPlugin === NULL) { $backendPlugin = $backendManager->createInstance('geofield_backend_default'); } return array('columns' => array('value' => $backendPlugin->schema(), 'geo_type' => array('type' => 'varchar', 'default' => '', 'length' => 64), 'lat' => array('type' => 'numeric', 'precision' => 18, 'scale' => 12, 'not null' => FALSE), 'lon' => array('type' => 'numeric', 'precision' => 18, 'scale' => 12, 'not null' => FALSE), 'left' => array('type' => 'numeric', 'precision' => 18, 'scale' => 12, 'not null' => FALSE), 'top' => array('type' => 'numeric', 'precision' => 18, 'scale' => 12, 'not null' => FALSE), 'right' => array('type' => 'numeric', 'precision' => 18, 'scale' => 12, 'not null' => FALSE), 'bottom' => array('type' => 'numeric', 'precision' => 18, 'scale' => 12, 'not null' => FALSE), 'geohash' => array('type' => 'varchar', 'length' => GEOFIELD_GEOHASH_LENGTH, 'not null' => FALSE)), 'indexes' => array('lat' => array('lat'), 'lon' => array('lon'), 'top' => array('top'), 'bottom' => array('bottom'), 'left' => array('left'), 'right' => array('right'), 'geohash' => array('geohash'), 'centroid' => array('lat', 'lon'), 'bbox' => array('top', 'bottom', 'left', 'right'))); }
protected function setUp() { parent::setUp(); $field_name = 'test_options'; $this->fieldStorage = FieldStorageConfig::create(['field_name' => $field_name, 'entity_type' => 'entity_test_rev', 'type' => 'list_string', 'cardinality' => 1, 'settings' => ['allowed_values_function' => 'options_test_dynamic_values_callback']]); $this->fieldStorage->save(); $this->field = FieldConfig::create(['field_name' => $field_name, 'entity_type' => 'entity_test_rev', 'bundle' => 'entity_test_rev', 'required' => TRUE])->save(); entity_get_form_display('entity_test_rev', 'entity_test_rev', 'default')->setComponent($field_name, ['type' => 'options_select'])->save(); // Create an entity and prepare test data that will be used by // options_test_dynamic_values_callback(). $values = ['user_id' => mt_rand(1, 10), 'name' => $this->randomMachineName()]; $this->entity = EntityTestRev::create($values); $this->entity->save(); $this->test = ['label' => $this->entity->label(), 'uuid' => $this->entity->uuid(), 'bundle' => $this->entity->bundle(), 'uri' => $this->entity->url()]; }
/** * 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; }
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { $type = $field_definition->getSetting('data_type'); $schema = array('columns' => array('value' => array('type' => $type))); if ($type == 'varchar') { $schema['columns']['value']['length'] = (int) $field_definition->getSetting('data_length'); } if ($type == 'text' || $type == 'int' || $type == 'float') { $schema['columns']['value']['size'] = $field_definition->getSetting('data_size'); } if ($type == 'decimal') { $schema['columns']['value']['precision'] = (int) $field_definition->getSetting('data_precision'); $schema['columns']['value']['scale'] = (int) $field_definition->getSetting('data_scale'); } return $schema; }
/** * Compares schemas to check for changes in the column definitions. * * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition * Current field storage definition. * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $original * The original field storage definition. * * @return bool * Returns TRUE if there are schema changes in the column definitions. */ protected function hasColumnChanges(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) { if ($storage_definition->getColumns() != $original->getColumns()) { // Base field definitions have schema data stored in the original // definition. return TRUE; } if (!$storage_definition->hasCustomStorage()) { $keys = array_flip($this->getColumnSchemaRelevantKeys()); $definition_schema = $this->getSchemaFromStorageDefinition($storage_definition); foreach ($this->loadFieldSchemaData($original) as $table => $table_schema) { foreach ($table_schema['fields'] as $name => $spec) { $definition_spec = array_intersect_key($definition_schema[$table]['fields'][$name], $keys); $stored_spec = array_intersect_key($spec, $keys); if ($definition_spec != $stored_spec) { return TRUE; } } } } return FALSE; }
/** * Generates a safe and unambiguous field table name. * * The method accounts for a maximum table name length of 64 characters, and * takes care of disambiguation. * * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition * The field storage definition. * @param bool $revision * TRUE for revision table, FALSE otherwise. * * @return string * The final table name. */ protected function generateFieldTableName(FieldStorageDefinitionInterface $storage_definition, $revision) { $separator = $revision ? '_revision__' : '__'; $table_name = $storage_definition->getTargetEntityTypeId() . $separator . $storage_definition->getName(); // Limit the string to 48 characters, keeping a 16 characters margin for db // prefixes. if (strlen($table_name) > 48) { // Use a shorter separator, a truncated entity_type, and a hash of the // field UUID. $separator = $revision ? '_r__' : '__'; // Truncate to the same length for the current and revision tables. $entity_type = substr($storage_definition->getTargetEntityTypeId(), 0, 34); $field_hash = substr(hash('sha256', $storage_definition->getUniqueStorageIdentifier()), 0, 10); $table_name = $entity_type . $separator . $field_hash; } return $table_name; }
/** * Determines whether the passed field has been already deleted. * * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition * The field storage definition. * * @return bool * Whether the field has been already deleted. */ protected function storageDefinitionIsDeleted(FieldStorageDefinitionInterface $storage_definition) { return !array_key_exists($storage_definition->getName(), $this->entityManager->getLastInstalledFieldStorageDefinitions($this->entityTypeId)); }
/** * Creates a new field definition based upon a field storage definition. * * In cases where one needs a field storage definitions to act like full * field definitions, this creates a new field definition based upon the * (limited) information available. That way it is possible to use the field * definition in places where a full field definition is required; e.g., with * widgets or formatters. * * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $definition * The field storage definition to base the new field definition upon. * * @return $this */ public static function createFromFieldStorageDefinition(FieldStorageDefinitionInterface $definition) { return static::create($definition->getType())->setCardinality($definition->getCardinality())->setConstraints($definition->getConstraints())->setCustomStorage($definition->hasCustomStorage())->setDescription($definition->getDescription())->setLabel($definition->getLabel())->setName($definition->getName())->setProvider($definition->getProvider())->setQueryable($definition->isQueryable())->setRequired($definition->isRequired())->setRevisionable($definition->isRevisionable())->setSettings($definition->getSettings())->setTargetEntityTypeId($definition->getTargetEntityTypeId())->setTranslatable($definition->isTranslatable()); }
/** * Generates a column name for a field data table. * * @private Calling this function circumvents the entity system and is * strongly discouraged. This function is not considered part of the public * API and modules relying on it might break even in minor releases. Only * call this function to write a query that \Drupal::entityQuery() does not * support. Always call entity_load() before using the data found in the * table. * * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition * The field storage definition. * @param string $column * The name of the column. * * @return string * A string containing a generated column name for a field data table that is * unique among all other fields. */ public static function _fieldColumnName(FieldStorageDefinitionInterface $storage_definition, $column) { return in_array($column, FieldStorageConfig::getReservedColumns()) ? $column : $storage_definition->getName() . '_' . $column; }
/** * {@inheritdoc} */ public function getFieldColumnName(FieldStorageDefinitionInterface $storage_definition, $column) { return in_array($column, $this->getReservedColumns()) ? $column : $storage_definition->getName() . '_' . $column; }
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { return array('columns' => array('value' => array('type' => 'varchar', 'length' => $field_definition->getSetting('max_length')), 'format' => array('type' => 'varchar', 'length' => 255)), 'indexes' => array('format' => array('format'))); }
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { return array('columns' => array('value' => array('type' => $field_definition->getSetting('case_sensitive') ? 'blob' : 'text', 'size' => 'big'))); }
/** * {@inheritdoc} */ public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { $subfield_types = self::subfieldTypes(); $settings = $field_definition->getSettings(); foreach (['first', 'second'] as $subfield) { $subfield_type = $settings['storage'][$subfield]['type']; // Typed data are slightly different from schema the definition. if ($subfield_type == 'text') { $subfield_type = 'string'; } elseif ($subfield_type == 'numeric') { $subfield_type = 'float'; } $properties[$subfield] = DataDefinition::create($subfield_type)->setLabel($subfield_types[$subfield_type]); } return $properties; }
/** * {@inheritdoc} */ public function getAllFieldConfigsForField(FieldStorageDefinitionInterface $definition, $entity_type_id) { $map = $this->entityFieldManager->getFieldMap()[$entity_type_id]; $definitions = []; $field_name = $definition->getName(); if (isset($map[$field_name])) { $bundles = $map[$field_name]['bundles']; foreach ($bundles as $bundle) { $bundle_definitions = $this->entityFieldManager->getFieldDefinitions($entity_type_id, $bundle); $definitions[$bundle] = $bundle_definitions[$field_name]; } } return $definitions; }
/** * Determines whether the passed field has been already deleted. * * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition * The field storage definition. * * @return bool * Whether the field has been already deleted. */ protected function storageDefinitionIsDeleted(FieldStorageDefinitionInterface $storage_definition) { // Configurable fields are marked for deletion. if ($storage_definition instanceof FieldStorageConfigInterface) { return $storage_definition->isDeleted(); } // For non configurable fields check whether they are still in the last // installed schema repository. return !array_key_exists($storage_definition->getName(), $this->entityManager->getLastInstalledFieldStorageDefinitions($this->entityTypeId)); }
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { $maxlenght = $field_definition->getSetting('maxlength'); return array('columns' => array('value' => array('type' => 'varchar', 'length' => $maxlenght, 'not null' => FALSE)), 'indexes' => array('value' => array('value'))); }
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { return array('columns' => array('value' => array('type' => 'numeric', 'precision' => $field_definition->getSetting('precision'), 'scale' => $field_definition->getSetting('scale')))); }
/** * Checks if the changes to the storage definition requires schema changes. * * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition * The updated field storage definition. * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $original * The original field storage definition. * * @return bool * TRUE if storage schema changes are required, FALSE otherwise. */ protected function requiresFieldStorageSchemaChanges(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) { $storage = $this->entityManager->getStorage($storage_definition->getTargetEntityTypeId()); return $storage instanceof DynamicallyFieldableEntityStorageSchemaInterface && $storage->requiresFieldStorageSchemaChanges($storage_definition, $original); }
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { return array('columns' => array('value' => array('type' => 'varchar', 'length' => (int) $field_definition->getSetting('max_length'), 'binary' => $field_definition->getSetting('case_sensitive')))); }
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { $target_type = $field_definition->getSetting('target_type'); $target_type_info = \Drupal::entityTypeManager()->getDefinition($target_type); $schema = parent::schema($field_definition); if ($target_type_info->getKey('revision')) { $schema['columns']['target_revision_id'] = array('description' => 'The revision ID of the target entity.', 'type' => 'int', 'unsigned' => TRUE); $schema['indexes']['target_revision_id'] = array('target_revision_id'); } return $schema; }
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { return array('columns' => array('value' => array('type' => 'varchar', 'length' => (int) $field_definition->getSetting('max_length'), 'not null' => FALSE))); }
/** * {@inheritdoc} */ public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $storage_definition) { $entity_type_id = $storage_definition->getTargetEntityTypeId(); // @todo Forward this to all interested handlers, not only storage, once // iterating handlers is possible: https://www.drupal.org/node/2332857. $storage = $this->entityTypeManager->getStorage($entity_type_id); if ($storage instanceof FieldStorageDefinitionListenerInterface) { $storage->onFieldStorageDefinitionDelete($storage_definition); } $this->eventDispatcher->dispatch(FieldStorageDefinitionEvents::DELETE, new FieldStorageDefinitionEvent($storage_definition)); $this->entityLastInstalledSchemaRepository->deleteLastInstalledFieldStorageDefinition($storage_definition); $this->entityFieldManager->clearCachedFieldDefinitions(); }
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { return array('columns' => array('value' => array('type' => 'int', 'not null' => FALSE, 'unsigned' => $field_definition->getSetting('unsigned'), 'size' => $field_definition->getSetting('size')))); }
/** * Generates an index name for a field data table. * * @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition * The field storage definition. * @param string $index * The name of the index. * * @return string * A string containing a generated index name for a field data table that is * unique among all other fields. */ protected function getFieldIndexName(FieldStorageDefinitionInterface $storage_definition, $index) { return $storage_definition->getName() . '_' . $index; }