|
1 <?php |
|
2 |
|
3 /** |
|
4 * @file |
|
5 * Field forms management. |
|
6 */ |
|
7 |
|
8 /** |
|
9 * Creates a form element for a field and can populate it with a default value. |
|
10 * |
|
11 * If the form element is not associated with an entity (i.e., $entity is NULL) |
|
12 * field_get_default_value will be called to supply the default value for the |
|
13 * field. Also allows other modules to alter the form element by implementing |
|
14 * their own hooks. |
|
15 * |
|
16 * @param $entity_type |
|
17 * The type of entity (for example 'node' or 'user') that the field belongs |
|
18 * to. |
|
19 * @param $entity |
|
20 * The entity object that the field belongs to. This may be NULL if creating a |
|
21 * form element with a default value. |
|
22 * @param $field |
|
23 * An array representing the field whose editing element is being created. |
|
24 * @param $instance |
|
25 * An array representing the structure for $field in its current context. |
|
26 * @param $langcode |
|
27 * The language associated with the field. |
|
28 * @param $items |
|
29 * An array of the field values. When creating a new entity this may be NULL |
|
30 * or an empty array to use default values. |
|
31 * @param $form |
|
32 * An array representing the form that the editing element will be attached |
|
33 * to. |
|
34 * @param $form_state |
|
35 * An array containing the current state of the form. |
|
36 * @param $get_delta |
|
37 * Used to get only a specific delta value of a multiple value field. |
|
38 * |
|
39 * @return |
|
40 * The form element array created for this field. |
|
41 */ |
|
42 function field_default_form($entity_type, $entity, $field, $instance, $langcode, $items, &$form, &$form_state, $get_delta = NULL) { |
|
43 // This could be called with no entity, as when a UI module creates a |
|
44 // dummy form to set default values. |
|
45 if ($entity) { |
|
46 list($id, , ) = entity_extract_ids($entity_type, $entity); |
|
47 } |
|
48 |
|
49 $parents = $form['#parents']; |
|
50 |
|
51 $addition = array(); |
|
52 $field_name = $field['field_name']; |
|
53 $addition[$field_name] = array(); |
|
54 |
|
55 // Populate widgets with default values when creating a new entity. |
|
56 if (empty($items) && empty($id)) { |
|
57 $items = field_get_default_value($entity_type, $entity, $field, $instance, $langcode); |
|
58 } |
|
59 |
|
60 // Let modules alter the widget properties. |
|
61 $context = array( |
|
62 'entity_type' => $entity_type, |
|
63 'entity' => $entity, |
|
64 'field' => $field, |
|
65 'instance' => $instance, |
|
66 ); |
|
67 drupal_alter(array('field_widget_properties', 'field_widget_properties_' . $entity_type), $instance['widget'], $context); |
|
68 |
|
69 // Collect widget elements. |
|
70 $elements = array(); |
|
71 |
|
72 // Store field information in $form_state. |
|
73 if (!field_form_get_state($parents, $field_name, $langcode, $form_state)) { |
|
74 $field_state = array( |
|
75 'field' => $field, |
|
76 'instance' => $instance, |
|
77 'items_count' => count($items), |
|
78 'array_parents' => array(), |
|
79 'errors' => array(), |
|
80 ); |
|
81 field_form_set_state($parents, $field_name, $langcode, $form_state, $field_state); |
|
82 } |
|
83 |
|
84 // If field module handles multiple values for this form element, and we are |
|
85 // displaying an individual element, process the multiple value form. |
|
86 if (!isset($get_delta) && field_behaviors_widget('multiple values', $instance) == FIELD_BEHAVIOR_DEFAULT) { |
|
87 // Store the entity in the form. |
|
88 $form['#entity'] = $entity; |
|
89 $elements = field_multiple_value_form($field, $instance, $langcode, $items, $form, $form_state); |
|
90 } |
|
91 // If the widget is handling multiple values (e.g Options), or if we are |
|
92 // displaying an individual element, just get a single form element and make |
|
93 // it the $delta value. |
|
94 else { |
|
95 $delta = isset($get_delta) ? $get_delta : 0; |
|
96 $function = $instance['widget']['module'] . '_field_widget_form'; |
|
97 if (function_exists($function)) { |
|
98 $element = array( |
|
99 '#entity' => $entity, |
|
100 '#entity_type' => $instance['entity_type'], |
|
101 '#bundle' => $instance['bundle'], |
|
102 '#field_name' => $field_name, |
|
103 '#language' => $langcode, |
|
104 '#field_parents' => $parents, |
|
105 '#columns' => array_keys($field['columns']), |
|
106 '#title' => check_plain($instance['label']), |
|
107 '#description' => field_filter_xss($instance['description']), |
|
108 // Only the first widget should be required. |
|
109 '#required' => $delta == 0 && $instance['required'], |
|
110 '#delta' => $delta, |
|
111 ); |
|
112 if ($element = $function($form, $form_state, $field, $instance, $langcode, $items, $delta, $element)) { |
|
113 // Allow modules to alter the field widget form element. |
|
114 $context = array( |
|
115 'form' => $form, |
|
116 'field' => $field, |
|
117 'instance' => $instance, |
|
118 'langcode' => $langcode, |
|
119 'items' => $items, |
|
120 'delta' => $delta, |
|
121 ); |
|
122 drupal_alter(array('field_widget_form', 'field_widget_' . $instance['widget']['type'] . '_form'), $element, $form_state, $context); |
|
123 |
|
124 // If we're processing a specific delta value for a field where the |
|
125 // field module handles multiples, set the delta in the result. |
|
126 // For fields that handle their own processing, we can't make |
|
127 // assumptions about how the field is structured, just merge in the |
|
128 // returned element. |
|
129 if (field_behaviors_widget('multiple values', $instance) == FIELD_BEHAVIOR_DEFAULT) { |
|
130 $elements[$delta] = $element; |
|
131 } |
|
132 else { |
|
133 $elements = $element; |
|
134 } |
|
135 } |
|
136 } |
|
137 } |
|
138 |
|
139 // Also aid in theming of field widgets by rendering a classified container. |
|
140 $addition[$field_name] = array( |
|
141 '#type' => 'container', |
|
142 '#attributes' => array( |
|
143 'class' => array( |
|
144 'field-type-' . drupal_html_class($field['type']), |
|
145 'field-name-' . drupal_html_class($field_name), |
|
146 'field-widget-' . drupal_html_class($instance['widget']['type']), |
|
147 ), |
|
148 ), |
|
149 '#weight' => $instance['widget']['weight'], |
|
150 ); |
|
151 |
|
152 // Populate the 'array_parents' information in $form_state['field'] after |
|
153 // the form is built, so that we catch changes in the form structure performed |
|
154 // in alter() hooks. |
|
155 $elements['#after_build'][] = 'field_form_element_after_build'; |
|
156 $elements['#field_name'] = $field_name; |
|
157 $elements['#language'] = $langcode; |
|
158 $elements['#field_parents'] = $parents; |
|
159 |
|
160 $addition[$field_name] += array( |
|
161 '#tree' => TRUE, |
|
162 // The '#language' key can be used to access the field's form element |
|
163 // when $langcode is unknown. |
|
164 '#language' => $langcode, |
|
165 $langcode => $elements, |
|
166 '#access' => field_access('edit', $field, $entity_type, $entity), |
|
167 ); |
|
168 |
|
169 return $addition; |
|
170 } |
|
171 |
|
172 /** |
|
173 * Special handling to create form elements for multiple values. |
|
174 * |
|
175 * Handles generic features for multiple fields: |
|
176 * - number of widgets |
|
177 * - AHAH-'add more' button |
|
178 * - drag-n-drop value reordering |
|
179 */ |
|
180 function field_multiple_value_form($field, $instance, $langcode, $items, &$form, &$form_state) { |
|
181 $field_name = $field['field_name']; |
|
182 $parents = $form['#parents']; |
|
183 |
|
184 // Determine the number of widgets to display. |
|
185 switch ($field['cardinality']) { |
|
186 case FIELD_CARDINALITY_UNLIMITED: |
|
187 $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state); |
|
188 $max = $field_state['items_count']; |
|
189 break; |
|
190 |
|
191 default: |
|
192 $max = $field['cardinality'] - 1; |
|
193 break; |
|
194 } |
|
195 |
|
196 $title = check_plain($instance['label']); |
|
197 $description = field_filter_xss($instance['description']); |
|
198 |
|
199 $id_prefix = implode('-', array_merge($parents, array($field_name))); |
|
200 $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper'); |
|
201 |
|
202 $field_elements = array(); |
|
203 |
|
204 $function = $instance['widget']['module'] . '_field_widget_form'; |
|
205 if (function_exists($function)) { |
|
206 for ($delta = 0; $delta <= $max; $delta++) { |
|
207 $multiple = $field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED; |
|
208 $element = array( |
|
209 '#entity_type' => $instance['entity_type'], |
|
210 '#entity' => $form['#entity'], |
|
211 '#bundle' => $instance['bundle'], |
|
212 '#field_name' => $field_name, |
|
213 '#language' => $langcode, |
|
214 '#field_parents' => $parents, |
|
215 '#columns' => array_keys($field['columns']), |
|
216 // For multiple fields, title and description are handled by the wrapping table. |
|
217 '#title' => $multiple ? '' : $title, |
|
218 '#description' => $multiple ? '' : $description, |
|
219 // Only the first widget should be required. |
|
220 '#required' => $delta == 0 && $instance['required'], |
|
221 '#delta' => $delta, |
|
222 '#weight' => $delta, |
|
223 ); |
|
224 if ($element = $function($form, $form_state, $field, $instance, $langcode, $items, $delta, $element)) { |
|
225 // Input field for the delta (drag-n-drop reordering). |
|
226 if ($multiple) { |
|
227 // We name the element '_weight' to avoid clashing with elements |
|
228 // defined by widget. |
|
229 $element['_weight'] = array( |
|
230 '#type' => 'weight', |
|
231 '#title' => t('Weight for row @number', array('@number' => $delta + 1)), |
|
232 '#title_display' => 'invisible', |
|
233 // Note: this 'delta' is the FAPI 'weight' element's property. |
|
234 '#delta' => $max, |
|
235 '#default_value' => isset($items[$delta]['_weight']) ? $items[$delta]['_weight'] : $delta, |
|
236 '#weight' => 100, |
|
237 ); |
|
238 } |
|
239 |
|
240 // Allow modules to alter the field widget form element. |
|
241 $context = array( |
|
242 'form' => $form, |
|
243 'field' => $field, |
|
244 'instance' => $instance, |
|
245 'langcode' => $langcode, |
|
246 'items' => $items, |
|
247 'delta' => $delta, |
|
248 ); |
|
249 drupal_alter(array('field_widget_form', 'field_widget_' . $instance['widget']['type'] . '_form'), $element, $form_state, $context); |
|
250 |
|
251 $field_elements[$delta] = $element; |
|
252 } |
|
253 } |
|
254 |
|
255 if ($field_elements) { |
|
256 $field_elements += array( |
|
257 '#theme' => 'field_multiple_value_form', |
|
258 '#field_name' => $field['field_name'], |
|
259 '#cardinality' => $field['cardinality'], |
|
260 '#title' => $title, |
|
261 '#required' => $instance['required'], |
|
262 '#description' => $description, |
|
263 '#prefix' => '<div id="' . $wrapper_id . '">', |
|
264 '#suffix' => '</div>', |
|
265 '#max_delta' => $max, |
|
266 ); |
|
267 // Add 'add more' button, if not working with a programmed form. |
|
268 if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED && empty($form_state['programmed'])) { |
|
269 $field_elements['add_more'] = array( |
|
270 '#type' => 'submit', |
|
271 '#name' => strtr($id_prefix, '-', '_') . '_add_more', |
|
272 '#value' => t('Add another item'), |
|
273 '#attributes' => array('class' => array('field-add-more-submit')), |
|
274 '#limit_validation_errors' => array(array_merge($parents, array($field_name, $langcode))), |
|
275 '#submit' => array('field_add_more_submit'), |
|
276 '#ajax' => array( |
|
277 'callback' => 'field_add_more_js', |
|
278 'wrapper' => $wrapper_id, |
|
279 'effect' => 'fade', |
|
280 ), |
|
281 ); |
|
282 } |
|
283 } |
|
284 } |
|
285 |
|
286 return $field_elements; |
|
287 } |
|
288 |
|
289 /** |
|
290 * Returns HTML for an individual form element. |
|
291 * |
|
292 * Combine multiple values into a table with drag-n-drop reordering. |
|
293 * TODO : convert to a template. |
|
294 * |
|
295 * @param $variables |
|
296 * An associative array containing: |
|
297 * - element: A render element representing the form element. |
|
298 * |
|
299 * @ingroup themeable |
|
300 */ |
|
301 function theme_field_multiple_value_form($variables) { |
|
302 $element = $variables['element']; |
|
303 $output = ''; |
|
304 |
|
305 if ($element['#cardinality'] > 1 || $element['#cardinality'] == FIELD_CARDINALITY_UNLIMITED) { |
|
306 $table_id = drupal_html_id($element['#field_name'] . '_values'); |
|
307 $order_class = $element['#field_name'] . '-delta-order'; |
|
308 $required = !empty($element['#required']) ? theme('form_required_marker', $variables) : ''; |
|
309 |
|
310 $header = array( |
|
311 array( |
|
312 'data' => '<label>' . t('!title !required', array('!title' => $element['#title'], '!required' => $required)) . "</label>", |
|
313 'colspan' => 2, |
|
314 'class' => array('field-label'), |
|
315 ), |
|
316 t('Order'), |
|
317 ); |
|
318 $rows = array(); |
|
319 |
|
320 // Sort items according to '_weight' (needed when the form comes back after |
|
321 // preview or failed validation) |
|
322 $items = array(); |
|
323 foreach (element_children($element) as $key) { |
|
324 if ($key === 'add_more') { |
|
325 $add_more_button = &$element[$key]; |
|
326 } |
|
327 else { |
|
328 $items[] = &$element[$key]; |
|
329 } |
|
330 } |
|
331 usort($items, '_field_sort_items_value_helper'); |
|
332 |
|
333 // Add the items as table rows. |
|
334 foreach ($items as $key => $item) { |
|
335 $item['_weight']['#attributes']['class'] = array($order_class); |
|
336 $delta_element = drupal_render($item['_weight']); |
|
337 $cells = array( |
|
338 array('data' => '', 'class' => array('field-multiple-drag')), |
|
339 drupal_render($item), |
|
340 array('data' => $delta_element, 'class' => array('delta-order')), |
|
341 ); |
|
342 $rows[] = array( |
|
343 'data' => $cells, |
|
344 'class' => array('draggable'), |
|
345 ); |
|
346 } |
|
347 |
|
348 $output = '<div class="form-item">'; |
|
349 $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => $table_id, 'class' => array('field-multiple-table')))); |
|
350 $output .= $element['#description'] ? '<div class="description">' . $element['#description'] . '</div>' : ''; |
|
351 $output .= '<div class="clearfix">' . drupal_render($add_more_button) . '</div>'; |
|
352 $output .= '</div>'; |
|
353 |
|
354 drupal_add_tabledrag($table_id, 'order', 'sibling', $order_class); |
|
355 } |
|
356 else { |
|
357 foreach (element_children($element) as $key) { |
|
358 $output .= drupal_render($element[$key]); |
|
359 } |
|
360 } |
|
361 |
|
362 return $output; |
|
363 } |
|
364 |
|
365 /** |
|
366 * #after_build callback for field elements in a form. |
|
367 * |
|
368 * This stores the final location of the field within the form structure so |
|
369 * that field_default_form_errors() can assign validation errors to the right |
|
370 * form element. |
|
371 * |
|
372 * @see field_default_form_errors() |
|
373 */ |
|
374 function field_form_element_after_build($element, &$form_state) { |
|
375 $parents = $element['#field_parents']; |
|
376 $field_name = $element['#field_name']; |
|
377 $langcode = $element['#language']; |
|
378 |
|
379 $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state); |
|
380 $field_state['array_parents'] = $element['#array_parents']; |
|
381 field_form_set_state($parents, $field_name, $langcode, $form_state, $field_state); |
|
382 |
|
383 return $element; |
|
384 } |
|
385 |
|
386 /** |
|
387 * Transfer field-level validation errors to widgets. |
|
388 */ |
|
389 function field_default_form_errors($entity_type, $entity, $field, $instance, $langcode, $items, $form, &$form_state) { |
|
390 $field_state = field_form_get_state($form['#parents'], $field['field_name'], $langcode, $form_state); |
|
391 |
|
392 if (!empty($field_state['errors'])) { |
|
393 // Locate the correct element in the form. |
|
394 $element = drupal_array_get_nested_value($form_state['complete form'], $field_state['array_parents']); |
|
395 // Only set errors if the element is accessible. |
|
396 if (!isset($element['#access']) || $element['#access']) { |
|
397 $function = $instance['widget']['module'] . '_field_widget_error'; |
|
398 $function_exists = function_exists($function); |
|
399 |
|
400 $multiple_widget = field_behaviors_widget('multiple values', $instance) != FIELD_BEHAVIOR_DEFAULT; |
|
401 foreach ($field_state['errors'] as $delta => $delta_errors) { |
|
402 // For multiple single-value widgets, pass errors by delta. |
|
403 // For a multiple-value widget, pass all errors to the main widget. |
|
404 $error_element = $multiple_widget ? $element : $element[$delta]; |
|
405 foreach ($delta_errors as $error) { |
|
406 if ($function_exists) { |
|
407 $function($error_element, $error, $form, $form_state); |
|
408 } |
|
409 else { |
|
410 // Make sure that errors are reported (even incorrectly flagged) if |
|
411 // the widget module fails to implement hook_field_widget_error(). |
|
412 form_error($error_element, $error['message']); |
|
413 } |
|
414 } |
|
415 } |
|
416 // Reinitialize the errors list for the next submit. |
|
417 $field_state['errors'] = array(); |
|
418 field_form_set_state($form['#parents'], $field['field_name'], $langcode, $form_state, $field_state); |
|
419 } |
|
420 } |
|
421 } |
|
422 |
|
423 /** |
|
424 * Submit handler for the "Add another item" button of a field form. |
|
425 * |
|
426 * This handler is run regardless of whether JS is enabled or not. It makes |
|
427 * changes to the form state. If the button was clicked with JS disabled, then |
|
428 * the page is reloaded with the complete rebuilt form. If the button was |
|
429 * clicked with JS enabled, then ajax_form_callback() calls field_add_more_js() |
|
430 * to return just the changed part of the form. |
|
431 */ |
|
432 function field_add_more_submit($form, &$form_state) { |
|
433 $button = $form_state['triggering_element']; |
|
434 |
|
435 // Go one level up in the form, to the widgets container. |
|
436 $element = drupal_array_get_nested_value($form, array_slice($button['#array_parents'], 0, -1)); |
|
437 $field_name = $element['#field_name']; |
|
438 $langcode = $element['#language']; |
|
439 $parents = $element['#field_parents']; |
|
440 |
|
441 // Increment the items count. |
|
442 $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state); |
|
443 $field_state['items_count']++; |
|
444 field_form_set_state($parents, $field_name, $langcode, $form_state, $field_state); |
|
445 |
|
446 $form_state['rebuild'] = TRUE; |
|
447 } |
|
448 |
|
449 /** |
|
450 * Ajax callback in response to a new empty widget being added to the form. |
|
451 * |
|
452 * This returns the new page content to replace the page content made obsolete |
|
453 * by the form submission. |
|
454 * |
|
455 * @see field_add_more_submit() |
|
456 */ |
|
457 function field_add_more_js($form, $form_state) { |
|
458 $button = $form_state['triggering_element']; |
|
459 |
|
460 // Go one level up in the form, to the widgets container. |
|
461 $element = drupal_array_get_nested_value($form, array_slice($button['#array_parents'], 0, -1)); |
|
462 $field_name = $element['#field_name']; |
|
463 $langcode = $element['#language']; |
|
464 $parents = $element['#field_parents']; |
|
465 |
|
466 $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state); |
|
467 |
|
468 $field = $field_state['field']; |
|
469 if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED) { |
|
470 return; |
|
471 } |
|
472 |
|
473 // Add a DIV around the delta receiving the Ajax effect. |
|
474 $delta = $element['#max_delta']; |
|
475 $element[$delta]['#prefix'] = '<div class="ajax-new-content">' . (isset($element[$delta]['#prefix']) ? $element[$delta]['#prefix'] : ''); |
|
476 $element[$delta]['#suffix'] = (isset($element[$delta]['#suffix']) ? $element[$delta]['#suffix'] : '') . '</div>'; |
|
477 |
|
478 return $element; |
|
479 } |
|
480 |
|
481 /** |
|
482 * Retrieves processing information about a field from $form_state. |
|
483 * |
|
484 * @param $parents |
|
485 * The array of #parents where the field lives in the form. |
|
486 * @param $field_name |
|
487 * The field name. |
|
488 * @param $langcode |
|
489 * The language in which the field values are entered. |
|
490 * @param $form_state |
|
491 * The form state. |
|
492 * |
|
493 * @return |
|
494 * An array with the following key/data pairs: |
|
495 * - field: the field definition array, |
|
496 * - instance: the field instance definition array, |
|
497 * - items_count: the number of widgets to display for the field, |
|
498 * - array_parents: the location of the field's widgets within the $form |
|
499 * structure. This entry is populated at '#after_build' time. |
|
500 * - errors: the array of field validation errors reported on the field. This |
|
501 * entry is populated at field_attach_form_validate() time. |
|
502 * |
|
503 * @see field_form_set_state() |
|
504 */ |
|
505 function field_form_get_state($parents, $field_name, $langcode, &$form_state) { |
|
506 $form_state_parents = _field_form_state_parents($parents, $field_name, $langcode); |
|
507 return drupal_array_get_nested_value($form_state, $form_state_parents); |
|
508 } |
|
509 |
|
510 /** |
|
511 * Stores processing information about a field in $form_state. |
|
512 * |
|
513 * @param $parents |
|
514 * The array of #parents where the field lives in the form. |
|
515 * @param $field_name |
|
516 * The field name. |
|
517 * @param $langcode |
|
518 * The language in which the field values are entered. |
|
519 * @param $form_state |
|
520 * The form state. |
|
521 * @param $field_state |
|
522 * The array of data to store. See field_form_get_state() for the structure |
|
523 * and content of the array. |
|
524 * |
|
525 * @see field_form_get_state() |
|
526 */ |
|
527 function field_form_set_state($parents, $field_name, $langcode, &$form_state, $field_state) { |
|
528 $form_state_parents = _field_form_state_parents($parents, $field_name, $langcode); |
|
529 drupal_array_set_nested_value($form_state, $form_state_parents, $field_state); |
|
530 } |
|
531 |
|
532 /** |
|
533 * Returns the location of processing information within $form_state. |
|
534 */ |
|
535 function _field_form_state_parents($parents, $field_name, $langcode) { |
|
536 // To ensure backwards compatibility on regular entity forms for widgets that |
|
537 // still access $form_state['field'][$field_name] directly, |
|
538 // - top-level fields (empty $parents) are placed directly under |
|
539 // $form_state['fields'][$field_name]. |
|
540 // - Other fields are placed under |
|
541 // $form_state['field']['#parents'][...$parents...]['#fields'][$field_name] |
|
542 // to avoid clashes between field names and $parents parts. |
|
543 // @todo Remove backwards compatibility in Drupal 8, and use a unique |
|
544 // $form_state['field'][...$parents...]['#fields'][$field_name] structure. |
|
545 if (!empty($parents)) { |
|
546 $form_state_parents = array_merge(array('#parents'), $parents, array('#fields')); |
|
547 } |
|
548 else { |
|
549 $form_state_parents = array(); |
|
550 } |
|
551 $form_state_parents = array_merge(array('field'), $form_state_parents, array($field_name, $langcode)); |
|
552 |
|
553 return $form_state_parents; |
|
554 } |
|
555 |
|
556 /** |
|
557 * Retrieves the field definition for a widget's helper callbacks. |
|
558 * |
|
559 * Widgets helper element callbacks (such as #process, #element_validate, |
|
560 * #value_callback, ...) should use field_widget_field() and |
|
561 * field_widget_instance() instead of field_info_field() and |
|
562 * field_info_instance() when they need to access field or instance properties. |
|
563 * See hook_field_widget_form() for more details. |
|
564 * |
|
565 * @param $element |
|
566 * The structured array for the widget. |
|
567 * @param $form_state |
|
568 * The form state. |
|
569 * |
|
570 * @return |
|
571 * The $field definition array for the current widget. |
|
572 * |
|
573 * @see field_widget_instance() |
|
574 * @see hook_field_widget_form() |
|
575 */ |
|
576 function field_widget_field($element, $form_state) { |
|
577 $field_state = field_form_get_state($element['#field_parents'], $element['#field_name'], $element['#language'], $form_state); |
|
578 return $field_state['field']; |
|
579 } |
|
580 |
|
581 /** |
|
582 * Retrieves the instance definition array for a widget's helper callbacks. |
|
583 * |
|
584 * Widgets helper element callbacks (such as #process, #element_validate, |
|
585 * #value_callback, ...) should use field_widget_field() and |
|
586 * field_widget_instance() instead of field_info_field() and |
|
587 * field_info_instance() when they need to access field or instance properties. |
|
588 * See hook_field_widget_form() for more details. |
|
589 * |
|
590 * @param $element |
|
591 * The structured array for the widget. |
|
592 * @param $form_state |
|
593 * The form state. |
|
594 * |
|
595 * @return |
|
596 * The $instance definition array for the current widget. |
|
597 * |
|
598 * @see field_widget_field() |
|
599 * @see hook_field_widget_form() |
|
600 */ |
|
601 function field_widget_instance($element, $form_state) { |
|
602 $field_state = field_form_get_state($element['#field_parents'], $element['#field_name'], $element['#language'], $form_state); |
|
603 return $field_state['instance']; |
|
604 } |