Simpletest Coverage - modules/field/field.info.inc

1 <?php
2 // $Id: field.info.inc,v 1.12 2009/08/11 14:59:40 dries Exp $
3
4 /**
5 * @file
6 * Field Info API, providing information about available fields and field types.
7 */
8
9 /**
10 * @defgroup field_info Field Info API
11 * @{
12 * Obtain information about Field API configuration.
13 *
14 * The Field Info API exposes information about field types, fields,
15 * instances, bundles, widget types, display formatters, behaviors,
16 * and settings defined by or with the Field API.
17 */
18
19 /**
20 * Clear the field info cache without clearing the field data cache.
21 *
22 * This is useful when deleted fields or instances are purged. We
23 * need to remove the purged records, but no actual field data items
24 * are affected.
25 */
26 function _field_info_cache_clear() {
27 _field_info_collate_types(TRUE);
28 _field_info_collate_fields(TRUE);
29 }
30
31 /**
32 * Collate all information on field types, widget types and related structures.
33 *
34 * @param $reset
35 * If TRUE, clear the cache. The information will be rebuilt from the database
36 * next time it is needed. Defaults to FALSE.
37 * @return
38 * If $reset is TRUE, nothing.
39 * If $reset is FALSE, an array containing the following elements:
40 *
41 * field types: array of hook_field_info() results, keyed by field_type.
42 * * label, description, settings, instance_settings, default_widget,
43 * default_formatter, behaviors: from hook_field_info()
44 * * module: the module that exposes the field type
45 *
46 * widget types: array of hook_field_widget_info() results, keyed by
47 * widget_type.
48 * * label, field types, settings, behaviors: from hook_field_widget_info()
49 * * module: module that exposes the widget type
50 *
51 * formatter types: array of hook_field_formatter_info() results, keyed by
52 * formatter_type.
53 * * label, field types, behaviors: from hook_field_formatter_info()
54 * * module: module that exposes the formatter type
55
56 * fieldable types: array of hook_fieldable_info() results, keyed by entity_type.
57 * * name, id key, revision key, bundle key, cacheable, bundles: from
58 * hook_fieldable_info()
59 * * module: module that exposes the entity type
60 */
61 function _field_info_collate_types($reset = FALSE) {
62 static $info;
63
64 if ($reset) {
65 $info = NULL;
66 cache_clear_all('field_info_types', 'cache_field');
67 return;
68 }
69
70 if (!isset($info)) {
71 if ($cached = cache_get('field_info_types', 'cache_field')) {
72 $info = $cached->data;
73 }
74 else {
75 $info = array(
76 'field types' => array(),
77 'widget types' => array(),
78 'formatter types' => array(),
79 'fieldable types' => array(),
80 );
81
82 // Populate field types.
83 foreach (module_implements('field_info') as $module) {
84 $field_types = (array) module_invoke($module, 'field_info');
85 foreach ($field_types as $name => $field_info) {
86 // Provide defaults.
87 $field_info += array(
88 'settings' => array(),
89 'instance_settings' => array(),
90 );
91 $info['field types'][$name] = $field_info;
92 $info['field types'][$name]['module'] = $module;
93 }
94 }
95 drupal_alter('field_info', $info['field types']);
96
97 // Populate widget types.
98 foreach (module_implements('field_widget_info') as $module) {
99 $widget_types = (array) module_invoke($module, 'field_widget_info');
100 foreach ($widget_types as $name => $widget_info) {
101 // Provide defaults.
102 $widget_info += array(
103 'settings' => array(),
104 );
105 $info['widget types'][$name] = $widget_info;
106 $info['widget types'][$name]['module'] = $module;
107 }
108 }
109 drupal_alter('field_widget_info', $info['widget types']);
110
111 // Populate formatters.
112 foreach (module_implements('field_formatter_info') as $module) {
113 $formatter_types = (array) module_invoke($module, 'field_formatter_info');
114 foreach ($formatter_types as $name => $formatter_info) {
115 // Provide defaults.
116 $formatter_info += array(
117 'settings' => array(),
118 );
119 $info['formatter types'][$name] = $formatter_info;
120 $info['formatter types'][$name]['module'] = $module;
121 }
122 }
123 drupal_alter('field_formatter_info', $info['formatter types']);
124
125 // Populate information about 'fieldable' entities.
126 foreach (module_implements('fieldable_info') as $module) {
127 $fieldable_types = (array) module_invoke($module, 'fieldable_info');
128 foreach ($fieldable_types as $name => $fieldable_info) {
129 // Provide defaults.
130 $fieldable_info += array(
131 'cacheable' => TRUE,
132 'bundles' => array(),
133 );
134 $fieldable_info['object keys'] += array(
135 'revision' => '',
136 'bundle' => '',
137 );
138 // If no bundle key provided, then we assume a single bundle, named
139 // after the type of the object. Make sure the bundle created
140 // has the human-readable name we need for bundle messages.
141 if (empty($fieldable_info['object keys']['bundle']) && empty($fieldable_info['bundles'])) {
142 $fieldable_info['bundles'] = array($name => array('label' => $fieldable_info['label']));
143 }
144 $info['fieldable types'][$name] = $fieldable_info;
145 $info['fieldable types'][$name]['module'] = $module;
146 }
147 }
148 drupal_alter('fieldable_info', $info['fieldable types']);
149
150 cache_set('field_info_types', $info, 'cache_field');
151 }
152 }
153
154 return $info;
155 }
156
157 /**
158 * Collate all information on existing fields and instances.
159 *
160 * @param $reset
161 * If TRUE, clear the cache. The information will be rebuilt from the
162 * database next time it is needed. Defaults to FALSE.
163 * @return
164 * If $reset is TRUE, nothing.
165 * If $reset is FALSE, an array containing the following elements:
166 * - fields: Array of existing fields, keyed by field name. This entry only
167 * lists non-deleted fields. Each field has an additional element,
168 * 'bundles', which is an array of all non-deleted instances to which the
169 * field is assigned.
170 * - fields_id: Array of existing fields, keyed by field id. This entry lists
171 * both deleted and non-deleted fields. The bundles element is the same as
172 * for 'fields'.
173 * - instances: Array of existing instances, keyed by bundle name and field
174 * name. This entry only lists non-deleted instances.
175 */
176 function _field_info_collate_fields($reset = FALSE) {
177 static $info;
178
179 if ($reset) {
180 $info = NULL;
181 cache_clear_all('field_info_fields', 'cache_field');
182 return;
183 }
184
185 if (!isset($info)) {
186 if ($cached = cache_get('field_info_fields', 'cache_field')) {
187 $definitions = $cached->data;
188 }
189 else {
190 $definitions = array(
191 'field_ids' => field_read_fields(array(), array('include_deleted' => 1)),
192 'instances' => field_read_instances(),
193 );
194 cache_set('field_info_fields', $definitions, 'cache_field');
195 }
196
197 // Populate 'field_ids' with all fields.
198 $info['field_ids'] = array();
199 foreach ($definitions['field_ids'] as $key => $field) {
200 $info['field_ids'][$key] = $definitions['field_ids'][$key] = _field_info_prepare_field($field);
201 }
202
203 // Populate 'fields' only with non-deleted fields.
204 $info['field'] = array();
205 foreach ($info['field_ids'] as $field) {
206 if (!$field['deleted']) {
207 $info['fields'][$field['field_name']] = $field;
208 }
209 }
210
211 // Populate 'instances'. Only non-deleted instances are considered.
212 $info['instances'] = array();
213 foreach (field_info_bundles() as $bundle => $bundle_info) {
214 $info['instances'][$bundle] = array();
215 }
216 foreach ($definitions['instances'] as $instance) {
217 $field = $info['fields'][$instance['field_name']];
218 $instance = _field_info_prepare_instance($instance, $field);
219 $info['instances'][$instance['bundle']][$instance['field_name']] = $instance;
220 // Enrich field definitions with the list of bundles where they have
221 // instances. NOTE: Deleted fields in $info['field_ids'] are not
222 // enriched because all of their instances are deleted, too, and
223 // are thus not in $definitions['instances'].
224 $info['fields'][$instance['field_name']]['bundles'][] = $instance['bundle'];
225 $info['field_ids'][$instance['field_id']]['bundles'][] = $instance['bundle'];
226 }
227 }
228
229 return $info;
230 }
231
232 /**
233 * Prepare a field definition for the current run-time context.
234 *
235 * Since the field was last saved or updated, new field settings can be
236 * expected.
237 *
238 * @param $field
239 * The raw field structure as read from the database.
240 */
241 function _field_info_prepare_field($field) {
242 // Make sure all expected field settings are present.
243 $field['settings'] += field_info_field_settings($field['type']);
244
245 return $field;
246 }
247
248 /**
249 * Prepare an instance definition for the current run-time context.
250 *
251 * Since the instance was last saved or updated, a number of things might have
252 * changed: widgets or formatters disabled, new settings expected, new build
253 * modes added...
254 *
255 * @param $instance
256 * The raw instance structure as read from the database.
257 * @param $field
258 * The field structure for the instance.
259 */
260 function _field_info_prepare_instance($instance, $field) {
261 $field_type = field_info_field_types($field['type']);
262
263 // Make sure all expected instance settings are present.
264 $instance['settings'] += field_info_instance_settings($field['type']);
265
266 // Fallback to default widget if widget type is not available.
267 if (!field_info_widget_types($instance['widget']['type'])) {
268 $instance['widget']['type'] = $field_type['default_widget'];
269 }
270 // Make sure all expected widget settings are present.
271 $instance['widget']['settings'] += field_info_widget_settings($instance['widget']['type']);
272
273 foreach ($instance['display'] as $build_mode => $display) {
274 if ($display['type'] != 'hidden') {
275 // Fallback to default formatter if formatter type is not available.
276 if (!field_info_formatter_types($instance['display'][$build_mode]['type'])) {
277 $instance['display'][$build_mode]['type'] = $field_type['default_formatter'];
278 }
279 // Make sure all expected formatter settings are present.
280 $instance['display'][$build_mode]['settings'] += field_info_formatter_settings($instance['display'][$build_mode]['type']);
281 }
282 }
283
284 // Fallback to 'full' display settings for unspecified build modes.
285 $obj_type = field_info_bundle_entity($instance['bundle']);
286 foreach (field_build_modes($obj_type) as $build_mode => $label) {
287 if (!isset($instance['display'][$build_mode])) {
288 $instance['display'][$build_mode] = $instance['display']['full'];
289 }
290 }
291
292 return $instance;
293 }
294
295 /**
296 * Helper function for determining the behavior of a widget
297 * with respect to a given operation.
298 *
299 * @param $op
300 * The name of the operation.
301 * Currently supported: 'default value', 'multiple values'.
302 * @param $instance
303 * The field instance array.
304 * @return
305 * FIELD_BEHAVIOR_NONE - do nothing for this operation.
306 * FIELD_BEHAVIOR_CUSTOM - use the widget's callback function.
307 * FIELD_BEHAVIOR_DEFAULT - use field.module default behavior.
308 */
309 function field_behaviors_widget($op, $instance) {
310 $info = field_info_widget_types($instance['widget']['type']);
311 return isset($info['behaviors'][$op]) ? $info['behaviors'][$op] : FIELD_BEHAVIOR_DEFAULT;
312 }
313
314 /**
315 * Helper function for determining the behavior of a formatter
316 * with respect to a given operation.
317 *
318 * @param $op
319 * The name of the operation.
320 * Currently supported: 'multiple values'
321 * @param $display
322 * The $instance['display'][$build_mode] array.
323 * @return
324 * FIELD_BEHAVIOR_NONE - do nothing for this operation.
325 * FIELD_BEHAVIOR_CUSTOM - use the formatter's callback function.
326 * FIELD_BEHAVIOR_DEFAULT - use field module default behavior.
327 */
328 function field_behaviors_formatter($op, $display) {
329 $info = field_info_formatter_types($display['type']);
330 return isset($info['behaviors'][$op]) ? $info['behaviors'][$op] : FIELD_BEHAVIOR_DEFAULT;
331 }
332
333 /**
334 * Return hook_field_info() data.
335 *
336 * @param $field_type
337 * (optional) A field type name. If ommitted, all field types will be
338 * returned.
339 * @return
340 * Either a field type description, as provided by hook_field_info(), or an
341 * array of all existing field types, keyed by field type name.
342 */
343 function field_info_field_types($field_type = NULL) {
344 $info = _field_info_collate_types();
345 $field_types = $info['field types'];
346 if ($field_type) {
347 if (isset($field_types[$field_type])) {
348 return $field_types[$field_type];
349 }
350 }
351 else {
352 return $field_types;
353 }
354 }
355
356 /**
357 * Return hook_field_widget_info() data.
358 *
359 * @param $widget_type
360 * (optional) A widget type name. If ommitted, all widget types will be
361 * returned.
362 * @return
363 * Either a widget type description, as provided by
364 * hook_field_widget_info(), or an array of all existing widget
365 * types, keyed by widget type name.
366 */
367 function field_info_widget_types($widget_type = NULL) {
368 $info = _field_info_collate_types();
369 $widget_types = $info['widget types'];
370 if ($widget_type) {
371 if (isset($widget_types[$widget_type])) {
372 return $widget_types[$widget_type];
373 }
374 }
375 else {
376 return $widget_types;
377 }
378 }
379
380 /**
381 * Return hook_field_formatter_info() data.
382 *
383 * @param $formatter_type
384 * (optional) A formatter type name. If ommitted, all formatter types will be
385 * returned.
386 * @return
387 * Either a formatter type description, as provided by hook_field_formatter_info(),
388 * or an array of all existing widget types, keyed by widget type name.
389 */
390 function field_info_formatter_types($formatter_type = NULL) {
391 $info = _field_info_collate_types();
392 $formatter_types = $info['formatter types'];
393 if ($formatter_type) {
394 if (isset($formatter_types[$formatter_type])) {
395 return $formatter_types[$formatter_type];
396 }
397 }
398 else {
399 return $formatter_types;
400 }
401 }
402
403 /**
404 * Return hook_fieldable_info() data.
405 *
406 * @param $obj_type
407 * (optional) A fieldable type name. If ommitted, all fieldable types will be
408 * returned.
409 * @return
410 * Either a fieldable type description, as provided by hook_fieldable_info(),
411 * or an array of all existing fieldable types, keyed by fieldable type name.
412 */
413 function field_info_fieldable_types($obj_type = NULL) {
414 $info = _field_info_collate_types();
415 $fieldable_types = $info['fieldable types'];
416 if ($obj_type) {
417 if (isset($fieldable_types[$obj_type])) {
418 return $fieldable_types[$obj_type];
419 }
420 }
421 else {
422 return $fieldable_types;
423 }
424 }
425
426 /**
427 * Return an array of fieldable bundle names and labels, for an individual
428 * object type or for all object types.
429 */
430 function field_info_bundles($obj_type = NULL) {
431 $info = _field_info_collate_types();
432 $bundles = array();
433 foreach ($info['fieldable types'] as $type => $fieldable_info) {
434 if (empty($obj_type) || $obj_type == $type) {
435 $bundles += $fieldable_info['bundles'];
436 }
437 }
438 return $bundles;
439 }
440
441 /**
442 * Identify the type of entity that created a bundle.
443 * // TODO : might not be needed depending on how we solve
444 * // the 'namespace bundle names' issue
445 */
446 function field_info_bundle_entity($bundle) {
447 $info = _field_info_collate_types();
448 foreach ($info['fieldable types'] as $type => $fieldable_info) {
449 if (isset($fieldable_info['bundles'][$bundle])) {
450 return $type;
451 }
452 }
453 return FALSE;
454 }
455
456 /**
457 * Return array of all field data, keyed by field name.
458 *
459 * @return
460 * An array of Field objects. Each Field object has an additional
461 * property, bundles, which is an array of all the bundles to which
462 * this field belongs.
463 */
464 function field_info_fields() {
465 $info = _field_info_collate_fields();
466 return $info['fields'];
467 }
468
469 /**
470 * Return data about an individual field.
471 *
472 * @param $field_name
473 * The name of the field to retrieve. $field_name can only refer to a
474 * non-deleted field.
475 * @return
476 * The named field object, or NULL. The Field object has an additional
477 * property, bundles, which is an array of all the bundles to which
478 * this field belongs.
479 */
480 function field_info_field($field_name) {
481 $info = _field_info_collate_fields();
482 if (isset($info['fields'][$field_name])) {
483 return $info['fields'][$field_name];
484 }
485 }
486
487 /**
488 * Return data about an individual field by its id.
489 *
490 * @param $field_id
491 * The id of the field to retrieve. $field_id can refer to a
492 * deleted field.
493 * @return
494 * The named field object, or NULL. The Field object has an additional
495 * property, bundles, which is an array of all the bundles to which
496 * this field belongs.
497 */
498 function field_info_field_by_id($field_id) {
499 $info = _field_info_collate_fields();
500 if (isset($info['field_ids'][$field_id])) {
501 return $info['field_ids'][$field_id];
502 }
503 }
504
505 /**
506 * Return an array of instance data for a given bundle,
507 * or for all known bundles, keyed by bundle name and field name.
508 *
509 * @param $bundle_name
510 * If set, return information on just this bundle.
511 */
512 function field_info_instances($bundle_name = NULL) {
513 $info = _field_info_collate_fields();
514 if (!isset($bundle_name)) {
515 return $info['instances'];
516 }
517 if (isset($info['instances'][$bundle_name])) {
518 return $info['instances'][$bundle_name];
519 }
520 return array();
521 }
522
523 /**
524 * Return an array of instance data for a specific field and bundle.
525 */
526 function field_info_instance($field_name, $bundle_name) {
527 $info = _field_info_collate_fields();
528 if (isset($info['instances'][$bundle_name][$field_name])) {
529 return $info['instances'][$bundle_name][$field_name];
530 }
531 }
532
533 /**
534 * Return a field type's default settings.
535 *
536 * @param $type
537 * A field type name.
538 * @return
539 * The field type's default settings, as provided by hook_field_info(), or an
540 * empty array.
541 */
542 function field_info_field_settings($type) {
543 $info = field_info_field_types($type);
544 return isset($info['settings']) ? $info['settings'] : array();
545 }
546
547 /**
548 * Return a field type's default instance settings.
549 *
550 * @param $type
551 * A field type name.
552 * @return
553 * The field type's default instance settings, as provided by
554 * hook_field_info(), or an empty array.
555 */
556 function field_info_instance_settings($type) {
557 $info = field_info_field_types($type);
558 return isset($info['instance_settings']) ? $info['instance_settings'] : array();
559 }
560
561 /**
562 * Return a field widget's default settings.
563 *
564 * @param $type
565 * A widget type name.
566 * @return
567 * The field type's default settings, as provided by hook_field_info(), or an
568 * empty array.
569 */
570 function field_info_widget_settings($type) {
571 $info = field_info_widget_types($type);
572 return isset($info['settings']) ? $info['settings'] : array();
573 }
574
575 /**
576 * Return a field formatter's default settings.
577 *
578 * @param $type
579 * A field formatter type name.
580 * @return
581 * The field formatter's default settings, as provided by
582 * hook_field_info(), or an empty array.
583 */
584 function field_info_formatter_settings($type) {
585 $info = field_info_formatter_types($type);
586 return isset($info['settings']) ? $info['settings'] : array();
587 }
588
589 /**
590 * @} End of "defgroup field_info"
591 */
592

Legend

Missed
lines code that were not excersized during program execution.
Covered
lines code were excersized during program execution.
Comment/non executable
Comment or non-executable line of code.
Dead
lines of code that according to xdebug could not be executed. This is counted as coverage code because in almost all cases it is code that runnable.