hook_field_extra_fields() is invoked by _field_extra_fields_pre_render(), which is a pre-render function used by field_attach_form(), and field_attach_view().
/**
* Pre-render callback to adjust weights and visibility of non-field elements.
*/
function _field_extra_fields_pre_render($elements) {
$entity_type = $elements['#entity_type'];
$bundle = $elements['#bundle'];
if (isset($elements['#type']) && $elements['#type'] == 'form') {
$extra_fields = field_info_extra_fields($entity_type, $bundle, 'form');
foreach ($extra_fields as $name => $settings) {
if (isset($elements[$name])) {
$elements[$name]['#weight'] = $settings['weight'];
}
}
}
elseif (isset($elements['#view_mode'])) {
$view_mode = $elements['#view_mode'];
$extra_fields = field_extra_fields_get_display($entity_type, $bundle, $view_mode);
foreach ($extra_fields as $name => $settings) {
if (isset($elements[$name])) {
$elements[$name]['#weight'] = $settings['weight'];
// Visibility: make sure we do not accidentally show a hidden element.
$elements[$name]['#access'] = isset($elements[$name]['#access']) ? ($elements[$name]['#access'] && $settings['visible']) : $settings['visible'];
}
}
}
return $elements;
}
Using those functions, you should not invoke the hook directly. Those functions are already used for entities that Drupal knows; if you are implementing a field for nodes, all you need to do is implementing the hook.
An example of hook_field_extra_fields() implementation is mollom_field_extra_fields().
function mollom_field_extra_fields() {
$extras = array();
$forms = array_flip(db_query('SELECT form_id FROM {mollom_form}')->fetchCol());
foreach (mollom_form_list() as $form_id => $info) {
// @todo Technically, an 'entity' does not need to be a Entity/Field API
// kind of entity. Ideally of course, developers should use fieldable
// entities, but contributed/custom code may not. It is not clear whether
// registering extra fields for non-existing entities/bundles can break
// anything, so leaving it this way for now.
if (isset($info['entity']) && isset($forms[$form_id])) {
// If the entity type does not implement bundles, then entity_get_info()
// assumes a single bundle named after the entity.
$entity_type = $info['entity'];
$bundle = (isset($info['bundle']) ? $info['bundle'] : $entity_type);
$extras[$entity_type][$bundle]['form']['mollom'] = array(
'label' => t('Mollom'),
'description' => t('Mollom CAPTCHA or privacy policy link'),
'weight' => 99,
);
}
}
return $extras;
}