Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
For a field of type list_text you can do the following:
$field = field_info_field('field_custom_field');
if (empty($field)) {
$field = array(
'field_name' => 'field_custom_field',
'type' => 'list_text',
'entity_types' => array('node'),
'locked' => TRUE,
'settings' => array(
'allowed_values_function' => 'node_type_get_names',
),
);
field_create_field($field);
}
This way you can populate a select list with all available node types, or whatever your callback will return.
If you would do the same for nodereference you could do something like:
$field = field_info_field('field_custom_field2');
if (empty($field)) {
$field = array(
'field_name' => 'field_custom_field2',
'type' => 'node_reference',
'entity_types' => array('node'),
'locked' => TRUE,
'settings' => array(
'referenceable_types_function' => 'my_node_types_function',
),
);
field_create_field($field);
}
function my_node_types_function() {
return drupal_map_assoc(array_keys(node_type_get_names()));
}
This way all node types will always be available even when more are created afterwards. Developers could also filter the node types in their callback function however they like. For fields of the 'list_text' type this setting can only be set in code, not through the interface as far as I know, so it's protected from users that don't know PHP.