field.default.inc

Default 'implementations' of hook_field_*(): common field housekeeping.

Those implementations are special, as field.module does not define any field types. Those functions take care of default stuff common to all field types. They are called through the _field_invoke_default() iterator, generally in the corresponding field_attach_[operation]() function.

File

drupal-7.x/modules/field/field.default.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * Default 'implementations' of hook_field_*(): common field housekeeping.
  5. *
  6. * Those implementations are special, as field.module does not define any field
  7. * types. Those functions take care of default stuff common to all field types.
  8. * They are called through the _field_invoke_default() iterator, generally in
  9. * the corresponding field_attach_[operation]() function.
  10. */
  11. /**
  12. * Extracts field values from submitted form values.
  13. *
  14. * @param $entity_type
  15. * The type of $entity.
  16. * @param $entity
  17. * The entity for the operation.
  18. * @param $field
  19. * The field structure for the operation.
  20. * @param $instance
  21. * The instance structure for $field on $entity's bundle.
  22. * @param $langcode
  23. * The language associated to $items.
  24. * @param $items
  25. * The field values. This parameter is altered by reference to receive the
  26. * incoming form values.
  27. * @param $form
  28. * The form structure where field elements are attached to. This might be a
  29. * full form structure, or a sub-element of a larger form.
  30. * @param $form_state
  31. * The form state.
  32. */
  33. function field_default_extract_form_values($entity_type, $entity, $field, $instance, $langcode, &$items, $form, &$form_state) {
  34. $path = array_merge($form['#parents'], array($field['field_name'], $langcode));
  35. $key_exists = NULL;
  36. $values = drupal_array_get_nested_value($form_state['values'], $path, $key_exists);
  37. if ($key_exists) {
  38. // Remove the 'value' of the 'add more' button.
  39. unset($values['add_more']);
  40. $items = $values;
  41. }
  42. }
  43. /**
  44. * Generic field validation handler.
  45. *
  46. * Possible error codes:
  47. * - 'field_cardinality': The number of values exceeds the field cardinality.
  48. *
  49. * @see _hook_field_validate()
  50. *
  51. * @param $entity_type
  52. * The type of $entity.
  53. * @param $entity
  54. * The entity for the operation.
  55. * @param $field
  56. * The field structure for the operation.
  57. * @param $instance
  58. * The instance structure for $field on $entity's bundle.
  59. * @param $langcode
  60. * The language associated to $items.
  61. * @param $items
  62. * $entity->{$field['field_name']}[$langcode], or an empty array if unset.
  63. * @param $errors
  64. * The array of errors, keyed by field name and by value delta, that have
  65. * already been reported for the entity. The function should add its errors
  66. * to this array. Each error is an associative array, with the following
  67. * keys and values:
  68. * - 'error': an error code (should be a string, prefixed with the module name)
  69. * - 'message': the human readable message to be displayed.
  70. */
  71. function field_default_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
  72. // Filter out empty values.
  73. $items = _field_filter_items($field, $items);
  74. // Check that the number of values doesn't exceed the field cardinality.
  75. // For form submitted values, this can only happen with 'multiple value'
  76. // widgets.
  77. if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED && count($items) > $field['cardinality']) {
  78. $errors[$field['field_name']][$langcode][0][] = array(
  79. 'error' => 'field_cardinality',
  80. 'message' => t('%name: this field cannot hold more than @count values.', array('%name' => $instance['label'], '@count' => $field['cardinality'])),
  81. );
  82. }
  83. }
  84. function field_default_submit($entity_type, $entity, $field, $instance, $langcode, &$items, $form, &$form_state) {
  85. // Filter out empty values.
  86. $items = _field_filter_items($field, $items);
  87. // Reorder items to account for drag-n-drop reordering.
  88. $items = _field_sort_items($field, $items);
  89. }
  90. /**
  91. * Default field 'insert' operation.
  92. *
  93. * Insert default value if no $entity->$field_name entry was provided.
  94. * This can happen with programmatic saves, or on form-based creation where
  95. * the current user doesn't have 'edit' permission for the field.
  96. */
  97. function field_default_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
  98. // _field_invoke() populates $items with an empty array if the $entity has no
  99. // entry for the field, so we check on the $entity itself.
  100. // We also check that the current field translation is actually defined before
  101. // assigning it a default value. This way we ensure that only the intended
  102. // languages get a default value. Otherwise we could have default values for
  103. // not yet open languages.
  104. if (empty($entity) || !property_exists($entity, $field['field_name']) ||
  105. (isset($entity->{$field['field_name']}[$langcode]) && count($entity->{$field['field_name']}[$langcode]) == 0)) {
  106. $items = field_get_default_value($entity_type, $entity, $field, $instance, $langcode);
  107. }
  108. }
  109. /**
  110. * Invokes hook_field_formatter_prepare_view() on the relevant formatters.
  111. *
  112. * @param $entity_type
  113. * The type of $entity; e.g. 'node' or 'user'.
  114. * @param $entities
  115. * An array of entities being displayed, keyed by entity id.
  116. * @param $field
  117. * The field structure for the operation.
  118. * @param $instances
  119. * Array of instance structures for $field for each entity, keyed by entity
  120. * id.
  121. * @param $langcode
  122. * The language associated to $items.
  123. * @param $items
  124. * Array of field values already loaded for the entities, keyed by entity id.
  125. * @param $display
  126. * Can be either:
  127. * - the name of a view mode
  128. * - or an array of display settings to use for display, as found in the
  129. * 'display' entry of $instance definitions.
  130. */
  131. function field_default_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $display) {
  132. // Group entities, instances and items by formatter module.
  133. $modules = array();
  134. foreach ($instances as $id => $instance) {
  135. if (is_string($display)) {
  136. $view_mode = $display;
  137. $instance_display = field_get_display($instance, $view_mode, $entities[$id]);
  138. }
  139. else {
  140. $instance_display = $display;
  141. }
  142. if ($instance_display['type'] !== 'hidden') {
  143. $module = $instance_display['module'];
  144. $modules[$module] = $module;
  145. $grouped_entities[$module][$id] = $entities[$id];
  146. $grouped_instances[$module][$id] = $instance;
  147. $grouped_displays[$module][$id] = $instance_display;
  148. // hook_field_formatter_prepare_view() alters $items by reference.
  149. $grouped_items[$module][$id] = &$items[$id];
  150. }
  151. }
  152. foreach ($modules as $module) {
  153. // Invoke hook_field_formatter_prepare_view().
  154. $function = $module . '_field_formatter_prepare_view';
  155. if (function_exists($function)) {
  156. $function($entity_type, $grouped_entities[$module], $field, $grouped_instances[$module], $langcode, $grouped_items[$module], $grouped_displays[$module]);
  157. }
  158. }
  159. }
  160. /**
  161. * Builds a renderable array for one field on one entity instance.
  162. *
  163. * @param $entity_type
  164. * The type of $entity; e.g. 'node' or 'user'.
  165. * @param $entity
  166. * A single object of type $entity_type.
  167. * @param $field
  168. * The field structure for the operation.
  169. * @param $instance
  170. * An array containing each field on $entity's bundle.
  171. * @param $langcode
  172. * The language associated to $items.
  173. * @param $items
  174. * Array of field values already loaded for the entities, keyed by entity id.
  175. * @param $display
  176. * Can be either:
  177. * - the name of a view mode;
  178. * - or an array of custom display settings, as found in the 'display' entry
  179. * of $instance definitions.
  180. */
  181. function field_default_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  182. list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
  183. $addition = array();
  184. // Prepare incoming display specifications.
  185. if (is_string($display)) {
  186. $view_mode = $display;
  187. $display = field_get_display($instance, $view_mode, $entity);
  188. }
  189. else {
  190. $view_mode = '_custom_display';
  191. }
  192. if ($display['type'] !== 'hidden') {
  193. // Calling the formatter function through module_invoke() can have a
  194. // performance impact on pages with many fields and values.
  195. $function = $display['module'] . '_field_formatter_view';
  196. if (function_exists($function)) {
  197. $elements = $function($entity_type, $entity, $field, $instance, $langcode, $items, $display);
  198. if ($elements) {
  199. $info = array(
  200. '#theme' => 'field',
  201. '#weight' => $display['weight'],
  202. '#title' => $instance['label'],
  203. '#access' => field_access('view', $field, $entity_type, $entity),
  204. '#label_display' => $display['label'],
  205. '#view_mode' => $view_mode,
  206. '#language' => $langcode,
  207. '#field_name' => $field['field_name'],
  208. '#field_type' => $field['type'],
  209. '#field_translatable' => $field['translatable'],
  210. '#entity_type' => $entity_type,
  211. '#bundle' => $bundle,
  212. '#object' => $entity,
  213. '#items' => $items,
  214. '#formatter' => $display['type']
  215. );
  216. $addition[$field['field_name']] = array_merge($info, $elements);
  217. }
  218. }
  219. }
  220. return $addition;
  221. }
  222. /**
  223. * Copies source field values into the entity to be prepared.
  224. *
  225. * @param $entity_type
  226. * The type of $entity; e.g. 'node' or 'user'.
  227. * @param $entity
  228. * The entity to be prepared for translation.
  229. * @param $field
  230. * The field structure for the operation.
  231. * @param $instance
  232. * The instance structure for $field on $entity's bundle.
  233. * @param $langcode
  234. * The language the entity has to be translated in.
  235. * @param $items
  236. * $entity->{$field['field_name']}[$langcode], or an empty array if unset.
  237. * @param $source_entity
  238. * The source entity holding the field values to be translated.
  239. * @param $source_langcode
  240. * The source language from which translate.
  241. */
  242. function field_default_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items, $source_entity, $source_langcode) {
  243. $field_name = $field['field_name'];
  244. // If the field is untranslatable keep using LANGUAGE_NONE.
  245. if ($langcode == LANGUAGE_NONE) {
  246. $source_langcode = LANGUAGE_NONE;
  247. }
  248. if (isset($source_entity->{$field_name}[$source_langcode])) {
  249. $items = $source_entity->{$field_name}[$source_langcode];
  250. }
  251. }