Saves a new field definition.
int SAVED_NEW if the definition was saved.
\Drupal\field\FieldException If the field definition is invalid.
\Drupal\Core\Entity\EntityStorageException In case of failures at the configuration storage level.
protected function saveNew() {
$module_handler = \Drupal::moduleHandler();
$entity_manager = \Drupal::entityManager();
$storage_controller = $entity_manager
->getStorageController($this->entityType);
// Field name cannot be longer than Field::ID_MAX_LENGTH characters. We
// use drupal_strlen() because the DB layer assumes that column widths
// are given in characters rather than bytes.
if (drupal_strlen($this->id) > static::ID_MAX_LENGTH) {
throw new FieldException(format_string('Attempt to create a field with an ID longer than @max characters: %id', array(
'@max' => static::ID_MAX_LENGTH,
'%id' => $this->id,
)));
}
// Ensure the field name is unique (we do not care about deleted fields).
if ($prior_field = current($storage_controller
->load(array(
$this->id,
)))) {
$message = $prior_field->active ? 'Attempt to create field name %id which already exists and is active.' : 'Attempt to create field name %id which already exists, although it is inactive.';
throw new FieldException(format_string($message, array(
'%id' => $this->id,
)));
}
// Disallow reserved field names. This can't prevent all field name
// collisions with existing entity properties, but some is better than
// none.
foreach ($entity_manager
->getDefinitions() as $type => $info) {
if (in_array($this->id, $info['entity_keys'])) {
throw new FieldException(format_string('Attempt to create field %id which is reserved by entity type %type.', array(
'%id' => $this->id,
'%type' => $type,
)));
}
}
// Check that the field type is known.
$field_type = field_info_field_types($this->type);
if (!$field_type) {
throw new FieldException(format_string('Attempt to create a field of unknown type %type.', array(
'%type' => $this->type,
)));
}
$this->module = $field_type['module'];
$this->active = TRUE;
// Make sure all settings are present, so that a complete field
// definition is passed to the various hooks and written to config.
$this->settings += $field_type['settings'];
// Provide default storage.
$this->storage += array(
'type' => variable_get('field_storage_default', 'field_sql_storage'),
'settings' => array(),
);
// Check that the storage type is known.
$storage_type = field_info_storage_types($this->storage['type']);
if (!$storage_type) {
throw new FieldException(format_string('Attempt to create a field with unknown storage type %type.', array(
'%type' => $this->storage['type'],
)));
}
$this->storage['module'] = $storage_type['module'];
$this->storage['active'] = TRUE;
// Provide default storage settings.
$this->storage['settings'] += $storage_type['settings'];
// Invoke the storage backend's hook_field_storage_create_field().
$module_handler
->invoke($this->storage['module'], 'field_storage_create_field', array(
$this,
));
// Save the configuration.
$result = parent::save();
field_cache_clear();
// Invoke hook_field_create_field() after the cache is cleared for API
// consistency.
$module_handler
->invokeAll('field_create_field', array(
$this,
));
return $result;
}