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