|
1 <?php |
|
2 |
|
3 /* |
|
4 * @file |
|
5 * Definition of the FieldInfo class. |
|
6 */ |
|
7 |
|
8 /** |
|
9 * Provides field and instance definitions for the current runtime environment. |
|
10 * |
|
11 * A FieldInfo object is created and statically persisted through the request |
|
12 * by the _field_info_field_cache() function. The object properties act as a |
|
13 * "static cache" of fields and instances definitions. |
|
14 * |
|
15 * The preferred way to access definitions is through the getBundleInstances() |
|
16 * method, which keeps cache entries per bundle, storing both fields and |
|
17 * instances for a given bundle. Fields used in multiple bundles are duplicated |
|
18 * in several cache entries, and are merged into a single list in the memory |
|
19 * cache. Cache entries are loaded for bundles as a whole, optimizing memory |
|
20 * and CPU usage for the most common pattern of iterating over all instances of |
|
21 * a bundle rather than accessing a single instance. |
|
22 * |
|
23 * The getFields() and getInstances() methods, which return all existing field |
|
24 * and instance definitions, are kept mainly for backwards compatibility, and |
|
25 * should be avoided when possible, since they load and persist in memory a |
|
26 * potentially large array of information. In many cases, the lightweight |
|
27 * getFieldMap() method should be preferred. |
|
28 */ |
|
29 class FieldInfo { |
|
30 |
|
31 /** |
|
32 * Lightweight map of fields across entity types and bundles. |
|
33 * |
|
34 * @var array |
|
35 */ |
|
36 protected $fieldMap; |
|
37 |
|
38 /** |
|
39 * List of $field structures keyed by ID. Includes deleted fields. |
|
40 * |
|
41 * @var array |
|
42 */ |
|
43 protected $fieldsById = array(); |
|
44 |
|
45 /** |
|
46 * Mapping of field names to the ID of the corresponding non-deleted field. |
|
47 * |
|
48 * @var array |
|
49 */ |
|
50 protected $fieldIdsByName = array(); |
|
51 |
|
52 /** |
|
53 * Whether $fieldsById contains all field definitions or a subset. |
|
54 * |
|
55 * @var bool |
|
56 */ |
|
57 protected $loadedAllFields = FALSE; |
|
58 |
|
59 /** |
|
60 * Separately tracks requested field names or IDs that do not exist. |
|
61 * |
|
62 * @var array |
|
63 */ |
|
64 protected $unknownFields = array(); |
|
65 |
|
66 /** |
|
67 * Instance definitions by bundle. |
|
68 * |
|
69 * @var array |
|
70 */ |
|
71 protected $bundleInstances = array(); |
|
72 |
|
73 /** |
|
74 * Whether $bundleInstances contains all instances definitions or a subset. |
|
75 * |
|
76 * @var bool |
|
77 */ |
|
78 protected $loadedAllInstances = FALSE; |
|
79 |
|
80 /** |
|
81 * Separately tracks requested bundles that are empty (or do not exist). |
|
82 * |
|
83 * @var array |
|
84 */ |
|
85 protected $emptyBundles = array(); |
|
86 |
|
87 /** |
|
88 * Extra fields by bundle. |
|
89 * |
|
90 * @var array |
|
91 */ |
|
92 protected $bundleExtraFields = array(); |
|
93 |
|
94 /** |
|
95 * Clears the "static" and persistent caches. |
|
96 */ |
|
97 public function flush() { |
|
98 $this->fieldMap = NULL; |
|
99 |
|
100 $this->fieldsById = array(); |
|
101 $this->fieldIdsByName = array(); |
|
102 $this->loadedAllFields = FALSE; |
|
103 $this->unknownFields = array(); |
|
104 |
|
105 $this->bundleInstances = array(); |
|
106 $this->loadedAllInstances = FALSE; |
|
107 $this->emptyBundles = array(); |
|
108 |
|
109 $this->bundleExtraFields = array(); |
|
110 |
|
111 cache_clear_all('field_info:', 'cache_field', TRUE); |
|
112 } |
|
113 |
|
114 /** |
|
115 * Collects a lightweight map of fields across bundles. |
|
116 * |
|
117 * @return |
|
118 * An array keyed by field name. Each value is an array with two entries: |
|
119 * - type: The field type. |
|
120 * - bundles: The bundles in which the field appears, as an array with |
|
121 * entity types as keys and the array of bundle names as values. |
|
122 */ |
|
123 public function getFieldMap() { |
|
124 // Read from the "static" cache. |
|
125 if ($this->fieldMap !== NULL) { |
|
126 return $this->fieldMap; |
|
127 } |
|
128 |
|
129 // Read from persistent cache. |
|
130 if ($cached = cache_get('field_info:field_map', 'cache_field')) { |
|
131 $map = $cached->data; |
|
132 |
|
133 // Save in "static" cache. |
|
134 $this->fieldMap = $map; |
|
135 |
|
136 return $map; |
|
137 } |
|
138 |
|
139 $map = array(); |
|
140 |
|
141 $query = db_query('SELECT fc.type, fci.field_name, fci.entity_type, fci.bundle FROM {field_config_instance} fci INNER JOIN {field_config} fc ON fc.id = fci.field_id WHERE fc.active = 1 AND fc.storage_active = 1 AND fc.deleted = 0 AND fci.deleted = 0'); |
|
142 foreach ($query as $row) { |
|
143 $map[$row->field_name]['bundles'][$row->entity_type][] = $row->bundle; |
|
144 $map[$row->field_name]['type'] = $row->type; |
|
145 } |
|
146 |
|
147 // Save in "static" and persistent caches. |
|
148 $this->fieldMap = $map; |
|
149 if (lock_acquire('field_info:field_map')) { |
|
150 cache_set('field_info:field_map', $map, 'cache_field'); |
|
151 lock_release('field_info:field_map'); |
|
152 } |
|
153 |
|
154 return $map; |
|
155 } |
|
156 |
|
157 /** |
|
158 * Returns all active fields, including deleted ones. |
|
159 * |
|
160 * @return |
|
161 * An array of field definitions, keyed by field ID. |
|
162 */ |
|
163 public function getFields() { |
|
164 // Read from the "static" cache. |
|
165 if ($this->loadedAllFields) { |
|
166 return $this->fieldsById; |
|
167 } |
|
168 |
|
169 // Read from persistent cache. |
|
170 if ($cached = cache_get('field_info:fields', 'cache_field')) { |
|
171 $this->fieldsById = $cached->data; |
|
172 } |
|
173 else { |
|
174 // Collect and prepare fields. |
|
175 foreach (field_read_fields(array(), array('include_deleted' => TRUE)) as $field) { |
|
176 $this->fieldsById[$field['id']] = $this->prepareField($field); |
|
177 } |
|
178 |
|
179 // Store in persistent cache. |
|
180 if (lock_acquire('field_info:fields')) { |
|
181 cache_set('field_info:fields', $this->fieldsById, 'cache_field'); |
|
182 lock_release('field_info:fields'); |
|
183 } |
|
184 } |
|
185 |
|
186 // Fill the name/ID map. |
|
187 foreach ($this->fieldsById as $field) { |
|
188 if (!$field['deleted']) { |
|
189 $this->fieldIdsByName[$field['field_name']] = $field['id']; |
|
190 } |
|
191 } |
|
192 |
|
193 $this->loadedAllFields = TRUE; |
|
194 |
|
195 return $this->fieldsById; |
|
196 } |
|
197 |
|
198 /** |
|
199 * Retrieves all active, non-deleted instances definitions. |
|
200 * |
|
201 * @param $entity_type |
|
202 * (optional) The entity type. |
|
203 * |
|
204 * @return |
|
205 * If $entity_type is not set, all instances keyed by entity type and bundle |
|
206 * name. If $entity_type is set, all instances for that entity type, keyed |
|
207 * by bundle name. |
|
208 */ |
|
209 public function getInstances($entity_type = NULL) { |
|
210 // If the full list is not present in "static" cache yet. |
|
211 if (!$this->loadedAllInstances) { |
|
212 |
|
213 // Read from persistent cache. |
|
214 if ($cached = cache_get('field_info:instances', 'cache_field')) { |
|
215 $this->bundleInstances = $cached->data; |
|
216 } |
|
217 else { |
|
218 // Collect and prepare instances. |
|
219 |
|
220 // We also need to populate the static field cache, since it will not |
|
221 // be set by subsequent getBundleInstances() calls. |
|
222 $this->getFields(); |
|
223 |
|
224 // Initialize empty arrays for all existing entity types and bundles. |
|
225 // This is not strictly needed, but is done to preserve the behavior of |
|
226 // field_info_instances() before http://drupal.org/node/1915646. |
|
227 foreach (field_info_bundles() as $existing_entity_type => $bundles) { |
|
228 foreach ($bundles as $bundle => $bundle_info) { |
|
229 $this->bundleInstances[$existing_entity_type][$bundle] = array(); |
|
230 } |
|
231 } |
|
232 |
|
233 foreach (field_read_instances() as $instance) { |
|
234 $field = $this->getField($instance['field_name']); |
|
235 $instance = $this->prepareInstance($instance, $field['type']); |
|
236 $this->bundleInstances[$instance['entity_type']][$instance['bundle']][$instance['field_name']] = $instance; |
|
237 } |
|
238 |
|
239 // Store in persistent cache. |
|
240 if (lock_acquire('field_info:instances')) { |
|
241 cache_set('field_info:instances', $this->bundleInstances, 'cache_field'); |
|
242 lock_release('field_info:instances'); |
|
243 } |
|
244 } |
|
245 |
|
246 $this->loadedAllInstances = TRUE; |
|
247 } |
|
248 |
|
249 if (isset($entity_type)) { |
|
250 return isset($this->bundleInstances[$entity_type]) ? $this->bundleInstances[$entity_type] : array(); |
|
251 } |
|
252 else { |
|
253 return $this->bundleInstances; |
|
254 } |
|
255 } |
|
256 |
|
257 /** |
|
258 * Returns a field definition from a field name. |
|
259 * |
|
260 * This method only retrieves active, non-deleted fields. |
|
261 * |
|
262 * @param $field_name |
|
263 * The field name. |
|
264 * |
|
265 * @return |
|
266 * The field definition, or NULL if no field was found. |
|
267 */ |
|
268 public function getField($field_name) { |
|
269 // Read from the "static" cache. |
|
270 if (isset($this->fieldIdsByName[$field_name])) { |
|
271 $field_id = $this->fieldIdsByName[$field_name]; |
|
272 return $this->fieldsById[$field_id]; |
|
273 } |
|
274 if (isset($this->unknownFields[$field_name])) { |
|
275 return; |
|
276 } |
|
277 |
|
278 // Do not check the (large) persistent cache, but read the definition. |
|
279 |
|
280 // Cache miss: read from definition. |
|
281 if ($field = field_read_field($field_name)) { |
|
282 $field = $this->prepareField($field); |
|
283 |
|
284 // Save in the "static" cache. |
|
285 $this->fieldsById[$field['id']] = $field; |
|
286 $this->fieldIdsByName[$field['field_name']] = $field['id']; |
|
287 |
|
288 return $field; |
|
289 } |
|
290 else { |
|
291 $this->unknownFields[$field_name] = TRUE; |
|
292 } |
|
293 } |
|
294 |
|
295 /** |
|
296 * Returns a field definition from a field ID. |
|
297 * |
|
298 * This method only retrieves active fields, deleted or not. |
|
299 * |
|
300 * @param $field_id |
|
301 * The field ID. |
|
302 * |
|
303 * @return |
|
304 * The field definition, or NULL if no field was found. |
|
305 */ |
|
306 public function getFieldById($field_id) { |
|
307 // Read from the "static" cache. |
|
308 if (isset($this->fieldsById[$field_id])) { |
|
309 return $this->fieldsById[$field_id]; |
|
310 } |
|
311 if (isset($this->unknownFields[$field_id])) { |
|
312 return; |
|
313 } |
|
314 |
|
315 // No persistent cache, fields are only persistently cached as part of a |
|
316 // bundle. |
|
317 |
|
318 // Cache miss: read from definition. |
|
319 if ($fields = field_read_fields(array('id' => $field_id), array('include_deleted' => TRUE))) { |
|
320 $field = current($fields); |
|
321 $field = $this->prepareField($field); |
|
322 |
|
323 // Store in the static cache. |
|
324 $this->fieldsById[$field['id']] = $field; |
|
325 if (!$field['deleted']) { |
|
326 $this->fieldIdsByName[$field['field_name']] = $field['id']; |
|
327 } |
|
328 |
|
329 return $field; |
|
330 } |
|
331 else { |
|
332 $this->unknownFields[$field_id] = TRUE; |
|
333 } |
|
334 } |
|
335 |
|
336 /** |
|
337 * Retrieves the instances for a bundle. |
|
338 * |
|
339 * The function also populates the corresponding field definitions in the |
|
340 * "static" cache. |
|
341 * |
|
342 * @param $entity_type |
|
343 * The entity type. |
|
344 * @param $bundle |
|
345 * The bundle name. |
|
346 * |
|
347 * @return |
|
348 * The array of instance definitions, keyed by field name. |
|
349 */ |
|
350 public function getBundleInstances($entity_type, $bundle) { |
|
351 // Read from the "static" cache. |
|
352 if (isset($this->bundleInstances[$entity_type][$bundle])) { |
|
353 return $this->bundleInstances[$entity_type][$bundle]; |
|
354 } |
|
355 if (isset($this->emptyBundles[$entity_type][$bundle])) { |
|
356 return array(); |
|
357 } |
|
358 |
|
359 // Read from the persistent cache. |
|
360 if ($cached = cache_get("field_info:bundle:$entity_type:$bundle", 'cache_field')) { |
|
361 $info = $cached->data; |
|
362 |
|
363 // Extract the field definitions and save them in the "static" cache. |
|
364 foreach ($info['fields'] as $field) { |
|
365 if (!isset($this->fieldsById[$field['id']])) { |
|
366 $this->fieldsById[$field['id']] = $field; |
|
367 if (!$field['deleted']) { |
|
368 $this->fieldIdsByName[$field['field_name']] = $field['id']; |
|
369 } |
|
370 } |
|
371 } |
|
372 unset($info['fields']); |
|
373 |
|
374 // Store the instance definitions in the "static" cache'. Empty (or |
|
375 // non-existent) bundles are stored separately, so that they do not |
|
376 // pollute the global list returned by getInstances(). |
|
377 if ($info['instances']) { |
|
378 $this->bundleInstances[$entity_type][$bundle] = $info['instances']; |
|
379 } |
|
380 else { |
|
381 $this->emptyBundles[$entity_type][$bundle] = TRUE; |
|
382 } |
|
383 |
|
384 return $info['instances']; |
|
385 } |
|
386 |
|
387 // Cache miss: collect from the definitions. |
|
388 |
|
389 $instances = array(); |
|
390 |
|
391 // Collect the fields in the bundle. |
|
392 $params = array('entity_type' => $entity_type, 'bundle' => $bundle); |
|
393 $fields = field_read_fields($params); |
|
394 |
|
395 // This iterates on non-deleted instances, so deleted fields are kept out of |
|
396 // the persistent caches. |
|
397 foreach (field_read_instances($params) as $instance) { |
|
398 $field = $fields[$instance['field_name']]; |
|
399 |
|
400 $instance = $this->prepareInstance($instance, $field['type']); |
|
401 $instances[$field['field_name']] = $instance; |
|
402 |
|
403 // If the field is not in our global "static" list yet, add it. |
|
404 if (!isset($this->fieldsById[$field['id']])) { |
|
405 $field = $this->prepareField($field); |
|
406 |
|
407 $this->fieldsById[$field['id']] = $field; |
|
408 $this->fieldIdsByName[$field['field_name']] = $field['id']; |
|
409 } |
|
410 } |
|
411 |
|
412 // Store in the 'static' cache'. Empty (or non-existent) bundles are stored |
|
413 // separately, so that they do not pollute the global list returned by |
|
414 // getInstances(). |
|
415 if ($instances) { |
|
416 $this->bundleInstances[$entity_type][$bundle] = $instances; |
|
417 } |
|
418 else { |
|
419 $this->emptyBundles[$entity_type][$bundle] = TRUE; |
|
420 } |
|
421 |
|
422 // The persistent cache additionally contains the definitions of the fields |
|
423 // involved in the bundle. |
|
424 $cache = array( |
|
425 'instances' => $instances, |
|
426 'fields' => array() |
|
427 ); |
|
428 foreach ($instances as $instance) { |
|
429 $cache['fields'][] = $this->fieldsById[$instance['field_id']]; |
|
430 } |
|
431 |
|
432 if (lock_acquire("field_info:bundle:$entity_type:$bundle")) { |
|
433 cache_set("field_info:bundle:$entity_type:$bundle", $cache, 'cache_field'); |
|
434 lock_release("field_info:bundle:$entity_type:$bundle"); |
|
435 } |
|
436 |
|
437 return $instances; |
|
438 } |
|
439 |
|
440 /** |
|
441 * Retrieves the "extra fields" for a bundle. |
|
442 * |
|
443 * @param $entity_type |
|
444 * The entity type. |
|
445 * @param $bundle |
|
446 * The bundle name. |
|
447 * |
|
448 * @return |
|
449 * The array of extra fields. |
|
450 */ |
|
451 public function getBundleExtraFields($entity_type, $bundle) { |
|
452 // Read from the "static" cache. |
|
453 if (isset($this->bundleExtraFields[$entity_type][$bundle])) { |
|
454 return $this->bundleExtraFields[$entity_type][$bundle]; |
|
455 } |
|
456 |
|
457 // Read from the persistent cache. |
|
458 if ($cached = cache_get("field_info:bundle_extra:$entity_type:$bundle", 'cache_field')) { |
|
459 $this->bundleExtraFields[$entity_type][$bundle] = $cached->data; |
|
460 return $this->bundleExtraFields[$entity_type][$bundle]; |
|
461 } |
|
462 |
|
463 // Cache miss: read from hook_field_extra_fields(). Note: given the current |
|
464 // shape of the hook, we have no other way than collecting extra fields on |
|
465 // all bundles. |
|
466 $info = array(); |
|
467 $extra = module_invoke_all('field_extra_fields'); |
|
468 drupal_alter('field_extra_fields', $extra); |
|
469 // Merge in saved settings. |
|
470 if (isset($extra[$entity_type][$bundle])) { |
|
471 $info = $this->prepareExtraFields($extra[$entity_type][$bundle], $entity_type, $bundle); |
|
472 } |
|
473 |
|
474 // Store in the 'static' and persistent caches. |
|
475 $this->bundleExtraFields[$entity_type][$bundle] = $info; |
|
476 if (lock_acquire("field_info:bundle_extra:$entity_type:$bundle")) { |
|
477 cache_set("field_info:bundle_extra:$entity_type:$bundle", $info, 'cache_field'); |
|
478 lock_release("field_info:bundle_extra:$entity_type:$bundle"); |
|
479 } |
|
480 |
|
481 return $this->bundleExtraFields[$entity_type][$bundle]; |
|
482 } |
|
483 |
|
484 /** |
|
485 * Prepares a field definition for the current run-time context. |
|
486 * |
|
487 * @param $field |
|
488 * The raw field structure as read from the database. |
|
489 * |
|
490 * @return |
|
491 * The field definition completed for the current runtime context. |
|
492 */ |
|
493 public function prepareField($field) { |
|
494 // Make sure all expected field settings are present. |
|
495 $field['settings'] += field_info_field_settings($field['type']); |
|
496 $field['storage']['settings'] += field_info_storage_settings($field['storage']['type']); |
|
497 |
|
498 // Add storage details. |
|
499 $details = (array) module_invoke($field['storage']['module'], 'field_storage_details', $field); |
|
500 drupal_alter('field_storage_details', $details, $field); |
|
501 $field['storage']['details'] = $details; |
|
502 |
|
503 // Populate the list of bundles using the field. |
|
504 $field['bundles'] = array(); |
|
505 if (!$field['deleted']) { |
|
506 $map = $this->getFieldMap(); |
|
507 if (isset($map[$field['field_name']])) { |
|
508 $field['bundles'] = $map[$field['field_name']]['bundles']; |
|
509 } |
|
510 } |
|
511 |
|
512 return $field; |
|
513 } |
|
514 |
|
515 /** |
|
516 * Prepares an instance definition for the current run-time context. |
|
517 * |
|
518 * @param $instance |
|
519 * The raw instance structure as read from the database. |
|
520 * @param $field_type |
|
521 * The field type. |
|
522 * |
|
523 * @return |
|
524 * The field instance array completed for the current runtime context. |
|
525 */ |
|
526 public function prepareInstance($instance, $field_type) { |
|
527 // Make sure all expected instance settings are present. |
|
528 $instance['settings'] += field_info_instance_settings($field_type); |
|
529 |
|
530 // Set a default value for the instance. |
|
531 if (field_behaviors_widget('default value', $instance) == FIELD_BEHAVIOR_DEFAULT && !isset($instance['default_value'])) { |
|
532 $instance['default_value'] = NULL; |
|
533 } |
|
534 |
|
535 // Prepare widget settings. |
|
536 $instance['widget'] = $this->prepareInstanceWidget($instance['widget'], $field_type); |
|
537 |
|
538 // Prepare display settings. |
|
539 foreach ($instance['display'] as $view_mode => $display) { |
|
540 $instance['display'][$view_mode] = $this->prepareInstanceDisplay($display, $field_type); |
|
541 } |
|
542 |
|
543 // Fall back to 'hidden' for view modes configured to use custom display |
|
544 // settings, and for which the instance has no explicit settings. |
|
545 $entity_info = entity_get_info($instance['entity_type']); |
|
546 $view_modes = array_merge(array('default'), array_keys($entity_info['view modes'])); |
|
547 $view_mode_settings = field_view_mode_settings($instance['entity_type'], $instance['bundle']); |
|
548 foreach ($view_modes as $view_mode) { |
|
549 if ($view_mode == 'default' || !empty($view_mode_settings[$view_mode]['custom_settings'])) { |
|
550 if (!isset($instance['display'][$view_mode])) { |
|
551 $instance['display'][$view_mode] = array( |
|
552 'type' => 'hidden', |
|
553 'label' => 'above', |
|
554 'settings' => array(), |
|
555 'weight' => 0, |
|
556 ); |
|
557 } |
|
558 } |
|
559 } |
|
560 |
|
561 return $instance; |
|
562 } |
|
563 |
|
564 /** |
|
565 * Prepares widget properties for the current run-time context. |
|
566 * |
|
567 * @param $widget |
|
568 * Widget specifications as found in $instance['widget']. |
|
569 * @param $field_type |
|
570 * The field type. |
|
571 * |
|
572 * @return |
|
573 * The widget properties completed for the current runtime context. |
|
574 */ |
|
575 public function prepareInstanceWidget($widget, $field_type) { |
|
576 $field_type_info = field_info_field_types($field_type); |
|
577 |
|
578 // Fill in default values. |
|
579 $widget += array( |
|
580 'type' => $field_type_info['default_widget'], |
|
581 'settings' => array(), |
|
582 'weight' => 0, |
|
583 ); |
|
584 |
|
585 $widget_type_info = field_info_widget_types($widget['type']); |
|
586 // Fall back to default formatter if formatter type is not available. |
|
587 if (!$widget_type_info) { |
|
588 $widget['type'] = $field_type_info['default_widget']; |
|
589 $widget_type_info = field_info_widget_types($widget['type']); |
|
590 } |
|
591 $widget['module'] = $widget_type_info['module']; |
|
592 // Fill in default settings for the widget. |
|
593 $widget['settings'] += field_info_widget_settings($widget['type']); |
|
594 |
|
595 return $widget; |
|
596 } |
|
597 |
|
598 /** |
|
599 * Adapts display specifications to the current run-time context. |
|
600 * |
|
601 * @param $display |
|
602 * Display specifications as found in $instance['display']['a_view_mode']. |
|
603 * @param $field_type |
|
604 * The field type. |
|
605 * |
|
606 * @return |
|
607 * The display properties completed for the current runtime context. |
|
608 */ |
|
609 public function prepareInstanceDisplay($display, $field_type) { |
|
610 $field_type_info = field_info_field_types($field_type); |
|
611 |
|
612 // Fill in default values. |
|
613 $display += array( |
|
614 'label' => 'above', |
|
615 'settings' => array(), |
|
616 'weight' => 0, |
|
617 ); |
|
618 if (empty($display['type'])) { |
|
619 $display['type'] = $field_type_info['default_formatter']; |
|
620 } |
|
621 if ($display['type'] != 'hidden') { |
|
622 $formatter_type_info = field_info_formatter_types($display['type']); |
|
623 // Fall back to default formatter if formatter type is not available. |
|
624 if (!$formatter_type_info) { |
|
625 $display['type'] = $field_type_info['default_formatter']; |
|
626 $formatter_type_info = field_info_formatter_types($display['type']); |
|
627 } |
|
628 $display['module'] = $formatter_type_info['module']; |
|
629 // Fill in default settings for the formatter. |
|
630 $display['settings'] += field_info_formatter_settings($display['type']); |
|
631 } |
|
632 |
|
633 return $display; |
|
634 } |
|
635 |
|
636 /** |
|
637 * Prepares 'extra fields' for the current run-time context. |
|
638 * |
|
639 * @param $extra_fields |
|
640 * The array of extra fields, as collected in hook_field_extra_fields(). |
|
641 * @param $entity_type |
|
642 * The entity type. |
|
643 * @param $bundle |
|
644 * The bundle name. |
|
645 * |
|
646 * @return |
|
647 * The list of extra fields completed for the current runtime context. |
|
648 */ |
|
649 public function prepareExtraFields($extra_fields, $entity_type, $bundle) { |
|
650 $entity_type_info = entity_get_info($entity_type); |
|
651 $bundle_settings = field_bundle_settings($entity_type, $bundle); |
|
652 $extra_fields += array('form' => array(), 'display' => array()); |
|
653 |
|
654 $result = array(); |
|
655 // Extra fields in forms. |
|
656 foreach ($extra_fields['form'] as $name => $field_data) { |
|
657 $settings = isset($bundle_settings['extra_fields']['form'][$name]) ? $bundle_settings['extra_fields']['form'][$name] : array(); |
|
658 if (isset($settings['weight'])) { |
|
659 $field_data['weight'] = $settings['weight']; |
|
660 } |
|
661 $result['form'][$name] = $field_data; |
|
662 } |
|
663 |
|
664 // Extra fields in displayed entities. |
|
665 $data = $extra_fields['display']; |
|
666 foreach ($extra_fields['display'] as $name => $field_data) { |
|
667 $settings = isset($bundle_settings['extra_fields']['display'][$name]) ? $bundle_settings['extra_fields']['display'][$name] : array(); |
|
668 $view_modes = array_merge(array('default'), array_keys($entity_type_info['view modes'])); |
|
669 foreach ($view_modes as $view_mode) { |
|
670 if (isset($settings[$view_mode])) { |
|
671 $field_data['display'][$view_mode] = $settings[$view_mode]; |
|
672 } |
|
673 else { |
|
674 $field_data['display'][$view_mode] = array( |
|
675 'weight' => $field_data['weight'], |
|
676 'visible' => TRUE, |
|
677 ); |
|
678 } |
|
679 } |
|
680 unset($field_data['weight']); |
|
681 $result['display'][$name] = $field_data; |
|
682 } |
|
683 |
|
684 return $result; |
|
685 } |
|
686 } |