summaryrefslogtreecommitdiff
path: root/modules/field/field.module
diff options
context:
space:
mode:
Diffstat (limited to 'modules/field/field.module')
-rw-r--r--modules/field/field.module308
1 files changed, 266 insertions, 42 deletions
diff --git a/modules/field/field.module b/modules/field/field.module
index d470c9fd7..4182e88a1 100644
--- a/modules/field/field.module
+++ b/modules/field/field.module
@@ -365,75 +365,308 @@ function _field_sort_items_value_helper($a, $b) {
}
/**
- * Registry of pseudo-field components in a given bundle.
+ * Gets or sets administratively defined bundle settings.
+ *
+ * For each bundle, settings are provided as a nested array with the following
+ * structure:
+ * @code
+ * array(
+ * 'view_modes' => array(
+ * // One sub-array per view mode for the entity type:
+ * 'full' => array(
+ * 'custom_display' => Whether the view mode uses custom display
+ * settings or settings of the 'default' mode,
+ * ),
+ * 'teaser' => ...
+ * ),
+ * 'extra_fields' => array(
+ * 'form' => array(
+ * // One sub-array per pseudo-field in displayed entities:
+ * 'extra_field_1' => array(
+ * 'weight' => The weight of the pseudo-field,
+ * ),
+ * 'extra_field_2' => ...
+ * ),
+ * 'display' => array(
+ * // One sub-array per pseudo-field in displayed entities:
+ * 'extra_field_1' => array(
+ * // One sub-array per view mode for the entity type, including
+ * // the 'default' mode:
+ * 'default' => array(
+ * 'weight' => The weight of the pseudo-field,
+ * 'visibility' => Whether the pseudo-field is visible or hidden,
+ * ),
+ * 'full' => ...
+ * ),
+ * 'extra_field_2' => ...
+ * ),
+ * ),
+ * ),
+ * @encode
*
* @param $entity_type
* The type of $entity; e.g. 'node' or 'user'.
* @param $bundle
* The bundle name.
+ * @param $settings
+ * (optional) The settings to store.
+ *
+ * @return
+ * If no $settings are passed, the current settings are returned.
+ */
+function field_bundle_settings($entity_type, $bundle, $settings = NULL) {
+ $stored_settings = variable_get('field_bundle_settings', array());
+
+ if (isset($settings)) {
+ $stored_settings[$entity_type][$bundle] = $settings;
+ variable_set('field_bundle_settings', $stored_settings);
+ drupal_static_reset('field_view_mode_settings');
+ drupal_static_reset('field_extra_fields');
+ }
+ else {
+ $settings = isset($stored_settings[$entity_type][$bundle]) ? $stored_settings[$entity_type][$bundle] : array();
+ $settings += array(
+ 'view_modes' => array(),
+ 'extra_fields' => array(),
+ );
+
+ return $settings;
+ }
+}
+
+/**
+ * Returns view mode settings in a given bundle.
+ *
+ * @param $entity_type
+ * The type of entity; e.g. 'node' or 'user'.
+ * @param $bundle
+ * The bundle name to return view mode settings for.
+ *
+ * @return
+ * An array keyed by view mode, with the following key/value pairs:
+ * - custom_settings: Boolean specifying whether the view mode uses a
+ * dedicated set of display options (TRUE), or the 'default' options
+ * (FALSE). Defaults to FALSE.
+ */
+function field_view_mode_settings($entity_type, $bundle) {
+ $cache = &drupal_static(__FUNCTION__, array());
+
+ if (!isset($cache[$entity_type][$bundle])) {
+ $bundle_settings = field_bundle_settings($entity_type, $bundle);
+ $settings = $bundle_settings['view_modes'];
+ // Include view modes for which nothing has been stored yet, but whose
+ // definition in hook_entity_info() specify they should use custom settings
+ // by default.
+ $entity_info = entity_get_info($entity_type);
+ foreach ($entity_info['view modes'] as $view_mode => $view_mode_info) {
+ if (!isset($settings[$view_mode]['custom_settings']) && $view_mode_info['custom settings']) {
+ $settings[$view_mode]['custom_settings'] = TRUE;
+ }
+ }
+ $cache[$entity_type][$bundle] = $settings;
+ }
+
+ return $cache[$entity_type][$bundle];
+}
+
+/**
+ * Returns a list and settings of pseudo-field elements in a given bundle.
+ *
+ * If $context is 'form', an array with the following structure:
+ * @code
+ * array(
+ * 'name_of_pseudo_field_component' => array(
+ * 'label' => The human readable name of the component,
+ * 'description' => A short description of the component content,
+ * 'weight' => The weight of the component in edit forms,
+ * ),
+ * 'name_of_other_pseudo_field_component' => array(
+ * // ...
+ * ),
+ * );
+ * @endcode
+ *
+ * If $context is 'display', an array with the following structure:
+ * @code
+ * array(
+ * 'name_of_pseudo_field_component' => array(
+ * 'label' => The human readable name of the component,
+ * 'description' => A short description of the component content,
+ * // One entry per view mode, including the 'default' mode:
+ * 'display' => array(
+ * 'default' => array(
+ * 'weight' => The weight of the component in displayed entities in
+ * this view mode,
+ * 'visibility' => Whether the component is visible or hidden in
+ * displayed entities in this view mode,
+ * ),
+ * 'teaser' => array(
+ * // ...
+ * ),
+ * ),
+ * ),
+ * 'name_of_other_pseudo_field_component' => array(
+ * // ...
+ * ),
+ * );
+ * @endcode
+ *
+ * @param $entity_type
+ * The type of entity; e.g. 'node' or 'user'.
+ * @param $bundle
+ * The bundle name.
+ * @param $context
+ * The context for which the list of pseudo-fields is requested. Either
+ * 'form' or 'display'.
+ *
* @return
* The array of pseudo-field elements in the bundle.
*/
-function field_extra_fields($entity_type, $bundle) {
- $info = &drupal_static(__FUNCTION__, array());
+function field_extra_fields($entity_type, $bundle, $context) {
+ $extra = &drupal_static(__FUNCTION__);
- if (empty($info)) {
+ if (!isset($extra)) {
$info = (array) module_invoke_all('field_extra_fields');
drupal_alter('field_extra_fields', $info);
- // Add saved weights. The array is keyed by entity type, bundle and
- // element name.
- $extra_weights = variable_get('field_extra_weights', array());
- foreach ($extra_weights as $entity_type_name => $bundles) {
- foreach ($bundles as $bundle_name => $weights) {
- foreach ($weights as $key => $value) {
- if (isset($info[$entity_type_name][$bundle_name][$key])) {
- $info[$entity_type_name][$bundle_name][$key]['weight'] = $value;
+ // Merge in saved settings, and make sure we have settings for all view
+ // modes.
+ foreach ($info as $entity_type_name => $bundles) {
+ $entity_type_info = entity_get_info($entity_type_name);
+ foreach ($bundles as $bundle_name => $extra_fields) {
+ $bundle_settings = field_bundle_settings($entity_type_name, $bundle_name);
+ $extra_fields += array('form' => array(), 'display' => array());
+
+ // Extra fields in forms.
+ $data = $extra_fields['form'];
+ foreach ($data as $name => $field_data) {
+ $settings = isset($bundle_settings['extra_fields']['form'][$name]) ? $bundle_settings['extra_fields']['form'][$name] : array();
+ if (isset($settings['weight'])) {
+ $data[$name]['weight'] = $settings['weight'];
}
}
+ $extra[$entity_type_name][$bundle_name]['form'] = $data;
+
+ // Extra fields in displayed entities.
+ $data = $extra_fields['display'];
+ foreach ($data as $name => $field_data) {
+ $settings = isset($bundle_settings['extra_fields']['display'][$name]) ? $bundle_settings['extra_fields']['display'][$name] : array();
+ $view_modes = array_merge(array('default'), array_keys($entity_type_info['view modes']));
+ foreach ($view_modes as $view_mode) {
+ if (isset($settings[$view_mode])) {
+ $data[$name]['display'][$view_mode] = $settings[$view_mode];
+ }
+ else {
+ $data[$name]['display'][$view_mode] = array(
+ 'weight' => $field_data['weight'],
+ 'visible' => TRUE,
+ );
+ }
+ unset($data[$name]['weight']);
+ }
+ }
+ $extra[$entity_type_name][$bundle_name]['display'] = $data;
}
}
}
- return isset($info[$entity_type][$bundle]) ? $info[$entity_type][$bundle]: array();
+ return isset($extra[$entity_type][$bundle][$context]) ? $extra[$entity_type][$bundle][$context] : array();
+}
+
+
+/**
+ * Returns the display settings to use for an instance in a given view mode.
+ *
+ * @param $instance
+ * The field instance being displayed.
+ * @param $view_mode
+ * The view mode.
+ *
+ * @return
+ * The display settings to be used when displaying the field values.
+ */
+function field_get_display($instance, $view_mode) {
+ // Check whether the view mode uses custom display settings or the 'default'
+ // mode.
+ $view_mode_settings = field_view_mode_settings($instance['entity_type'], $instance['bundle']);
+ $actual_mode = (!empty($view_mode_settings[$view_mode]['custom_settings']) ? $view_mode : 'default');
+ $display = $instance['display'][$actual_mode];
+
+ // Let modules alter the display settings.
+ $context = array(
+ 'entity_type' => $instance['entity_type'],
+ 'field' => field_info_field($instance['field_name']),
+ 'instance' => $instance,
+ 'view_mode' => $view_mode,
+ );
+ drupal_alter(array('field_display', 'field_display_' . $instance['entity_type']), $display, $context);
+
+ return $display;
}
/**
- * Retrieve the user-defined weight for a 'pseudo-field' component.
+ * Returns the display settings to use for pseudo-fields in a given view mode.
*
* @param $entity_type
* The type of $entity; e.g. 'node' or 'user'.
* @param $bundle
* The bundle name.
- * @param $pseudo_field
- * The name of the 'pseudo-field'.
+ * @param $view_mode
+ * The view mode.
+ *
* @return
- * The weight for the 'pseudo-field', respecting the user settings stored by
- * field.module.
+ * The display settings to be used when viewing the bundle's pseudo-fields.
*/
-function field_extra_field_weight($entity_type, $bundle, $pseudo_field) {
- $extra = field_extra_fields($entity_type, $bundle);
- if (isset($extra[$pseudo_field])) {
- return $extra[$pseudo_field]['weight'];
+function field_extra_fields_get_display($entity_type, $bundle, $view_mode) {
+ // Check whether the view mode uses custom display settings or the 'default'
+ // mode.
+ $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
+ $actual_mode = (!empty($view_mode_settings[$view_mode]['custom_settings'])) ? $view_mode : 'default';
+ $extra_fields = field_extra_fields($entity_type, $bundle, 'display');
+
+ $displays = array();
+ foreach ($extra_fields as $name => $value) {
+ $displays[$name] = $extra_fields[$name]['display'][$actual_mode];
}
+
+ // Let modules alter the display settings.
+ $context = array(
+ 'entity_type' => $entity_type,
+ 'bundle' => $bundle,
+ 'view_mode' => $view_mode,
+ );
+ drupal_alter('field_extra_fields_display', $displays, $context);
+
+ return $displays;
}
/**
- * Pre-render callback to adjust weights of non-field elements on entities.
+ * Pre-render callback to adjust weights and visibility of non-field elements.
*/
-function _field_extra_weights_pre_render($elements) {
- if (isset($elements['#extra_fields'])) {
- foreach ($elements['#extra_fields'] as $key => $value) {
- // Some core 'fields' use a different key in node forms and in 'view'
- // render arrays. Ensure that we are not on a form first.
- if (!isset($elements['#build_id']) && isset($value['view']) && isset($elements[$value['view']])) {
- $elements[$value['view']]['#weight'] = $value['weight'];
+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_extra_fields($entity_type, $bundle, 'form');
+ foreach ($extra_fields as $name => $settings) {
+ if (isset($elements[$name])) {
+ $elements[$name]['#weight'] = $settings['weight'];
}
- elseif (isset($elements[$key])) {
- $elements[$key]['#weight'] = $value['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;
}
@@ -543,7 +776,7 @@ function field_view_value($entity_type, $entity, $field_name, $item, $display =
* display settings specified for this view mode in the $instance
* definition for the field in the entity's bundle.
* If no display settings are found for the view mode, the settings for
- * the 'full' view mode will be used.
+ * the 'default' view mode will be used.
* - An array of display settings, as found in the 'display' entry of
* $instance definitions. The following key/value pairs are allowed:
* - label: (string) Position of the label. The default 'field' theme
@@ -574,15 +807,6 @@ function field_view_field($entity_type, $entity, $field_name, $display = array()
// When using custom display settings, fill in default values.
$display = _field_info_prepare_instance_display($field, $display);
}
- else {
- // When using a view mode, make sure we have settings for it, or fall
- // back to the 'full' view mode.
- list(, , $bundle) = entity_extract_ids($entity_type, $entity);
- $instance = field_info_instance($entity_type, $field_name, $bundle);
- if (!isset($instance['display'][$display])) {
- $display = 'full';
- }
- }
// Hook invocations are done through the _field_invoke() functions in
// 'single field' mode, to reuse the language fallback logic.