| 7 field.crud.inc | field_create_field($field) |
| 8 field.crud.inc | field_create_field($field) |
Creates a field.
This function does not bind the field to any bundle; use field_create_instance() for that.
Parameters
$field: A field definition array. The field_name and type properties are required. Other properties, if omitted, will be given the following default values:
- cardinality: 1
- locked: FALSE
- indexes: the field-type indexes, specified by the field type's hook_field_schema(). The indexes specified in $field are added to those default indexes. It is possible to override the definition of a field-type index by providing an index with the same name, or to remove it by redefining it as an empty array of columns. Overriding field-type indexes should be done carefully, for it might seriously affect the site's performance.
- settings: each omitted setting is given the default value defined in hook_field_info().
- storage:
- type: the storage backend specified in the 'field_storage_default' system variable.
- settings: each omitted setting is given the default value specified in hook_field_storage_info().
Return value
The $field array with the id property filled in.
Throws
See: Field API data structures.
Related topics
70 calls to field_create_field()
File
- modules/
field/ field.crud.inc, line 56 - Field CRUD API, handling field and field instance creation and deletion.
Code
function field_create_field($field) {
// Field name is required.
if (empty($field['field_name'])) {
throw new FieldException('Attempt to create an unnamed field.');
}
// Field type is required.
if (empty($field['type'])) {
throw new FieldException('Attempt to create a field with no type.');
}
// Field name cannot contain invalid characters.
if (!preg_match('/^[_a-z]+[_a-z0-9]*$/', $field['field_name'])) {
throw new FieldException('Attempt to create a field with invalid characters. Only lowercase alphanumeric characters and underscores are allowed, and only lowercase letters and underscore are allowed as the first character');
}
// Field name cannot be longer than 32 characters. We use drupal_strlen()
// because the DB layer assumes that column widths are given in characters,
// not bytes.
if (drupal_strlen($field['field_name']) > 32) {
throw new FieldException(t('Attempt to create a field with a name longer than 32 characters: %name',
array('%name' => $field['field_name'])));
}
// Ensure the field name is unique over active and disabled fields.
// We do not care about deleted fields.
$prior_field = field_read_field($field['field_name'], array('include_inactive' => TRUE));
if (!empty($prior_field)) {
$message = $prior_field['active'] ?
t('Attempt to create field name %name which already exists and is active.', array('%name' => $field['field_name'])) :
t('Attempt to create field name %name which already exists, although it is inactive.', array('%name' => $field['field_name']));
throw new FieldException($message);
}
// Disallow reserved field names. This can't prevent all field name
// collisions with existing entity properties, but some is better
// than none.
foreach (entity_get_info() as $type => $info) {
if (in_array($field['field_name'], $info['entity keys'])) {
throw new FieldException(t('Attempt to create field name %name which is reserved by entity type %type.', array('%name' => $field['field_name'], '%type' => $type)));
}
}
$field += array(
'entity_types' => array(),
'cardinality' => 1,
'translatable' => FALSE,
'locked' => FALSE,
'settings' => array(),
'storage' => array(),
'deleted' => 0,
);
// Check that the field type is known.
$field_type = field_info_field_types($field['type']);
if (!$field_type) {
throw new FieldException(t('Attempt to create a field of unknown type %type.', array('%type' => $field['type'])));
}
// Create all per-field-type properties (needed here as long as we have
// settings that impact column definitions).
$field['settings'] += field_info_field_settings($field['type']);
$field['module'] = $field_type['module'];
$field['active'] = 1;
// Provide default storage.
$field['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($field['storage']['type']);
if (!$storage_type) {
throw new FieldException(t('Attempt to create a field with unknown storage type %type.', array('%type' => $field['storage']['type'])));
}
// Provide default storage settings.
$field['storage']['settings'] += field_info_storage_settings($field['storage']['type']);
$field['storage']['module'] = $storage_type['module'];
$field['storage']['active'] = 1;
// Collect storage information.
module_load_install($field['module']);
$schema = (array) module_invoke($field['module'], 'field_schema', $field);
$schema += array(
'columns' => array(),
'indexes' => array(),
'foreign keys' => array(),
);
// 'columns' are hardcoded in the field type.
$field['columns'] = $schema['columns'];
// 'foreign keys' are hardcoded in the field type.
$field['foreign keys'] = $schema['foreign keys'];
// 'indexes' can be both hardcoded in the field type, and specified in the
// incoming $field definition.
$field += array(
'indexes' => array(),
);
$field['indexes'] += $schema['indexes'];
// The serialized 'data' column contains everything from $field that does not
// have its own column and is not automatically populated when the field is
// read.
$data = $field;
unset($data['columns'], $data['field_name'], $data['type'], $data['active'], $data['module'], $data['storage_type'], $data['storage_active'], $data['storage_module'], $data['locked'], $data['cardinality'], $data['deleted']);
// Additionally, do not save the 'bundles' property populated by
// field_info_field().
unset($data['bundles']);
$record = array(
'field_name' => $field['field_name'],
'type' => $field['type'],
'module' => $field['module'],
'active' => $field['active'],
'storage_type' => $field['storage']['type'],
'storage_module' => $field['storage']['module'],
'storage_active' => $field['storage']['active'],
'locked' => $field['locked'],
'data' => $data,
'cardinality' => $field['cardinality'],
'translatable' => $field['translatable'],
'deleted' => $field['deleted'],
);
// Store the field and get the id back.
drupal_write_record('field_config', $record);
$field['id'] = $record['id'];
// Invoke hook_field_storage_create_field after the field is
// complete (e.g. it has its id).
try {
// Invoke hook_field_storage_create_field after
// drupal_write_record() sets the field id.
module_invoke($storage_type['module'], 'field_storage_create_field', $field);
}
catch (Exception $e) {
// If storage creation failed, remove the field_config record before
// rethrowing the exception.
db_delete('field_config')
->condition('id', $field['id'])
->execute();
throw $e;
}
// Clear caches
field_cache_clear(TRUE);
// Invoke external hooks after the cache is cleared for API consistency.
module_invoke_all('field_create_field', $field);
return $field;
}
Login or register to post comments
Comments
field id property
i don't understand the purpose of this function's return value and specifically the id property of the field .
field_create_instance needs only the name of the field for field_name , in other words it doesn't require the structure returned by this function
How to programatically add fields to the user entity
Example on how to programatically add fields to the user profile and how to avail them, or not, into the User Registration form.
<?php
/**
* Implementation of hook_enable().
*/
function MYMODULE_enable() {
// Check if our field is not already created.
if (!field_info_field('field_myField')) {
$field = array(
'field_name' => 'field_myField',
'type' => 'text',
);
field_create_field($field);
// Create the instance on the bundle.
$instance = array(
'field_name' => 'field_myField',
'entity_type' => 'user',
'label' => 'My Field Name',
'bundle' => 'user',
// If you don't set the "required" property then the field wont be required by default.
'required' => TRUE,
'settings' => array(
// Here you inform either or not you want this field showing up on the registration form.
'user_register_form' => 1,
),
'widget' => array(
'type' => 'textfield',
),
);
field_create_instance($instance);
}
}
?>
It doesn't look like the
It doesn't look like the 'no_ui' seeting is working properly as of Drupal 7.10.
I have this
<?php$field['settings']['no_ui'] = TRUE;
?>
however, even with this, other content types can add the field from the UI.
Is there anyway to stop this?
thanks!
david barratt
Really working example of creating & instantiating a field
Here I programmatically create & instantiate a field called 'MYMODULE_rating'. The field is defined in the same module which tries to create it in hook_enable()
MYMODULE.install
<?php
/** Implements hook_enable()
*/
function MYMODULE_enable(){
# Use me. Otherwise, I won't work because I don't know your custom defined fields ]:->
field_cache_clear();
field_associate_fields('MYMODULE');
# Already created?
if (field_info_field('MYMODULE_rating'))
return;
# Create the field singleton
$field = array( 'field_name' => 'MYMODULE_rating', 'type' => 'MYMODULE_rating', );
$field = field_create_field($field);
# Create the instance on the bundle.
$instance = array(
'field_name' => $field['field_name'],
'entity_type' => 'node',
'bundle' => 'wine',
'label' => 'Rating',
'description' => 'Rating information',
'required' => TRUE,
'settings' => array(),
'widget' => array(),
'display' => array(
'default' => array('label' => 'hidden'),
),
);
field_create_instance($instance);
$instance['bundle'] = 'review';
field_create_instance($instance);
}
?>
For the curious: the field was declared in MYMODULE.field.inc:
<?php
/** Implements hook_field_info() */
function MYMODULE_field_info(){
# Rating field
$fields['MYMODULE_rating'] = array(
'label' => t('Rating'),
'description' => t('rating information'),
'settings' => array(),
'instance_settings' => array(),
'default_widget' => 'MYMODULE_hidden',
'default_formatter' => 'MYMODULE_rating',
);
return $fields; # Get all field types with: field_info_field_types()
}
// ... also implemented the default_widget, default_formatter & hook_field_load()
?>