field_test.field.inc 12 KB

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