field.default.inc 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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. }