Skip navigation
Help

field.module

  1. drupal
    1. 7 drupal/modules/field/field.module

Attach custom data fields to Drupal entities.

Classes

NameDescription
FieldExceptionBase class for all exceptions thrown by Field API functions.
FieldUpdateForbiddenExceptionException class thrown by hook_field_update_forbid().

Functions & methods

NameDescription
field_accessDetermine whether the user has access to a given field.
field_associate_fieldsAllows a module to update the database for fields and columns it controls.
field_bundle_settingsGets or sets administratively defined bundle settings.
field_cache_clearClear the field info and field data caches.
field_cronImplements hook_cron().
field_extract_bundleHelper function to extract the bundle name of from a bundle object.
field_extra_fields_get_displayReturns the display settings to use for pseudo-fields in a given view mode.
field_filter_xssLike filter_xss_admin(), but with a shorter list of allowed tags.
field_flush_cachesImplements hook_flush_caches().
field_get_default_valueHelper function to get the default value for a field on an entity.
field_get_displayReturns the display settings to use for an instance in a given view mode.
field_get_itemsReturns the field items in the language they currently would be displayed.
field_has_dataDetermine whether a field has any data.
field_helpImplements hook_help().
field_modules_disabledImplements hook_modules_disabled().
field_modules_enabledImplements hook_modules_enabled().
field_modules_uninstalledImplements hook_modules_uninstalled().
field_themeImplements hook_theme().
field_view_fieldReturns a renderable array for the value of a single field in an entity.
field_view_mode_settingsReturns view mode settings in a given bundle.
field_view_valueReturns a renderable array for a single field value.
template_preprocess_fieldTheme preprocess function for theme_field() and field.tpl.php.
template_process_fieldTheme process function for theme_field() and field.tpl.php.
theme_fieldReturns HTML for a field.
_element_validate_integerDEPRECATED: Helper form element validator: integer.
_element_validate_integer_positiveDEPRECATED: Helper form element validator: integer > 0.
_element_validate_numberDEPRECATED: Helper form element validator: number.
_field_extra_fields_pre_renderPre-render callback to adjust weights and visibility of non-field elements.
_field_filter_itemsHelper function to filter out empty field values.
_field_filter_xss_allowed_tagsList of tags allowed by field_filter_xss().
_field_filter_xss_display_allowed_tagsHuman-readable list of allowed tags, for display in help texts.
_field_sort_itemsHelper function to sort items in a field according to user drag-n-drop reordering.
_field_sort_items_helperSort function for items order. (copied form element_sort(), which acts on #weight keys)
_field_sort_items_value_helperSame as above, using ['_weight']['#value']

Constants

NameDescription
FIELD_BEHAVIOR_CUSTOMValue for field API indicating a widget can receive several field values.
FIELD_BEHAVIOR_DEFAULTValue for field API concerning widget default and multiple value settings.
FIELD_BEHAVIOR_NONEValue for field API indicating a widget doesn't accept default values.
FIELD_CARDINALITY_UNLIMITEDValue for field API indicating a field accepts an unlimited number of values.
FIELD_LOAD_CURRENTAge argument for loading the most recent version of an entity's field data with field_attach_load().
FIELD_LOAD_REVISIONAge argument for loading the version of an entity's field data specified in the entity with field_attach_load().

File

drupal/modules/field/field.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * Attach custom data fields to Drupal entities.
  5. */
  6. /**
  7. * Base class for all exceptions thrown by Field API functions.
  8. *
  9. * This class has no functionality of its own other than allowing all
  10. * Field API exceptions to be caught by a single catch block.
  11. */
  12. class FieldException extends Exception {}
  13. /*
  14. * Load all public Field API functions. Drupal currently has no
  15. * mechanism for auto-loading core APIs, so we have to load them on
  16. * every page request.
  17. */
  18. require_once DRUPAL_ROOT . '/modules/field/field.crud.inc';
  19. require_once DRUPAL_ROOT . '/modules/field/field.default.inc';
  20. require_once DRUPAL_ROOT . '/modules/field/field.info.inc';
  21. require_once DRUPAL_ROOT . '/modules/field/field.multilingual.inc';
  22. require_once DRUPAL_ROOT . '/modules/field/field.attach.inc';
  23. require_once DRUPAL_ROOT . '/modules/field/field.form.inc';
  24. /**
  25. * @defgroup field Field API
  26. * @{
  27. * Attach custom data fields to Drupal entities.
  28. *
  29. * The Field API allows custom data fields to be attached to Drupal
  30. * entities and takes care of storing, loading, editing, and rendering
  31. * field data. Any entity type (node, user, etc.) can use the Field
  32. * API to make itself "fieldable" and thus allow fields to be attached
  33. * to it. Other modules can provide a user interface for managing custom
  34. * fields via a web browser as well as a wide and flexible variety of
  35. * data type, form element, and display format capabilities.
  36. *
  37. * The Field API defines two primary data structures, Field and
  38. * Instance, and the concept of a Bundle. A Field defines a
  39. * particular type of data that can be attached to entities. A Field
  40. * Instance is a Field attached to a single Bundle. A Bundle is a set
  41. * of fields that are treated as a group by the Field Attach API and
  42. * is related to a single fieldable entity type.
  43. *
  44. * For example, suppose a site administrator wants Article nodes to
  45. * have a subtitle and photo. Using the Field API or Field UI module,
  46. * the administrator creates a field named 'subtitle' of type 'text'
  47. * and a field named 'photo' of type 'image'. The administrator
  48. * (again, via a UI) creates two Field Instances, one attaching the
  49. * field 'subtitle' to the 'node' bundle 'article' and one attaching
  50. * the field 'photo' to the 'node' bundle 'article'. When the node
  51. * system uses the Field Attach API to load all fields for an Article
  52. * node, it passes the node's entity type (which is 'node') and
  53. * content type (which is 'article') as the node's bundle.
  54. * field_attach_load() then loads the 'subtitle' and 'photo' fields
  55. * because they are both attached to the 'node' bundle 'article'.
  56. *
  57. * Field definitions are represented as an array of key/value pairs.
  58. *
  59. * array $field:
  60. * - id (integer, read-only)
  61. * The primary identifier of the field. It is assigned automatically
  62. * by field_create_field().
  63. * - field_name (string)
  64. * The name of the field. Each field name is unique within Field API.
  65. * When a field is attached to an entity, the field's data is stored
  66. * in $entity->$field_name. Maximum length is 32 characters.
  67. * - type (string)
  68. * The type of the field, such as 'text' or 'image'. Field types
  69. * are defined by modules that implement hook_field_info().
  70. * - entity_types (array)
  71. * The array of entity types that can hold instances of this field. If
  72. * empty or not specified, the field can have instances in any entity type.
  73. * - cardinality (integer)
  74. * The number of values the field can hold. Legal values are any
  75. * positive integer or FIELD_CARDINALITY_UNLIMITED.
  76. * - translatable (integer)
  77. * Whether the field is translatable.
  78. * - locked (integer)
  79. * Whether or not the field is available for editing. If TRUE, users can't
  80. * change field settings or create new instances of the field in the UI.
  81. * Defaults to FALSE.
  82. * - module (string, read-only)
  83. * The name of the module that implements the field type.
  84. * - active (integer, read-only)
  85. * TRUE if the module that implements the field type is currently
  86. * enabled, FALSE otherwise.
  87. * - deleted (integer, read-only)
  88. * TRUE if this field has been deleted, FALSE otherwise. Deleted
  89. * fields are ignored by the Field Attach API. This property exists
  90. * because fields can be marked for deletion but only actually
  91. * destroyed by a separate garbage-collection process.
  92. * - columns (array, read-only).
  93. * An array of the Field API columns used to store each value of
  94. * this field. The column list may depend on field settings; it is
  95. * not constant per field type. Field API column specifications are
  96. * exactly like Schema API column specifications but, depending on
  97. * the field storage module in use, the name of the column may not
  98. * represent an actual column in an SQL database.
  99. * - indexes (array).
  100. * An array of indexes on data columns, using the same definition format
  101. * as Schema API index specifications. Only columns that appear in the
  102. * 'columns' setting are allowed. Note that field types can specify
  103. * default indexes, which can be modified or added to when
  104. * creating a field.
  105. * - foreign keys: (optional) An associative array of relations, using the same
  106. * structure as the 'foreign keys' definition of hook_schema(). Note, however,
  107. * that the field data is not necessarily stored in SQL. Also, the possible
  108. * usage is limited, as you cannot specify another field as related, only
  109. * existing SQL tables, such as filter formats.
  110. * - settings (array)
  111. * A sub-array of key/value pairs of field-type-specific settings. Each
  112. * field type module defines and documents its own field settings.
  113. * - storage (array)
  114. * A sub-array of key/value pairs identifying the storage backend to use for
  115. * the for the field.
  116. * - type (string)
  117. * The storage backend used by the field. Storage backends are defined
  118. * by modules that implement hook_field_storage_info().
  119. * - module (string, read-only)
  120. * The name of the module that implements the storage backend.
  121. * - active (integer, read-only)
  122. * TRUE if the module that implements the storage backend is currently
  123. * enabled, FALSE otherwise.
  124. * - settings (array)
  125. * A sub-array of key/value pairs of settings. Each storage backend
  126. * defines and documents its own settings.
  127. *
  128. * Field instance definitions are represented as an array of key/value pairs.
  129. *
  130. * array $instance:
  131. * - id (integer, read-only)
  132. * The primary identifier of this field instance. It is assigned
  133. * automatically by field_create_instance().
  134. * - field_id (integer, read-only)
  135. * The foreign key of the field attached to the bundle by this instance.
  136. * It is populated automatically by field_create_instance().
  137. * - field_name (string)
  138. * The name of the field attached to the bundle by this instance.
  139. * - entity_type (string)
  140. * The name of the entity type the instance is attached to.
  141. * - bundle (string)
  142. * The name of the bundle that the field is attached to.
  143. * - label (string)
  144. * A human-readable label for the field when used with this
  145. * bundle. For example, the label will be the title of Form API
  146. * elements for this instance.
  147. * - description (string)
  148. * A human-readable description for the field when used with this
  149. * bundle. For example, the description will be the help text of
  150. * Form API elements for this instance.
  151. * - required (integer)
  152. * TRUE if a value for this field is required when used with this
  153. * bundle, FALSE otherwise. Currently, required-ness is only enforced
  154. * during Form API operations, not by field_attach_load(),
  155. * field_attach_insert(), or field_attach_update().
  156. * - default_value_function (string)
  157. * The name of the function, if any, that will provide a default value.
  158. * - default_value (array)
  159. * If default_value_function is not set, then fixed values can be provided.
  160. * - deleted (integer, read-only)
  161. * TRUE if this instance has been deleted, FALSE otherwise.
  162. * Deleted instances are ignored by the Field Attach API.
  163. * This property exists because instances can be marked for deletion but
  164. * only actually destroyed by a separate garbage-collection process.
  165. * - settings (array)
  166. * A sub-array of key/value pairs of field-type-specific instance
  167. * settings. Each field type module defines and documents its own
  168. * instance settings.
  169. * - widget (array)
  170. * A sub-array of key/value pairs identifying the Form API input widget
  171. * for the field when used by this bundle.
  172. * - type (string)
  173. * The type of the widget, such as text_textfield. Widget types
  174. * are defined by modules that implement hook_field_widget_info().
  175. * - settings (array)
  176. * A sub-array of key/value pairs of widget-type-specific settings.
  177. * Each field widget type module defines and documents its own
  178. * widget settings.
  179. * - weight (float)
  180. * The weight of the widget relative to the other elements in entity
  181. * edit forms.
  182. * - module (string, read-only)
  183. * The name of the module that implements the widget type.
  184. * - display (array)
  185. * A sub-array of key/value pairs identifying the way field values should
  186. * be displayed in each of the entity type's view modes, plus the 'default'
  187. * mode. For each view mode, Field UI lets site administrators define
  188. * whether they want to use a dedicated set of display options or the
  189. * 'default' options to reduce the number of displays to maintain as they
  190. * add new fields. For nodes, on a fresh install, only the 'teaser' view
  191. * mode is configured to use custom display options, all other view modes
  192. * defined use the 'default' options by default. When programmatically
  193. * adding field instances on nodes, it is therefore recommended to at least
  194. * specify display options for 'default' and 'teaser'.
  195. * - default (array)
  196. * A sub-array of key/value pairs describing the display options to be
  197. * used when the field is being displayed in view modes that are not
  198. * configured to use dedicated display options.
  199. * - label (string)
  200. * Position of the label. 'inline', 'above' and 'hidden' are the
  201. * values recognized by the default 'field' theme implementation.
  202. * - type (string)
  203. * The type of the display formatter, or 'hidden' for no display.
  204. * - settings (array)
  205. * A sub-array of key/value pairs of display options specific to
  206. * the formatter.
  207. * - weight (float)
  208. * The weight of the field relative to the other entity components
  209. * displayed in this view mode.
  210. * - module (string, read-only)
  211. * The name of the module which implements the display formatter.
  212. * - some_mode
  213. * A sub-array of key/value pairs describing the display options to be
  214. * used when the field is being displayed in the 'some_mode' view mode.
  215. * Those options will only be actually applied at run time if the view
  216. * mode is not configured to use default settings for this bundle.
  217. * - ...
  218. * - other_mode
  219. * - ...
  220. *
  221. * Bundles are represented by two strings, an entity type and a bundle name.
  222. *
  223. * - @link field_types Field Types API @endlink. Defines field types,
  224. * widget types, and display formatters. Field modules use this API
  225. * to provide field types like Text and Node Reference along with the
  226. * associated form elements and display formatters.
  227. *
  228. * - @link field_crud Field CRUD API @endlink. Create, updates, and
  229. * deletes fields, bundles (a.k.a. "content types"), and instances.
  230. * Modules use this API, often in hook_install(), to create
  231. * custom data structures.
  232. *
  233. * - @link field_attach Field Attach API @endlink. Connects entity
  234. * types to the Field API. Field Attach API functions load, store,
  235. * generate Form API structures, display, and perform a variety of
  236. * other functions for field data connected to individual entities.
  237. * Fieldable entity types like node and user use this API to make
  238. * themselves fieldable.
  239. *
  240. * - @link field_info Field Info API @endlink. Exposes information
  241. * about all fields, instances, widgets, and related information
  242. * defined by or with the Field API.
  243. *
  244. * - @link field_storage Field Storage API @endlink. Provides a
  245. * pluggable back-end storage system for actual field data. The
  246. * default implementation, field_sql_storage.module, stores field data
  247. * in the local SQL database.
  248. *
  249. * - @link field_purge Field API bulk data deletion @endlink. Cleans
  250. * up after bulk deletion operations such as field_delete_field()
  251. * and field_delete_instance().
  252. *
  253. * - @link field_language Field language API @endlink. Provides native
  254. * multilingual support for the Field API.
  255. */
  256. /**
  257. * Value for field API indicating a field accepts an unlimited number of values.
  258. */
  259. define('FIELD_CARDINALITY_UNLIMITED', -1);
  260. /**
  261. * Value for field API indicating a widget doesn't accept default values.
  262. *
  263. * @see hook_field_widget_info()
  264. */
  265. define('FIELD_BEHAVIOR_NONE', 0x0001);
  266. /**
  267. * Value for field API concerning widget default and multiple value settings.
  268. *
  269. * @see hook_field_widget_info()
  270. *
  271. * When used in a widget default context, indicates the widget accepts default
  272. * values. When used in a multiple value context for a widget that allows the
  273. * input of one single field value, indicates that the widget will be repeated
  274. * for each value input.
  275. */
  276. define('FIELD_BEHAVIOR_DEFAULT', 0x0002);
  277. /**
  278. * Value for field API indicating a widget can receive several field values.
  279. *
  280. * @see hook_field_widget_info()
  281. */
  282. define('FIELD_BEHAVIOR_CUSTOM', 0x0004);
  283. /**
  284. * Age argument for loading the most recent version of an entity's
  285. * field data with field_attach_load().
  286. */
  287. define('FIELD_LOAD_CURRENT', 'FIELD_LOAD_CURRENT');
  288. /**
  289. * Age argument for loading the version of an entity's field data
  290. * specified in the entity with field_attach_load().
  291. */
  292. define('FIELD_LOAD_REVISION', 'FIELD_LOAD_REVISION');
  293. /**
  294. * Exception class thrown by hook_field_update_forbid().
  295. */
  296. class FieldUpdateForbiddenException extends FieldException {}
  297. /**
  298. * Implements hook_flush_caches().
  299. */
  300. function field_flush_caches() {
  301. return array('cache_field');
  302. }
  303. /**
  304. * Implements hook_help().
  305. */
  306. function field_help($path, $arg) {
  307. switch ($path) {
  308. case 'admin/help#field':
  309. $output = '';
  310. $output .= '<h3>' . t('About') . '</h3>';
  311. $output .= '<p>' . t('The Field module allows custom data fields to be defined for <em>entity</em> types (entities include content items, comments, user accounts, and taxonomy terms). The Field module takes care of storing, loading, editing, and rendering field data. Most users will not interact with the Field module directly, but will instead use the <a href="@field-ui-help">Field UI module</a> user interface. Module developers can use the Field API to make new entity types "fieldable" and thus allow fields to be attached to them. For more information, see the online handbook entry for <a href="@field">Field module</a>.', array('@field-ui-help' => url('admin/help/field_ui'), '@field' => 'http://drupal.org/handbook/modules/field')) . '</p>';
  312. $output .= '<h3>' . t('Uses') . '</h3>';
  313. $output .= '<dl>';
  314. $output .= '<dt>' . t('Enabling field types') . '</dt>';
  315. $output .= '<dd>' . t('The Field module provides the infrastructure for fields and field attachment; the field types and input widgets themselves are provided by additional modules. Some of the modules are required; the optional modules can be enabled from the <a href="@modules">Modules administration page</a>. Drupal core includes the following field type modules: Number (required), Text (required), List (required), Taxonomy (optional), Image (optional), and File (optional); the required Options module provides input widgets for other field modules. Additional fields and widgets may be provided by contributed modules, which you can find in the <a href="@contrib">contributed module section of Drupal.org</a>. Currently enabled field and input widget modules:', array('@modules' => url('admin/modules'), '@contrib' => 'http://drupal.org/project/modules', '@options' => url('admin/help/options')));
  316. // Make a list of all widget and field modules currently enabled, in
  317. // order by displayed module name (module names are not translated).
  318. $items = array();
  319. $info = system_get_info('module');
  320. $modules = array_merge(module_implements('field_info'), module_implements('field_widget_info'));
  321. $modules = array_unique($modules);
  322. sort($modules);
  323. foreach ($modules as $module) {
  324. $display = $info[$module]['name'];
  325. if (module_hook($module, 'help')) {
  326. $items['items'][] = l($display, 'admin/help/' . $module);
  327. }
  328. else {
  329. $items['items'][] = $display;
  330. }
  331. }
  332. $output .= theme('item_list', $items) . '</dd>';
  333. $output .= '<dt>' . t('Managing field data storage') . '</dt>';
  334. $output .= '<dd>' . t('Developers of field modules can either use the default <a href="@sql-store">Field SQL storage module</a> to store data for their fields, or a contributed or custom module developed using the <a href="@storage-api">field storage API</a>.', array('@storage-api' => 'http://api.drupal.org/api/group/field_storage/7', '@sql-store' => url('admin/help/field_sql_storage'))) . '</dd>';
  335. $output .= '</dl>';
  336. return $output;
  337. }
  338. }
  339. /**
  340. * Implements hook_theme().
  341. */
  342. function field_theme() {
  343. return array(
  344. 'field' => array(
  345. 'render element' => 'element',
  346. ),
  347. 'field_multiple_value_form' => array(
  348. 'render element' => 'element',
  349. ),
  350. );
  351. }
  352. /**
  353. * Implements hook_cron().
  354. *
  355. * Purges some deleted Field API data, if any exists.
  356. */
  357. function field_cron() {
  358. $limit = variable_get('field_purge_batch_size', 10);
  359. field_purge_batch($limit);
  360. }
  361. /**
  362. * Implements hook_modules_uninstalled().
  363. */
  364. function field_modules_uninstalled($modules) {
  365. module_load_include('inc', 'field', 'field.crud');
  366. foreach ($modules as $module) {
  367. // TODO D7: field_module_delete is not yet implemented
  368. // field_module_delete($module);
  369. }
  370. }
  371. /**
  372. * Implements hook_modules_enabled().
  373. */
  374. function field_modules_enabled($modules) {
  375. foreach ($modules as $module) {
  376. field_associate_fields($module);
  377. }
  378. field_cache_clear();
  379. }
  380. /**
  381. * Implements hook_modules_disabled().
  382. */
  383. function field_modules_disabled($modules) {
  384. // Track fields whose field type is being disabled.
  385. db_update('field_config')
  386. ->fields(array('active' => 0))
  387. ->condition('module', $modules, 'IN')
  388. ->execute();
  389. // Track fields whose storage backend is being disabled.
  390. db_update('field_config')
  391. ->fields(array('storage_active' => 0))
  392. ->condition('storage_module', $modules, 'IN')
  393. ->execute();
  394. field_cache_clear();
  395. }
  396. /**
  397. * Allows a module to update the database for fields and columns it controls.
  398. *
  399. * @param string $module
  400. * The name of the module to update on.
  401. */
  402. function field_associate_fields($module) {
  403. // Associate field types.
  404. $field_types =(array) module_invoke($module, 'field_info');
  405. foreach ($field_types as $name => $field_info) {
  406. watchdog('field', 'Updating field type %type with module %module.', array('%type' => $name, '%module' => $module));
  407. db_update('field_config')
  408. ->fields(array('module' => $module, 'active' => 1))
  409. ->condition('type', $name)
  410. ->execute();
  411. }
  412. // Associate storage backends.
  413. $storage_types = (array) module_invoke($module, 'field_storage_info');
  414. foreach ($storage_types as $name => $storage_info) {
  415. watchdog('field', 'Updating field storage %type with module %module.', array('%type' => $name, '%module' => $module));
  416. db_update('field_config')
  417. ->fields(array('storage_module' => $module, 'storage_active' => 1))
  418. ->condition('storage_type', $name)
  419. ->execute();
  420. }
  421. }
  422. /**
  423. * Helper function to get the default value for a field on an entity.
  424. *
  425. * @param $entity_type
  426. * The type of $entity; e.g., 'node' or 'user'.
  427. * @param $entity
  428. * The entity for the operation.
  429. * @param $field
  430. * The field structure.
  431. * @param $instance
  432. * The instance structure.
  433. * @param $langcode
  434. * The field language to fill-in with the default value.
  435. */
  436. function field_get_default_value($entity_type, $entity, $field, $instance, $langcode = NULL) {
  437. $items = array();
  438. if (!empty($instance['default_value_function'])) {
  439. $function = $instance['default_value_function'];
  440. if (function_exists($function)) {
  441. $items = $function($entity_type, $entity, $field, $instance, $langcode);
  442. }
  443. }
  444. elseif (!empty($instance['default_value'])) {
  445. $items = $instance['default_value'];
  446. }
  447. return $items;
  448. }
  449. /**
  450. * Helper function to filter out empty field values.
  451. *
  452. * @param $field
  453. * The field definition.
  454. * @param $items
  455. * The field values to filter.
  456. *
  457. * @return
  458. * The array of items without empty field values. The function also renumbers
  459. * the array keys to ensure sequential deltas.
  460. */
  461. function _field_filter_items($field, $items) {
  462. $function = $field['module'] . '_field_is_empty';
  463. function_exists($function);
  464. foreach ((array) $items as $delta => $item) {
  465. // Explicitly break if the function is undefined.
  466. if ($function($item, $field)) {
  467. unset($items[$delta]);
  468. }
  469. }
  470. return array_values($items);
  471. }
  472. /**
  473. * Helper function to sort items in a field according to
  474. * user drag-n-drop reordering.
  475. */
  476. function _field_sort_items($field, $items) {
  477. if (($field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED) && isset($items[0]['_weight'])) {
  478. usort($items, '_field_sort_items_helper');
  479. foreach ($items as $delta => $item) {
  480. if (is_array($items[$delta])) {
  481. unset($items[$delta]['_weight']);
  482. }
  483. }
  484. }
  485. return $items;
  486. }
  487. /**
  488. * Sort function for items order.
  489. * (copied form element_sort(), which acts on #weight keys)
  490. */
  491. function _field_sort_items_helper($a, $b) {
  492. $a_weight = (is_array($a) ? $a['_weight'] : 0);
  493. $b_weight = (is_array($b) ? $b['_weight'] : 0);
  494. return $a_weight - $b_weight;
  495. }
  496. /**
  497. * Same as above, using ['_weight']['#value']
  498. */
  499. function _field_sort_items_value_helper($a, $b) {
  500. $a_weight = (is_array($a) && isset($a['_weight']['#value']) ? $a['_weight']['#value'] : 0);
  501. $b_weight = (is_array($b) && isset($b['_weight']['#value']) ? $b['_weight']['#value'] : 0);
  502. return $a_weight - $b_weight;
  503. }
  504. /**
  505. * Gets or sets administratively defined bundle settings.
  506. *
  507. * For each bundle, settings are provided as a nested array with the following
  508. * structure:
  509. * @code
  510. * array(
  511. * 'view_modes' => array(
  512. * // One sub-array per view mode for the entity type:
  513. * 'full' => array(
  514. * 'custom_display' => Whether the view mode uses custom display
  515. * settings or settings of the 'default' mode,
  516. * ),
  517. * 'teaser' => ...
  518. * ),
  519. * 'extra_fields' => array(
  520. * 'form' => array(
  521. * // One sub-array per pseudo-field in displayed entities:
  522. * 'extra_field_1' => array(
  523. * 'weight' => The weight of the pseudo-field,
  524. * ),
  525. * 'extra_field_2' => ...
  526. * ),
  527. * 'display' => array(
  528. * // One sub-array per pseudo-field in displayed entities:
  529. * 'extra_field_1' => array(
  530. * // One sub-array per view mode for the entity type, including
  531. * // the 'default' mode:
  532. * 'default' => array(
  533. * 'weight' => The weight of the pseudo-field,
  534. * 'visible' => TRUE if the pseudo-field is visible, FALSE if hidden,
  535. * ),
  536. * 'full' => ...
  537. * ),
  538. * 'extra_field_2' => ...
  539. * ),
  540. * ),
  541. * );
  542. * @endcode
  543. *
  544. * @param $entity_type
  545. * The type of $entity; e.g., 'node' or 'user'.
  546. * @param $bundle
  547. * The bundle name.
  548. * @param $settings
  549. * (optional) The settings to store.
  550. *
  551. * @return
  552. * If no $settings are passed, the current settings are returned.
  553. */
  554. function field_bundle_settings($entity_type, $bundle, $settings = NULL) {
  555. $stored_settings = variable_get('field_bundle_settings', array());
  556. if (isset($settings)) {
  557. $stored_settings[$entity_type][$bundle] = $settings;
  558. variable_set('field_bundle_settings', $stored_settings);
  559. field_info_cache_clear();
  560. }
  561. else {
  562. $settings = isset($stored_settings[$entity_type][$bundle]) ? $stored_settings[$entity_type][$bundle] : array();
  563. $settings += array(
  564. 'view_modes' => array(),
  565. 'extra_fields' => array(),
  566. );
  567. $settings['extra_fields'] += array(
  568. 'form' => array(),
  569. 'display' => array(),
  570. );
  571. return $settings;
  572. }
  573. }
  574. /**
  575. * Returns view mode settings in a given bundle.
  576. *
  577. * @param $entity_type
  578. * The type of entity; e.g. 'node' or 'user'.
  579. * @param $bundle
  580. * The bundle name to return view mode settings for.
  581. *
  582. * @return
  583. * An array keyed by view mode, with the following key/value pairs:
  584. * - custom_settings: Boolean specifying whether the view mode uses a
  585. * dedicated set of display options (TRUE), or the 'default' options
  586. * (FALSE). Defaults to FALSE.
  587. */
  588. function field_view_mode_settings($entity_type, $bundle) {
  589. $cache = &drupal_static(__FUNCTION__, array());
  590. if (!isset($cache[$entity_type][$bundle])) {
  591. $bundle_settings = field_bundle_settings($entity_type, $bundle);
  592. $settings = $bundle_settings['view_modes'];
  593. // Include view modes for which nothing has been stored yet, but whose
  594. // definition in hook_entity_info() specify they should use custom settings
  595. // by default.
  596. $entity_info = entity_get_info($entity_type);
  597. foreach ($entity_info['view modes'] as $view_mode => $view_mode_info) {
  598. if (!isset($settings[$view_mode]['custom_settings']) && $view_mode_info['custom settings']) {
  599. $settings[$view_mode]['custom_settings'] = TRUE;
  600. }
  601. }
  602. $cache[$entity_type][$bundle] = $settings;
  603. }
  604. return $cache[$entity_type][$bundle];
  605. }
  606. /**
  607. * Returns the display settings to use for an instance in a given view mode.
  608. *
  609. * @param $instance
  610. * The field instance being displayed.
  611. * @param $view_mode
  612. * The view mode.
  613. * @param $entity
  614. * The entity being displayed.
  615. *
  616. * @return
  617. * The display settings to be used when displaying the field values.
  618. */
  619. function field_get_display($instance, $view_mode, $entity) {
  620. // Check whether the view mode uses custom display settings or the 'default'
  621. // mode.
  622. $view_mode_settings = field_view_mode_settings($instance['entity_type'], $instance['bundle']);
  623. $actual_mode = (!empty($view_mode_settings[$view_mode]['custom_settings']) ? $view_mode : 'default');
  624. $display = $instance['display'][$actual_mode];
  625. // Let modules alter the display settings.
  626. $context = array(
  627. 'entity_type' => $instance['entity_type'],
  628. 'field' => field_info_field($instance['field_name']),
  629. 'instance' => $instance,
  630. 'entity' => $entity,
  631. 'view_mode' => $view_mode,
  632. );
  633. drupal_alter(array('field_display', 'field_display_' . $instance['entity_type']), $display, $context);
  634. return $display;
  635. }
  636. /**
  637. * Returns the display settings to use for pseudo-fields in a given view mode.
  638. *
  639. * @param $entity_type
  640. * The type of $entity; e.g., 'node' or 'user'.
  641. * @param $bundle
  642. * The bundle name.
  643. * @param $view_mode
  644. * The view mode.
  645. *
  646. * @return
  647. * The display settings to be used when viewing the bundle's pseudo-fields.
  648. */
  649. function field_extra_fields_get_display($entity_type, $bundle, $view_mode) {
  650. // Check whether the view mode uses custom display settings or the 'default'
  651. // mode.
  652. $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
  653. $actual_mode = (!empty($view_mode_settings[$view_mode]['custom_settings'])) ? $view_mode : 'default';
  654. $extra_fields = field_info_extra_fields($entity_type, $bundle, 'display');
  655. $displays = array();
  656. foreach ($extra_fields as $name => $value) {
  657. $displays[$name] = $extra_fields[$name]['display'][$actual_mode];
  658. }
  659. // Let modules alter the display settings.
  660. $context = array(
  661. 'entity_type' => $entity_type,
  662. 'bundle' => $bundle,
  663. 'view_mode' => $view_mode,
  664. );
  665. drupal_alter('field_extra_fields_display', $displays, $context);
  666. return $displays;
  667. }
  668. /**
  669. * Pre-render callback to adjust weights and visibility of non-field elements.
  670. */
  671. function _field_extra_fields_pre_render($elements) {
  672. $entity_type = $elements['#entity_type'];
  673. $bundle = $elements['#bundle'];
  674. if (isset($elements['#type']) && $elements['#type'] == 'form') {
  675. $extra_fields = field_info_extra_fields($entity_type, $bundle, 'form');
  676. foreach ($extra_fields as $name => $settings) {
  677. if (isset($elements[$name])) {
  678. $elements[$name]['#weight'] = $settings['weight'];
  679. }
  680. }
  681. }
  682. elseif (isset($elements['#view_mode'])) {
  683. $view_mode = $elements['#view_mode'];
  684. $extra_fields = field_extra_fields_get_display($entity_type, $bundle, $view_mode);
  685. foreach ($extra_fields as $name => $settings) {
  686. if (isset($elements[$name])) {
  687. $elements[$name]['#weight'] = $settings['weight'];
  688. // Visibility: make sure we do not accidentally show a hidden element.
  689. $elements[$name]['#access'] = isset($elements[$name]['#access']) ? ($elements[$name]['#access'] && $settings['visible']) : $settings['visible'];
  690. }
  691. }
  692. }
  693. return $elements;
  694. }
  695. /**
  696. * Clear the field info and field data caches.
  697. */
  698. function field_cache_clear() {
  699. cache_clear_all('*', 'cache_field', TRUE);
  700. field_info_cache_clear();
  701. }
  702. /**
  703. * Like filter_xss_admin(), but with a shorter list of allowed tags.
  704. *
  705. * Used for items entered by administrators, like field descriptions,
  706. * allowed values, where some (mainly inline) mark-up may be desired
  707. * (so check_plain() is not acceptable).
  708. */
  709. function field_filter_xss($string) {
  710. return filter_xss($string, _field_filter_xss_allowed_tags());
  711. }
  712. /**
  713. * List of tags allowed by field_filter_xss().
  714. */
  715. function _field_filter_xss_allowed_tags() {
  716. return array('a', 'b', 'big', 'code', 'del', 'em', 'i', 'ins', 'pre', 'q', 'small', 'span', 'strong', 'sub', 'sup', 'tt', 'ol', 'ul', 'li', 'p', 'br', 'img');
  717. }
  718. /**
  719. * Human-readable list of allowed tags, for display in help texts.
  720. */
  721. function _field_filter_xss_display_allowed_tags() {
  722. return '<' . implode('> <', _field_filter_xss_allowed_tags()) . '>';
  723. }
  724. /**
  725. * Returns a renderable array for a single field value.
  726. *
  727. * @param $entity_type
  728. * The type of $entity; e.g., 'node' or 'user'.
  729. * @param $entity
  730. * The entity containing the field to display. Must at least contain the id
  731. * key and the field data to display.
  732. * @param $field_name
  733. * The name of the field to display.
  734. * @param $item
  735. * The field value to display, as found in
  736. * $entity->field_name[$langcode][$delta].
  737. * @param $display
  738. * Can be either the name of a view mode, or an array of display settings.
  739. * See field_view_field() for more information.
  740. * @param $langcode
  741. * (Optional) The language of the value in $item. If not provided, the
  742. * current language will be assumed.
  743. * @return
  744. * A renderable array for the field value.
  745. */
  746. function field_view_value($entity_type, $entity, $field_name, $item, $display = array(), $langcode = NULL) {
  747. $output = array();
  748. if ($field = field_info_field($field_name)) {
  749. // Determine the langcode that will be used by language fallback.
  750. $langcode = field_language($entity_type, $entity, $field_name, $langcode);
  751. // Push the item as the single value for the field, and defer to
  752. // field_view_field() to build the render array for the whole field.
  753. $clone = clone $entity;
  754. $clone->{$field_name}[$langcode] = array($item);
  755. $elements = field_view_field($entity_type, $clone, $field_name, $display, $langcode);
  756. // Extract the part of the render array we need.
  757. $output = isset($elements[0]) ? $elements[0] : array();
  758. if (isset($elements['#access'])) {
  759. $output['#access'] = $elements['#access'];
  760. }
  761. }
  762. return $output;
  763. }
  764. /**
  765. * Returns a renderable array for the value of a single field in an entity.
  766. *
  767. * The resulting output is a fully themed field with label and multiple values.
  768. *
  769. * This function can be used by third-party modules that need to output an
  770. * isolated field.
  771. * - Do not use inside node (or other entities) templates, use
  772. * render($content[FIELD_NAME]) instead.
  773. * - Do not use to display all fields in an entity, use
  774. * field_attach_prepare_view() and field_attach_view() instead.
  775. * - The field_view_value() function can be used to output a single formatted
  776. * field value, without label or wrapping field markup.
  777. *
  778. * The function takes care of invoking the prepare_view steps. It also respects
  779. * field access permissions.
  780. *
  781. * @param $entity_type
  782. * The type of $entity; e.g., 'node' or 'user'.
  783. * @param $entity
  784. * The entity containing the field to display. Must at least contain the id
  785. * key and the field data to display.
  786. * @param $field_name
  787. * The name of the field to display.
  788. * @param $display
  789. * Can be either:
  790. * - The name of a view mode. The field will be displayed according to the
  791. * display settings specified for this view mode in the $instance
  792. * definition for the field in the entity's bundle.
  793. * If no display settings are found for the view mode, the settings for
  794. * the 'default' view mode will be used.
  795. * - An array of display settings, as found in the 'display' entry of
  796. * $instance definitions. The following key/value pairs are allowed:
  797. * - label: (string) Position of the label. The default 'field' theme
  798. * implementation supports the values 'inline', 'above' and 'hidden'.
  799. * Defaults to 'above'.
  800. * - type: (string) The formatter to use. Defaults to the
  801. * 'default_formatter' for the field type, specified in
  802. * hook_field_info(). The default formatter will also be used if the
  803. * requested formatter is not available.
  804. * - settings: (array) Settings specific to the formatter. Defaults to the
  805. * formatter's default settings, specified in
  806. * hook_field_formatter_info().
  807. * - weight: (float) The weight to assign to the renderable element.
  808. * Defaults to 0.
  809. * @param $langcode
  810. * (Optional) The language the field values are to be shown in. The site's
  811. * current language fallback logic will be applied no values are available
  812. * for the language. If no language is provided the current language will be
  813. * used.
  814. * @return
  815. * A renderable array for the field value.
  816. *
  817. * @see field_view_value()
  818. */
  819. function field_view_field($entity_type, $entity, $field_name, $display = array(), $langcode = NULL) {
  820. $output = array();
  821. if ($field = field_info_field($field_name)) {
  822. if (is_array($display)) {
  823. // When using custom display settings, fill in default values.
  824. $display = _field_info_prepare_instance_display($field, $display);
  825. }
  826. // Hook invocations are done through the _field_invoke() functions in
  827. // 'single field' mode, to reuse the language fallback logic.
  828. // Determine the actual language to display for the field, given the
  829. // languages available in the field data.
  830. $display_language = field_language($entity_type, $entity, $field_name, $langcode);
  831. $options = array('field_name' => $field_name, 'language' => $display_language);
  832. $null = NULL;
  833. // Invoke prepare_view steps if needed.
  834. if (empty($entity->_field_view_prepared)) {
  835. list($id) = entity_extract_ids($entity_type, $entity);
  836. // First let the field types do their preparation.
  837. _field_invoke_multiple('prepare_view', $entity_type, array($id => $entity), $display, $null, $options);
  838. // Then let the formatters do their own specific massaging.
  839. _field_invoke_multiple_default('prepare_view', $entity_type, array($id => $entity), $display, $null, $options);
  840. }
  841. // Build the renderable array.
  842. $result = _field_invoke_default('view', $entity_type, $entity, $display, $null, $options);
  843. // Invoke hook_field_attach_view_alter() to let other modules alter the
  844. // renderable array, as in a full field_attach_view() execution.
  845. $context = array(
  846. 'entity_type' => $entity_type,
  847. 'entity' => $entity,
  848. 'view_mode' => '_custom',
  849. 'display' => $display,
  850. );
  851. drupal_alter('field_attach_view', $result, $context);
  852. if (isset($result[$field_name])) {
  853. $output = $result[$field_name];
  854. }
  855. }
  856. return $output;
  857. }
  858. /**
  859. * Returns the field items in the language they currently would be displayed.
  860. *
  861. * @param $entity_type
  862. * The type of $entity; e.g., 'node' or 'user'.
  863. * @param $entity
  864. * The entity containing the data to be displayed.
  865. * @param $field_name
  866. * The field to be displayed.
  867. * @param $langcode
  868. * (optional) The language code $entity->{$field_name} has to be displayed in.
  869. * Defaults to the current language.
  870. *
  871. * @return
  872. * An array of field items keyed by delta if available, FALSE otherwise.
  873. */
  874. function field_get_items($entity_type, $entity, $field_name, $langcode = NULL) {
  875. $langcode = field_language($entity_type, $entity, $field_name, $langcode);
  876. return isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : FALSE;
  877. }
  878. /**
  879. * Determine whether a field has any data.
  880. *
  881. * @param $field
  882. * A field structure.
  883. * @return
  884. * TRUE if the field has data for any entity; FALSE otherwise.
  885. */
  886. function field_has_data($field) {
  887. $query = new EntityFieldQuery();
  888. return (bool) $query
  889. ->fieldCondition($field)
  890. ->range(0, 1)
  891. ->count()
  892. ->execute();
  893. }
  894. /**
  895. * Determine whether the user has access to a given field.
  896. *
  897. * @param $op
  898. * The operation to be performed. Possible values:
  899. * - "edit"
  900. * - "view"
  901. * @param $field
  902. * The field on which the operation is to be performed.
  903. * @param $entity_type
  904. * The type of $entity; e.g., 'node' or 'user'.
  905. * @param $entity
  906. * (optional) The entity for the operation.
  907. * @param $account
  908. * (optional) The account to check, if not given use currently logged in user.
  909. * @return
  910. * TRUE if the operation is allowed;
  911. * FALSE if the operation is denied.
  912. */
  913. function field_access($op, $field, $entity_type, $entity = NULL, $account = NULL) {
  914. global $user;
  915. if (!isset($account)) {
  916. $account = $user;
  917. }
  918. foreach (module_implements('field_access') as $module) {
  919. $function = $module . '_field_access';
  920. $access = $function($op, $field, $entity_type, $entity, $account);
  921. if ($access === FALSE) {
  922. return FALSE;
  923. }
  924. }
  925. return TRUE;
  926. }
  927. /**
  928. * Helper function to extract the bundle name of from a bundle object.
  929. *
  930. * @param $entity_type
  931. * The type of $entity; e.g., 'node' or 'user'.
  932. * @param $bundle
  933. * The bundle object (or string if bundles for this entity type do not exist
  934. * as standalone objects).
  935. * @return
  936. * The bundle name.
  937. */
  938. function field_extract_bundle($entity_type, $bundle) {
  939. if (is_string($bundle)) {
  940. return $bundle;
  941. }
  942. $info = entity_get_info($entity_type);
  943. if (is_object($bundle) && isset($info['bundle keys']['bundle']) && isset($bundle->{$info['bundle keys']['bundle']})) {
  944. return $bundle->{$info['bundle keys']['bundle']};
  945. }
  946. }
  947. /**
  948. * Theme preprocess function for theme_field() and field.tpl.php.
  949. *
  950. * @see theme_field()
  951. * @see field.tpl.php
  952. */
  953. function template_preprocess_field(&$variables, $hook) {
  954. $element = $variables['element'];
  955. // There's some overhead in calling check_plain() so only call it if the label
  956. // variable is being displayed. Otherwise, set it to NULL to avoid PHP
  957. // warnings if a theme implementation accesses the variable even when it's
  958. // supposed to be hidden. If a theme implementation needs to print a hidden
  959. // label, it needs to supply a preprocess function that sets it to the
  960. // sanitized element title or whatever else is wanted in its place.
  961. $variables['label_hidden'] = ($element['#label_display'] == 'hidden');
  962. $variables['label'] = $variables['label_hidden'] ? NULL : check_plain($element['#title']);
  963. // We want other preprocess functions and the theme implementation to have
  964. // fast access to the field item render arrays. The item render array keys
  965. // (deltas) should always be a subset of the keys in #items, and looping on
  966. // those keys is faster than calling element_children() or looping on all keys
  967. // within $element, since that requires traversal of all element properties.
  968. $variables['items'] = array();
  969. foreach ($element['#items'] as $delta => $item) {
  970. if (!empty($element[$delta])) {
  971. $variables['items'][$delta] = $element[$delta];
  972. }
  973. }
  974. // Add default CSS classes. Since there can be many fields rendered on a page,
  975. // save some overhead by calling strtr() directly instead of
  976. // drupal_html_class().
  977. $variables['field_name_css'] = strtr($element['#field_name'], '_', '-');
  978. $variables['field_type_css'] = strtr($element['#field_type'], '_', '-');
  979. $variables['classes_array'] = array(
  980. 'field',
  981. 'field-name-' . $variables['field_name_css'],
  982. 'field-type-' . $variables['field_type_css'],
  983. 'field-label-' . $element['#label_display'],
  984. );
  985. // Add a "clearfix" class to the wrapper since we float the label and the
  986. // field items in field.css if the label is inline.
  987. if ($element['#label_display'] == 'inline') {
  988. $variables['classes_array'][] = 'clearfix';
  989. }
  990. // Add specific suggestions that can override the default implementation.
  991. $variables['theme_hook_suggestions'] = array(
  992. 'field__' . $element['#field_type'],
  993. 'field__' . $element['#field_name'],
  994. 'field__' . $element['#bundle'],
  995. 'field__' . $element['#field_name'] . '__' . $element['#bundle'],
  996. );
  997. }
  998. /**
  999. * Theme process function for theme_field() and field.tpl.php.
  1000. *
  1001. * @see theme_field()
  1002. * @see field.tpl.php
  1003. */
  1004. function template_process_field(&$variables, $hook) {
  1005. // The default theme implementation is a function, so template_process() does
  1006. // not automatically run, so we need to flatten the classes and attributes
  1007. // here. For best performance, only call drupal_attributes() when needed, and
  1008. // note that template_preprocess_field() does not initialize the
  1009. // *_attributes_array variables.
  1010. $variables['classes'] = implode(' ', $variables['classes_array']);
  1011. $variables['attributes'] = empty($variables['attributes_array']) ? '' : drupal_attributes($variables['attributes_array']);
  1012. $variables['title_attributes'] = empty($variables['title_attributes_array']) ? '' : drupal_attributes($variables['title_attributes_array']);
  1013. $variables['content_attributes'] = empty($variables['content_attributes_array']) ? '' : drupal_attributes($variables['content_attributes_array']);
  1014. foreach ($variables['items'] as $delta => $item) {
  1015. $variables['item_attributes'][$delta] = empty($variables['item_attributes_array'][$delta]) ? '' : drupal_attributes($variables['item_attributes_array'][$delta]);
  1016. }
  1017. }
  1018. /**
  1019. * @} End of "defgroup field"
  1020. */
  1021. /**
  1022. * Returns HTML for a field.
  1023. *
  1024. * This is the default theme implementation to display the value of a field.
  1025. * Theme developers who are comfortable with overriding theme functions may do
  1026. * so in order to customize this markup. This function can be overridden with
  1027. * varying levels of specificity. For example, for a field named 'body'
  1028. * displayed on the 'article' content type, any of the following functions will
  1029. * override this default implementation. The first of these functions that
  1030. * exists is used:
  1031. * - THEMENAME_field__body__article()
  1032. * - THEMENAME_field__article()
  1033. * - THEMENAME_field__body()
  1034. * - THEMENAME_field()
  1035. *
  1036. * Theme developers who prefer to customize templates instead of overriding
  1037. * functions may copy the "field.tpl.php" from the "modules/field/theme" folder
  1038. * of the Drupal installation to somewhere within the theme's folder and
  1039. * customize it, just like customizing other Drupal templates such as
  1040. * page.tpl.php or node.tpl.php. However, it takes longer for the server to
  1041. * process templates than to call a function, so for websites with many fields
  1042. * displayed on a page, this can result in a noticeable slowdown of the website.
  1043. * For these websites, developers are discouraged from placing a field.tpl.php
  1044. * file into the theme's folder, but may customize templates for specific
  1045. * fields. For example, for a field named 'body' displayed on the 'article'
  1046. * content type, any of the following templates will override this default
  1047. * implementation. The first of these templates that exists is used:
  1048. * - field--body--article.tpl.php
  1049. * - field--article.tpl.php
  1050. * - field--body.tpl.php
  1051. * - field.tpl.php
  1052. * So, if the body field on the article content type needs customization, a
  1053. * field--body--article.tpl.php file can be added within the theme's folder.
  1054. * Because it's a template, it will result in slightly more time needed to
  1055. * display that field, but it will not impact other fields, and therefore,
  1056. * is unlikely to cause a noticeable change in website performance. A very rough
  1057. * guideline is that if a page is being displayed with more than 100 fields and
  1058. * they are all themed with a template instead of a function, it can add up to
  1059. * 5% to the time it takes to display that page. This is a guideline only and
  1060. * the exact performance impact depends on the server configuration and the
  1061. * details of the website.
  1062. *
  1063. * @param $variables
  1064. * An associative array containing:
  1065. * - label_hidden: A boolean indicating to show or hide the field label.
  1066. * - title_attributes: A string containing the attributes for the title.
  1067. * - label: The label for the field.
  1068. * - content_attributes: A string containing the attributes for the content's
  1069. * div.
  1070. * - items: An array of field items.
  1071. * - item_attributes: An array of attributes for each item.
  1072. * - classes: A string containing the classes for the wrapping div.
  1073. * - attributes: A string containing the attributes for the wrapping div.
  1074. *
  1075. * @see template_preprocess_field()
  1076. * @see template_process_field()
  1077. * @see field.tpl.php
  1078. *
  1079. * @ingroup themeable
  1080. */
  1081. function theme_field($variables) {
  1082. $output = '';
  1083. // Render the label, if it's not hidden.
  1084. if (!$variables['label_hidden']) {
  1085. $output .= '<div class="field-label"' . $variables['title_attributes'] . '>' . $variables['label'] . ':&nbsp;</div>';
  1086. }
  1087. // Render the items.
  1088. $output .= '<div class="field-items"' . $variables['content_attributes'] . '>';
  1089. foreach ($variables['items'] as $delta => $item) {
  1090. $classes = 'field-item ' . ($delta % 2 ? 'odd' : 'even');
  1091. $output .= '<div class="' . $classes . '"' . $variables['item_attributes'][$delta] . '>' . drupal_render($item) . '</div>';
  1092. }
  1093. $output .= '</div>';
  1094. // Render the top-level DIV.
  1095. $output = '<div class="' . $variables['classes'] . '"' . $variables['attributes'] . '>' . $output . '</div>';
  1096. return $output;
  1097. }
  1098. /**
  1099. * DEPRECATED: Helper form element validator: integer.
  1100. *
  1101. * Use element_validate_integer() instead.
  1102. *
  1103. * @deprecated
  1104. * @see element_validate_integer()
  1105. */
  1106. function _element_validate_integer($element, &$form_state) {
  1107. element_validate_integer($element, $form_state);
  1108. }
  1109. /**
  1110. * DEPRECATED: Helper form element validator: integer > 0.
  1111. *
  1112. * Use element_validate_integer_positive() instead.
  1113. *
  1114. * @deprecated
  1115. * @see element_validate_number_positive()
  1116. */
  1117. function _element_validate_integer_positive($element, &$form_state) {
  1118. element_validate_integer_positive($element, $form_state);
  1119. }
  1120. /**
  1121. * DEPRECATED: Helper form element validator: number.
  1122. *
  1123. * Use element_validate_number() instead.
  1124. *
  1125. * @deprecated
  1126. * @see element_validate_number()
  1127. */
  1128. function _element_validate_number($element, &$form_state) {
  1129. element_validate_number($element, $form_state);
  1130. }