tripal_fields.fields.inc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. <?php
  2. /**
  3. * Implements hook_field_info().
  4. */
  5. function tripal_fields_field_info() {
  6. $fields = array(
  7. 'organism_id' => array(
  8. 'label' => t('Organism'),
  9. 'description' => t('A field for specifying an organism.'),
  10. 'default_widget' => 'tripal_fields_organism_select_widget',
  11. 'default_formatter' => 'tripal_fields_organism_formatter',
  12. 'settings' => array(),
  13. 'storage' => array(
  14. 'type' => 'field_chado_storage',
  15. 'module' => 'tripal_fields',
  16. 'active' => TRUE
  17. ),
  18. ),
  19. 'dbxref_id' => array(
  20. 'label' => t('Cross-reference'),
  21. 'description' => t('This record can be cross-referenced with a record in another online database. This field is intended for the most prominent reference. At a minimum, the database and accession must be provided.'),
  22. 'default_widget' => 'tripal_fields_primary_dbxref_widget',
  23. 'default_formatter' => 'tripal_fields_primary_dbxref_formatter',
  24. 'settings' => array(),
  25. 'storage' => array(
  26. 'type' => 'field_chado_storage',
  27. 'module' => 'tripal_fields',
  28. 'active' => TRUE
  29. ),
  30. ),
  31. 'residues' => array(
  32. 'label' => t('Residues'),
  33. 'description' => t('A field for managing nucleotide and protein residues.'),
  34. 'default_widget' => 'tripal_fields_residue_textarea_widget',
  35. 'default_formatter' => 'tripal_fields_residues_formatter',
  36. 'settings' => array(),
  37. 'storage' => array(
  38. 'type' => 'field_chado_storage',
  39. 'module' => 'tripal_fields',
  40. 'active' => TRUE
  41. ),
  42. ),
  43. 'md5checksum' => array(
  44. 'label' => t('MD5 checksum'),
  45. 'description' => t('A field for generating MD5 checksum for a sequence.'),
  46. 'default_widget' => 'tripal_fields_md5checksum_checkbox_widget',
  47. 'default_formatter' => 'tripal_fields_md5checksum_formatter',
  48. 'settings' => array(),
  49. 'storage' => array(
  50. 'type' => 'field_chado_storage',
  51. 'module' => 'tripal_fields',
  52. 'active' => TRUE
  53. ),
  54. ),
  55. 'seqlen' => array(
  56. 'label' => t('Sequence length'),
  57. 'description' => t('A field for calculating the length of a sequence.'),
  58. 'default_widget' => 'tripal_fields_seqlen_hidden_widget',
  59. 'default_formatter' => 'tripal_fields_seqlen_formatter',
  60. 'settings' => array(),
  61. 'storage' => array(
  62. 'type' => 'field_chado_storage',
  63. 'module' => 'tripal_fields',
  64. 'active' => TRUE
  65. ),
  66. ),
  67. // The field provides a widget for adding new properties
  68. // to an entity that is connected to a base table that has a prop table
  69. // in Chado.
  70. 'kvproperty' => array(
  71. 'label' => t('Add a Property Type'),
  72. 'description' => t('This record may have any number of properties. Use this field to first add the type.'),
  73. 'default_widget' => 'tripal_fields_kvproperty_widget',
  74. 'default_formatter' => 'tripal_fields_kvproperty_formatter',
  75. 'settings' => array(),
  76. 'storage' => array(
  77. 'type' => 'field_chado_storage',
  78. 'module' => 'tripal_fields',
  79. 'active' => TRUE
  80. ),
  81. ),
  82. );
  83. return $fields;
  84. }
  85. /**
  86. * Implements hook_field_widget_info().
  87. */
  88. function tripal_fields_field_widget_info() {
  89. return array(
  90. 'tripal_fields_organism_select_widget' => array(
  91. 'label' => t('Organism Select'),
  92. 'field types' => array('organism_id')
  93. ),
  94. 'tripal_fields_primary_dbxref_widget' => array(
  95. 'label' => t('Cross-reference'),
  96. 'field types' => array('dbxref_id'),
  97. 'description' => t('This record can be cross-referenced with a record in another online database. This field is intended for the most prominent reference. At a minimum, the database and accession must be provided.'),
  98. ),
  99. 'tripal_fields_md5checksum_checkbox_widget' => array(
  100. 'label' => t('MD5 Checksum Checkbox'),
  101. 'field types' => array('md5checksum'),
  102. ),
  103. 'tripal_fields_residues_textarea_widget' => array(
  104. 'label' => t('Residues'),
  105. 'field types' => array('residues'),
  106. ),
  107. 'tripal_fields_seqlen_hidden_widget' => array(
  108. 'label' => t('Sequence Length'),
  109. 'field types' => array('seqlen'),
  110. ),
  111. 'tripal_fields_kvproperty_widget' => array(
  112. 'label' => t('Property'),
  113. 'field types' => array('kvproperty'),
  114. ),
  115. );
  116. }
  117. /**
  118. * Implements hook_field_formatter_info().
  119. */
  120. function tripal_fields_field_formatter_info() {
  121. return array(
  122. 'tripal_fields_organism_formatter' => array(
  123. 'label' => t('Organism'),
  124. 'field types' => array('organism_id')
  125. ),
  126. 'tripal_fields_primary_dbxref_formatter' => array(
  127. 'label' => t('Cross-reference'),
  128. 'field types' => array('dbxref_id')
  129. ),
  130. 'tripal_fields_md5checksum_formatter' => array(
  131. 'label' => t('MD5 checksum'),
  132. 'field types' => array('md5checksum')
  133. ),
  134. 'tripal_fields_residues_formatter' => array(
  135. 'label' => t('Residues'),
  136. 'field types' => array('residues')
  137. ),
  138. 'tripal_fields_seqlen_formatter' => array(
  139. 'label' => t('Sequence length'),
  140. 'field types' => array('seqlen')
  141. ),
  142. 'tripal_fields_kvproperty_formatter' => array(
  143. 'label' => t('Property'),
  144. 'field types' => array('kvproperty')
  145. ),
  146. );
  147. }
  148. /**
  149. * Implements hook_field_formatter_view().
  150. *
  151. * Two formatters are implemented.
  152. * - field_example_simple_text just outputs markup indicating the color that
  153. * was entered and uses an inline style to set the text color to that value.
  154. * - field_example_color_background does the same but also changes the
  155. * background color of div.region-content.
  156. *
  157. * @see field_example_field_formatter_info()
  158. */
  159. function tripal_fields_field_formatter_view($entity_type, $entity, $field,
  160. $instance, $langcode, $items, $display) {
  161. $element = array();
  162. switch ($display['type']) {
  163. case 'tripal_fields_organism_formatter':
  164. foreach ($items as $delta => $item) {
  165. $organism = chado_select_record('organism', array('genus', 'species'), array('organism_id' => $item['value']));
  166. // TODO: add hook here to allow other modules to change this display
  167. // if they want.
  168. $element[$delta] = array(
  169. // We create a render array to produce the desired markup,
  170. // "<p>Genus Species</p>".
  171. // See theme_html_tag().
  172. '#type' => 'markup',
  173. '#markup' => '<i>' . $organism[0]->genus .' ' . $organism[0]->species . '</i>',
  174. );
  175. }
  176. break;
  177. case 'tripal_fields_primary_dbxref_formatter':
  178. module_load_include('inc', 'tripal_fields', 'includes/tripal_fields/fields/primary_dbxref');
  179. $content = tripal_fields_primary_dbxref_formatter($entity_type, $entity, $field,
  180. $instance, $langcode, $items, $display);
  181. $element[$delta] = array(
  182. // We create a render array to produce the desired markup,
  183. '#type' => 'markup',
  184. '#markup' => $content,
  185. );
  186. break;
  187. case 'tripal_fields_md5checksum_formatter':
  188. module_load_include('inc', 'tripal_fields', 'includes/tripal_fields/fields/md5checksum');
  189. $content = tripal_fields_md5checksum_checkbox_formatter($entity_type, $entity, $field,
  190. $instance, $langcode, $items, $display);
  191. $element[$delta] = array(
  192. // We create a render array to produce the desired markup,
  193. '#type' => 'markup',
  194. '#markup' => $content,
  195. );
  196. break;
  197. case 'tripal_fields_residues_formatter':
  198. foreach ($items as $delta => $item) {
  199. // TODO: add hook here to allow other modules to change this display
  200. // if they want.
  201. $residues = key_exists('value', $item) ? $item['value'] : '';
  202. $element[$delta] = array(
  203. // We create a render array to produce the desired markup,
  204. '#type' => 'markup',
  205. '#markup' => '<pre>' . $residues . '</pre>',
  206. );
  207. }
  208. break;
  209. case 'tripal_fields_seqlen_formatter':
  210. foreach ($items as $delta => $item) {
  211. // TODO: add hook here to allow other modules to change this display
  212. // if they want.
  213. $element[$delta] = array(
  214. // We create a render array to produce the desired markup,
  215. '#type' => 'markup',
  216. '#markup' => key_exists('value', $item) ? $item['value'] : '',
  217. );
  218. }
  219. break;
  220. case 'tripal_fields_kvproperty_formatter':
  221. // Do nothing. This field is only used in the form.
  222. $element[$delta] = '';
  223. break;
  224. }
  225. return $element;
  226. }
  227. /**
  228. * Implements hook_field_widget_form().
  229. */
  230. function tripal_fields_field_widget_form(&$form, &$form_state, $field,
  231. $instance, $langcode, $items, $delta, $element) {
  232. $widget = $element;
  233. $widget['#delta'] = $delta;
  234. $field_name = $field['field_name'];
  235. switch ($instance['widget']['type']) {
  236. case 'tripal_fields_organism_select_widget':
  237. $options = tripal_get_organism_select_options();
  238. $widget += array(
  239. '#type' => 'select',
  240. '#title' => $element['#title'],
  241. '#description' => $element['#description'],
  242. '#options' => $options,
  243. '#default_value' => count($items) > 0 ? $items[0]['value'] : 0,
  244. '#required' => $element['#required'],
  245. '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
  246. '#delta' => $delta,
  247. '#element_validate' => array('tripal_fields_organism_select_widget_validate'),
  248. );
  249. $element['value'] = $widget;
  250. break;
  251. case 'tripal_fields_primary_dbxref_widget':
  252. // Make sure the include files get parsed now and for the form submits.
  253. form_load_include($form_state, 'inc', 'tripal_fields', 'includes/fields/primary_dbxref');
  254. module_load_include('inc', 'tripal_fields', 'includes/fields/primary_dbxref');
  255. // Update the widget with the new field.
  256. tripal_fields_primary_dbxref_widget($field_name, $widget, $form,
  257. $form_state, $field, $instance, $langcode, $items, $delta, $element);
  258. $element['value'] = $widget;
  259. break;
  260. case 'tripal_fields_md5checksum_checkbox_widget':
  261. form_load_include($form_state, 'inc', 'tripal_fields', 'includes/tripal_fields/fields/md5checksum');
  262. module_load_include('inc', 'tripal_fields', 'includes/tripal_fields/fields/md5checksum');
  263. tripal_fields_md5checksum_checkbox_widget($field_name, $widget,
  264. $form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
  265. $element['value'] = $widget;
  266. break;
  267. case 'tripal_fields_residues_textarea_widget':
  268. $widget += array(
  269. '#type' => 'textarea',
  270. '#title' => $element['#title'],
  271. '#description' => $element['#description'],
  272. '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
  273. '#default_value' => count($items) > 0 ? $items[0]['value'] : 0,
  274. '#delta' => $delta,
  275. '#element_validate' => array('tripal_fields_residues_textarea_widget_validate'),
  276. );
  277. $element['value'] = $widget;
  278. break;
  279. case 'tripal_fields_seqlen_hidden_widget':
  280. $widget += array(
  281. '#type' => 'hidden',
  282. '#title' => $element['#title'],
  283. '#description' => $element['#description'],
  284. '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
  285. '#delta' => $delta,
  286. '#element_validate' => array('tripal_fields_seqlen_hidden_widget_validate'),
  287. );
  288. $element['value'] = $widget;
  289. break;
  290. case 'tripal_fields_kvproperty_widget':
  291. $widget += array(
  292. '#element_validate' => array('tripal_fields_kvproperty_widget_validate'),
  293. '#type' => 'fieldset',
  294. '#title' => $element['#title'],
  295. '#description' => $element['#description'],
  296. '#weight' => isset($element['#weight']) ? $element['#weight'] : 0,
  297. '#delta' => $delta,
  298. '#group' => 'entity_vetical_tabs',
  299. array(
  300. 'kvproperty' => array(
  301. '#title' => t('Property Type'),
  302. '#type' => 'textfield',
  303. '#description' => t("Please enter the type of property that you want to add. As you type, suggestions will be provided."),
  304. '#autocomplete_path' => "eadmin/tripal/chado/tripal_cv/cvterm/auto_name/",
  305. ),
  306. 'kvproperty_add' => array(
  307. '#value' => t('Add fields for property type'),
  308. '#type' => 'button',
  309. '#name' => 'kvproperty_add',
  310. ),
  311. ),
  312. );
  313. $element['value'] = $widget;
  314. break;
  315. }
  316. return $element;
  317. }
  318. /**
  319. * Implements hook_field_is_empty().
  320. */
  321. function tripal_fields_field_is_empty($item, $field) {
  322. if (empty($item['value']) && (string) $item['value'] !== '0') {
  323. return TRUE;
  324. }
  325. return FALSE;
  326. }
  327. /**
  328. * Callback function for validating the tripal_fields_organism_select_widget.
  329. */
  330. function tripal_fields_organism_select_widget_validate($element, &$form_state) {
  331. $field_name = $element['#field_name'];
  332. // If the form ID is field_ui_field_edit_form, then the user is editing the
  333. // field's values in the manage fields form of Drupal. We don't want
  334. // to validate it as if it were being used in a data entry form.
  335. if ($form_state['build_info']['form_id'] =='field_ui_field_edit_form') {
  336. return;
  337. }
  338. $organism_id = tripal_fields_get_field_form_values($field_name, $form_state);
  339. if (count($organism_id) == 0) {
  340. form_error($element, t("Please specify an organism that already exists in the database."));
  341. }
  342. }
  343. /**
  344. * Callback function for validating the tripal_fields_kvproperty_widget.
  345. */
  346. function tripal_fields_kvproperty_widget_validate($element, &$form_state) {
  347. // Add the new field to the entity
  348. $form_state['rebuild'] = TRUE;
  349. }
  350. /**
  351. * Callback function for validating the tripal_fields_residues_textarea_widget.
  352. */
  353. function tripal_fields_residues_textarea_widget_validate($element, &$form_state) {
  354. $field_name = $element['#field_name'];
  355. // Remove any white spaces.
  356. $residues = tripal_fields_get_field_form_values($field_name, $form_state);
  357. if (count($residues) > 0) {
  358. $residues = preg_replace('/\s/', '', $residues[0]);
  359. tripal_fields_set_field_form_values($field_name, $form_state, $residues);
  360. }
  361. }
  362. /**
  363. * Callback function for validating the tripal_fields_seqlen_hidden_widget.
  364. */
  365. function tripal_fields_seqlen_hidden_widget_validate($element, &$form_state) {
  366. $field_name = $element['#field_name'];
  367. // Get the residues so we can calculate teh length.
  368. $residues = tripal_fields_get_field_form_values('feature__residues', $form_state);
  369. // Remove any white spaces.
  370. if (count($residues) > 0) {
  371. $residues = preg_replace('/\s/', '', $residues[0]);
  372. tripal_fields_set_field_form_values($field_name, $form_state, strlen($residues));
  373. }
  374. else {
  375. // Otherwise, remove the md5 value
  376. tripal_fields_set_field_form_values ($field_name, $form_state, '__NULL__');
  377. }
  378. }
  379. /**
  380. * Theme function for the primary_dbxref_widget.
  381. *
  382. * @param $variables
  383. */
  384. function theme_tripal_fields_primary_dbxref_widget($variables) {
  385. $element = $variables['element'];
  386. $layout = "
  387. <div class=\"primary-dbxref-widget\">
  388. <div class=\"primary-dbxref-widget-item\">" .
  389. drupal_render($element[0]['dbxref__db_id']) . "
  390. </div>
  391. <div class=\"primary-dbxref-widget-item\">" .
  392. drupal_render($element[0]['dbxref__accession']) . "
  393. </div>
  394. <div class=\"primary-dbxref-widget-item\">" .
  395. drupal_render($element[0]['dbxref__version']) . "
  396. </div>
  397. <div class=\"primary-dbxref-widget-item\">" .
  398. drupal_render($element[0]['dbxref__description']) . "
  399. </div>
  400. </div>
  401. ";
  402. return $layout;
  403. }
  404. /**
  405. * Returns the values of the field from the $form_state.
  406. */
  407. function tripal_fields_get_field_form_values($field_name, $form_state, $child = NULL) {
  408. $values = array();
  409. if (!array_key_exists('values', $form_state)) {
  410. return $values;
  411. }
  412. if (array_key_exists($field_name, $form_state['values'])) {
  413. foreach ($form_state['values'][$field_name] as $langcode => $items) {
  414. foreach ($items as $delta => $value) {
  415. if ($child and array_key_exists($child, $value['value'][0]) and $value['value'][0][$child]) {
  416. $values[] = $value['value'][0][$child];
  417. }
  418. else if (!$child and $value['value']) {
  419. $values[] = $value['value'];
  420. }
  421. }
  422. }
  423. }
  424. return $values;
  425. }
  426. /**
  427. * Returns the values of the field from the $form_state.
  428. */
  429. function tripal_fields_set_field_form_values($field_name, &$form_state, $newvalue, $child = NULL) {
  430. $values = array();
  431. foreach ($form_state['values'][$field_name] as $langcode => $items) {
  432. foreach ($items as $delta => $value) {
  433. if ($child and array_key_exists($child, $value['value'][0]) and $value['value'][0][$child]) {
  434. $form_state['values'][$field_name][$langcode][$delta]['value'][0][$child] = $newvalue;
  435. }
  436. else if (!$child) {
  437. $form_state['values'][$field_name][$langcode][$delta]['value'] = $newvalue;
  438. }
  439. }
  440. }
  441. return $values;
  442. }