1 |
85ad3d82
|
Assos Assos
|
<?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 |
|
|
} |