field_test.field.inc

Defines a field type and its formatters and widgets.

File

drupal-7.x/modules/field/tests/field_test.field.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * Defines a field type and its formatters and widgets.
  5. */
  6. /**
  7. * Implements hook_field_info().
  8. */
  9. function field_test_field_info() {
  10. return array(
  11. 'test_field' => array(
  12. 'label' => t('Test field'),
  13. 'description' => t('Dummy field type used for tests.'),
  14. 'settings' => array(
  15. 'test_field_setting' => 'dummy test string',
  16. 'changeable' => 'a changeable field setting',
  17. 'unchangeable' => 'an unchangeable field setting',
  18. ),
  19. 'instance_settings' => array(
  20. 'test_instance_setting' => 'dummy test string',
  21. 'test_hook_field_load' => FALSE,
  22. ),
  23. 'default_widget' => 'test_field_widget',
  24. 'default_formatter' => 'field_test_default',
  25. ),
  26. 'shape' => array(
  27. 'label' => t('Shape'),
  28. 'description' => t('Another dummy field type.'),
  29. 'settings' => array(
  30. 'foreign_key_name' => 'shape',
  31. ),
  32. 'instance_settings' => array(),
  33. 'default_widget' => 'test_field_widget',
  34. 'default_formatter' => 'field_test_default',
  35. ),
  36. 'hidden_test_field' => array(
  37. 'no_ui' => TRUE,
  38. 'label' => t('Hidden from UI test field'),
  39. 'description' => t('Dummy hidden field type used for tests.'),
  40. 'settings' => array(),
  41. 'instance_settings' => array(),
  42. 'default_widget' => 'test_field_widget',
  43. 'default_formatter' => 'field_test_default',
  44. ),
  45. );
  46. }
  47. /**
  48. * Implements hook_field_update_forbid().
  49. */
  50. function field_test_field_update_forbid($field, $prior_field, $has_data) {
  51. if ($field['type'] == 'test_field' && $field['settings']['unchangeable'] != $prior_field['settings']['unchangeable']) {
  52. throw new FieldException("field_test 'unchangeable' setting cannot be changed'");
  53. }
  54. }
  55. /**
  56. * Implements hook_field_load().
  57. */
  58. function field_test_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
  59. $args = func_get_args();
  60. field_test_memorize(__FUNCTION__, $args);
  61. foreach ($items as $id => $item) {
  62. // To keep the test non-intrusive, only act for instances with the
  63. // test_hook_field_load setting explicitly set to TRUE.
  64. if ($instances[$id]['settings']['test_hook_field_load']) {
  65. foreach ($item as $delta => $value) {
  66. // Don't add anything on empty values.
  67. if ($value) {
  68. $items[$id][$delta]['additional_key'] = 'additional_value';
  69. }
  70. }
  71. }
  72. }
  73. }
  74. /**
  75. * Implements hook_field_insert().
  76. */
  77. function field_test_field_insert($entity_type, $entity, $field, $instance, $items) {
  78. $args = func_get_args();
  79. field_test_memorize(__FUNCTION__, $args);
  80. }
  81. /**
  82. * Implements hook_field_update().
  83. */
  84. function field_test_field_update($entity_type, $entity, $field, $instance, $items) {
  85. $args = func_get_args();
  86. field_test_memorize(__FUNCTION__, $args);
  87. }
  88. /**
  89. * Implements hook_field_delete().
  90. */
  91. function field_test_field_delete($entity_type, $entity, $field, $instance, $items) {
  92. $args = func_get_args();
  93. field_test_memorize(__FUNCTION__, $args);
  94. }
  95. /**
  96. * Implements hook_field_validate().
  97. *
  98. * Possible error codes:
  99. * - 'field_test_invalid': The value is invalid.
  100. */
  101. function field_test_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
  102. $args = func_get_args();
  103. field_test_memorize(__FUNCTION__, $args);
  104. foreach ($items as $delta => $item) {
  105. if ($item['value'] == -1) {
  106. $errors[$field['field_name']][$langcode][$delta][] = array(
  107. 'error' => 'field_test_invalid',
  108. 'message' => t('%name does not accept the value -1.', array('%name' => $instance['label'])),
  109. );
  110. }
  111. }
  112. }
  113. /**
  114. * Implements hook_field_is_empty().
  115. */
  116. function field_test_field_is_empty($item, $field) {
  117. return empty($item['value']);
  118. }
  119. /**
  120. * Implements hook_field_settings_form().
  121. */
  122. function field_test_field_settings_form($field, $instance, $has_data) {
  123. $settings = $field['settings'];
  124. $form['test_field_setting'] = array(
  125. '#type' => 'textfield',
  126. '#title' => t('Field test field setting'),
  127. '#default_value' => $settings['test_field_setting'],
  128. '#required' => FALSE,
  129. '#description' => t('A dummy form element to simulate field setting.'),
  130. );
  131. return $form;
  132. }
  133. /**
  134. * Implements hook_field_instance_settings_form().
  135. */
  136. function field_test_field_instance_settings_form($field, $instance) {
  137. $settings = $instance['settings'];
  138. $form['test_instance_setting'] = array(
  139. '#type' => 'textfield',
  140. '#title' => t('Field test field instance setting'),
  141. '#default_value' => $settings['test_instance_setting'],
  142. '#required' => FALSE,
  143. '#description' => t('A dummy form element to simulate field instance setting.'),
  144. );
  145. return $form;
  146. }
  147. /**
  148. * Implements hook_field_widget_info().
  149. */
  150. function field_test_field_widget_info() {
  151. return array(
  152. 'test_field_widget' => array(
  153. 'label' => t('Test field'),
  154. 'field types' => array('test_field', 'hidden_test_field'),
  155. 'settings' => array('test_widget_setting' => 'dummy test string'),
  156. ),
  157. 'test_field_widget_multiple' => array(
  158. 'label' => t('Test field 1'),
  159. 'field types' => array('test_field'),
  160. 'settings' => array('test_widget_setting_multiple' => 'dummy test string'),
  161. 'behaviors' => array(
  162. 'multiple values' => FIELD_BEHAVIOR_CUSTOM,
  163. ),
  164. ),
  165. );
  166. }
  167. /**
  168. * Implements hook_field_widget_form().
  169. */
  170. function field_test_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  171. switch ($instance['widget']['type']) {
  172. case 'test_field_widget':
  173. $element += array(
  174. '#type' => 'textfield',
  175. '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : '',
  176. );
  177. return array('value' => $element);
  178. case 'test_field_widget_multiple':
  179. $values = array();
  180. foreach ($items as $delta => $value) {
  181. $values[] = $value['value'];
  182. }
  183. $element += array(
  184. '#type' => 'textfield',
  185. '#default_value' => implode(', ', $values),
  186. '#element_validate' => array('field_test_widget_multiple_validate'),
  187. );
  188. return $element;
  189. }
  190. }
  191. /**
  192. * Form element validation handler for 'test_field_widget_multiple' widget.
  193. */
  194. function field_test_widget_multiple_validate($element, &$form_state) {
  195. $values = array_map('trim', explode(',', $element['#value']));
  196. $items = array();
  197. foreach ($values as $value) {
  198. $items[] = array('value' => $value);
  199. }
  200. form_set_value($element, $items, $form_state);
  201. }
  202. /**
  203. * Implements hook_field_widget_error().
  204. */
  205. function field_test_field_widget_error($element, $error, $form, &$form_state) {
  206. // @todo No easy way to differenciate widget types, we should receive it as a
  207. // parameter.
  208. if (isset($element['value'])) {
  209. // Widget is test_field_widget.
  210. $error_element = $element['value'];
  211. }
  212. else {
  213. // Widget is test_field_widget_multiple.
  214. $error_element = $element;
  215. }
  216. form_error($error_element, $error['message']);
  217. }
  218. /**
  219. * Implements hook_field_widget_settings_form().
  220. */
  221. function field_test_field_widget_settings_form($field, $instance) {
  222. $widget = $instance['widget'];
  223. $settings = $widget['settings'];
  224. $form['test_widget_setting'] = array(
  225. '#type' => 'textfield',
  226. '#title' => t('Field test field widget setting'),
  227. '#default_value' => $settings['test_widget_setting'],
  228. '#required' => FALSE,
  229. '#description' => t('A dummy form element to simulate field widget setting.'),
  230. );
  231. return $form;
  232. }
  233. /**
  234. * Implements hook_field_formatter_info().
  235. */
  236. function field_test_field_formatter_info() {
  237. return array(
  238. 'field_test_default' => array(
  239. 'label' => t('Default'),
  240. 'description' => t('Default formatter'),
  241. 'field types' => array('test_field'),
  242. 'settings' => array(
  243. 'test_formatter_setting' => 'dummy test string',
  244. ),
  245. ),
  246. 'field_test_multiple' => array(
  247. 'label' => t('Multiple'),
  248. 'description' => t('Multiple formatter'),
  249. 'field types' => array('test_field'),
  250. 'settings' => array(
  251. 'test_formatter_setting_multiple' => 'dummy test string',
  252. ),
  253. ),
  254. 'field_test_with_prepare_view' => array(
  255. 'label' => t('Tests hook_field_formatter_prepare_view()'),
  256. 'field types' => array('test_field'),
  257. 'settings' => array(
  258. 'test_formatter_setting_additional' => 'dummy test string',
  259. ),
  260. ),
  261. );
  262. }
  263. /**
  264. * Implements hook_field_formatter_settings_form().
  265. */
  266. function field_test_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  267. $display = $instance['display'][$view_mode];
  268. $settings = $display['settings'];
  269. $element = array();
  270. // The name of the setting depends on the formatter type.
  271. $map = array(
  272. 'field_test_default' => 'test_formatter_setting',
  273. 'field_test_multiple' => 'test_formatter_setting_multiple',
  274. 'field_test_with_prepare_view' => 'test_formatter_setting_additional',
  275. );
  276. if (isset($map[$display['type']])) {
  277. $name = $map[$display['type']];
  278. $element[$name] = array(
  279. '#title' => t('Setting'),
  280. '#type' => 'textfield',
  281. '#size' => 20,
  282. '#default_value' => $settings[$name],
  283. '#required' => TRUE,
  284. );
  285. }
  286. return $element;
  287. }
  288. /**
  289. * Implements hook_field_formatter_settings_summary().
  290. */
  291. function field_test_field_formatter_settings_summary($field, $instance, $view_mode) {
  292. $display = $instance['display'][$view_mode];
  293. $settings = $display['settings'];
  294. $summary = '';
  295. // The name of the setting depends on the formatter type.
  296. $map = array(
  297. 'field_test_default' => 'test_formatter_setting',
  298. 'field_test_multiple' => 'test_formatter_setting_multiple',
  299. 'field_test_with_prepare_view' => 'test_formatter_setting_additional',
  300. );
  301. if (isset($map[$display['type']])) {
  302. $name = $map[$display['type']];
  303. $summary = t('@setting: @value', array('@setting' => $name, '@value' => $settings[$name]));
  304. }
  305. return $summary;
  306. }
  307. /**
  308. * Implements hook_field_formatter_prepare_view().
  309. */
  310. function field_test_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
  311. foreach ($items as $id => $item) {
  312. // To keep the test non-intrusive, only act on the
  313. // 'field_test_with_prepare_view' formatter.
  314. if ($displays[$id]['type'] == 'field_test_with_prepare_view') {
  315. foreach ($item as $delta => $value) {
  316. // Don't add anything on empty values.
  317. if ($value) {
  318. $items[$id][$delta]['additional_formatter_value'] = $value['value'] + 1;
  319. }
  320. }
  321. }
  322. }
  323. }
  324. /**
  325. * Implements hook_field_formatter_view().
  326. */
  327. function field_test_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  328. $element = array();
  329. $settings = $display['settings'];
  330. switch ($display['type']) {
  331. case 'field_test_default':
  332. foreach ($items as $delta => $item) {
  333. $element[$delta] = array('#markup' => $settings['test_formatter_setting'] . '|' . $item['value']);
  334. }
  335. break;
  336. case 'field_test_with_prepare_view':
  337. foreach ($items as $delta => $item) {
  338. $element[$delta] = array('#markup' => $settings['test_formatter_setting_additional'] . '|' . $item['value'] . '|' . $item['additional_formatter_value']);
  339. }
  340. break;
  341. case 'field_test_multiple':
  342. if (!empty($items)) {
  343. $array = array();
  344. foreach ($items as $delta => $item) {
  345. $array[] = $delta . ':' . $item['value'];
  346. }
  347. $element[0] = array('#markup' => $settings['test_formatter_setting_multiple'] . '|' . implode('|', $array));
  348. }
  349. break;
  350. }
  351. return $element;
  352. }
  353. /**
  354. * Sample 'default value' callback.
  355. */
  356. function field_test_default_value($entity_type, $entity, $field, $instance) {
  357. return array(array('value' => 99));
  358. }
  359. /**
  360. * Implements hook_field_access().
  361. */
  362. function field_test_field_access($op, $field, $entity_type, $entity, $account) {
  363. if ($field['field_name'] == "field_no_{$op}_access") {
  364. return FALSE;
  365. }
  366. return TRUE;
  367. }