tripal_chado.fields.inc 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192
  1. <?php
  2. /**
  3. * Implements hook_field_info().
  4. *
  5. * TODO: move these array elements to a hook function that
  6. * is implemented in the field file. This will put all of the
  7. * field info in a single place for each field. See the formatter_info()
  8. * function for an example.
  9. */
  10. function tripal_chado_field_info() {
  11. $fields = array(
  12. /*
  13. * Generic fields that support multiple base tables.
  14. */
  15. 'chado_base__organism_id' => array(
  16. 'label' => t('Organism'),
  17. 'description' => t('A field for specifying an organism.'),
  18. 'default_widget' => 'chado_base__organism_id_widget',
  19. 'default_formatter' => 'chado_base__organism_id_formatter',
  20. 'settings' => array(),
  21. 'storage' => array(
  22. 'type' => 'field_chado_storage',
  23. 'module' => 'tripal_chado',
  24. 'active' => TRUE
  25. ),
  26. ),
  27. 'chado_base__dbxref_id' => array(
  28. 'label' => t('Cross reference'),
  29. 'description' => t('This record can be cross referenced with a record in
  30. another online database. This field is intended for the most prominent
  31. reference. At a minimum, the database and accession must be provided.'),
  32. 'default_widget' => 'chado_base__dbxref_id_widget',
  33. 'default_formatter' => 'chado_base__dbxref_id_formatter',
  34. 'settings' => array(),
  35. 'storage' => array(
  36. 'type' => 'field_chado_storage',
  37. 'module' => 'tripal_chado',
  38. 'active' => TRUE
  39. ),
  40. ),
  41. /*
  42. * Fields that support linker tables.
  43. */
  44. 'chado_linker__cvterm' => array(
  45. 'label' => t('Annotations'),
  46. 'description' => t('This record can be annotated with terms
  47. from other vocabularies.'),
  48. 'default_widget' => 'chado_linker__cvterm_widget',
  49. 'default_formatter' => 'chado_linker__cvterm_formatter',
  50. 'settings' => array(),
  51. 'storage' => array(
  52. 'type' => 'field_chado_storage',
  53. 'module' => 'tripal_chado',
  54. 'active' => TRUE
  55. ),
  56. ),
  57. 'chado_linker__synonym' => array(
  58. 'label' => t('Synonyms'),
  59. 'description' => t('Adds an alternative name (synonym or alias) to this record.'),
  60. 'default_widget' => 'chado_linker__synonym_widget',
  61. 'default_formatter' => 'chado_linker__synonym_formatter',
  62. 'settings' => array(),
  63. 'storage' => array(
  64. 'type' => 'field_chado_storage',
  65. 'module' => 'tripal_chado',
  66. 'active' => TRUE
  67. ),
  68. ),
  69. 'chado_linker__prop' => array(
  70. 'label' => t('Add a Property'),
  71. 'description' => t('Add details about this property.'),
  72. 'default_widget' => 'chado_linker__prop_widget',
  73. 'default_formatter' => 'chado_linker__prop_formatter',
  74. 'settings' => array(),
  75. 'storage' => array(
  76. 'type' => 'field_chado_storage',
  77. 'module' => 'tripal_chado',
  78. 'active' => TRUE
  79. ),
  80. ),
  81. 'chado_linker__dbxref' => array(
  82. 'label' => t('Cross references'),
  83. 'description' => t('This record can be cross referenced with a record in
  84. another online database. This field is intended for one or more
  85. references. At a minimum, the database and accession must be provided.'),
  86. 'default_widget' => 'chado_linker__dbxref_widget',
  87. 'default_formatter' => 'chado_linker__dbxref_formatter',
  88. 'settings' => array(),
  89. 'storage' => array(
  90. 'type' => 'field_chado_storage',
  91. 'module' => 'tripal_chado',
  92. 'active' => TRUE
  93. ),
  94. ),
  95. 'chado_linker__pub' => array(
  96. 'label' => t('Publications'),
  97. 'description' => t('Associates a publication (e.g. journal article,
  98. conference proceedings, book chapter, etc.) with this record.'),
  99. 'default_widget' => 'chado_linker__pub_widget',
  100. 'default_formatter' => 'chado_linker__pub_formatter',
  101. 'settings' => array(),
  102. 'storage' => array(
  103. 'type' => 'field_chado_storage',
  104. 'module' => 'tripal_chado',
  105. 'active' => TRUE
  106. ),
  107. ),
  108. /*
  109. * Fields that add new fields. These fields are not shown on
  110. * pages. They are avaiable to site curators when adding/updating
  111. * a record and allow the user to add new linker table fields.
  112. */
  113. 'chado_linker__prop_adder' => array(
  114. 'label' => t('Add a Property Type'),
  115. 'description' => t('This record may have any number of properties. Use
  116. this field to first add the type.'),
  117. 'default_widget' => 'chado_linker__prop_adder_widget',
  118. 'default_formatter' => 'hidden',
  119. 'settings' => array(),
  120. 'storage' => array(
  121. 'type' => 'field_chado_storage',
  122. 'module' => 'tripal_chado',
  123. 'active' => TRUE
  124. ),
  125. ),
  126. // The field provides a widget for adding new vocabularies for cvterm
  127. // linker tables. This will allow cvterms to be grouped by vocabulary
  128. // ('category').
  129. 'chado_linker__cvterm_adder' => array(
  130. 'label' => t('Add an Annotation Type'),
  131. 'description' => t('This record may have any number of types of
  132. annotations. Use this field to first add the type.'),
  133. 'default_widget' => 'chado_linker__cvterm_adder_widget',
  134. 'default_formatter' => 'hidden',
  135. 'settings' => array(),
  136. 'storage' => array(
  137. 'type' => 'field_chado_storage',
  138. 'module' => 'tripal_chado',
  139. 'active' => TRUE
  140. ),
  141. ),
  142. /*
  143. * Field specific to the feature table of Chado.
  144. */
  145. 'chado_feature__residues' => array(
  146. 'label' => t('Residues'),
  147. 'description' => t('A field for managing nucleotide and protein residues.'),
  148. 'default_widget' => 'chado_feature__residues_widget',
  149. 'default_formatter' => 'chado_feature__residues_formatter',
  150. 'settings' => array(),
  151. 'storage' => array(
  152. 'type' => 'field_chado_storage',
  153. 'module' => 'tripal_chado',
  154. 'active' => TRUE
  155. ),
  156. ),
  157. 'chado_feature__md5checksum' => array(
  158. 'label' => t('MD5 checksum'),
  159. 'description' => t('A field for generating MD5 checksum for a sequence.'),
  160. 'default_widget' => 'chado_feature__md5checksum_widget',
  161. 'default_formatter' => 'chado_feature__md5checksum_formatter',
  162. 'settings' => array(),
  163. 'storage' => array(
  164. 'type' => 'field_chado_storage',
  165. 'module' => 'tripal_chado',
  166. 'active' => TRUE
  167. ),
  168. ),
  169. 'chado_feature__seqlen' => array(
  170. 'label' => t('Sequence length'),
  171. 'description' => t('A field for calculating the length of a sequence.'),
  172. 'default_widget' => 'chado_feature__seqlen_widget',
  173. 'default_formatter' => 'chado_feature__seqlen_formatter',
  174. 'settings' => array(),
  175. 'storage' => array(
  176. 'type' => 'field_chado_storage',
  177. 'module' => 'tripal_chado',
  178. 'active' => TRUE
  179. ),
  180. ),
  181. );
  182. return $fields;
  183. }
  184. /**
  185. * Implements hook_field_widget_info().
  186. *
  187. * TODO: move these array elements to a hook function that
  188. * is implemented in the field file. This will put all of the
  189. * field info in a single place for each field. See the formatter_info()
  190. * function for an example.
  191. */
  192. function tripal_chado_field_widget_info() {
  193. return array(
  194. /*
  195. * Generic fields that support multiple base tables.
  196. */
  197. 'chado_base__organism_id_widget' => array(
  198. 'label' => t('Organism Select'),
  199. 'field types' => array('chado_base__organism_id')
  200. ),
  201. 'chado_base__dbxref_id_widget' => array(
  202. 'label' => t('Cross reference'),
  203. 'field types' => array('chado_base__dbxref_id'),
  204. 'description' => t('This record can be cross referenced with a record in
  205. another online database. This field is intended for the most
  206. prominent reference. At a minimum, the database and accession
  207. must be provided.'),
  208. ),
  209. /*
  210. * Fields that support linker tables.
  211. */
  212. 'chado_linker__pub_widget' => array(
  213. 'label' => t('Publications'),
  214. 'field types' => array('chado_linker__pub'),
  215. ),
  216. 'chado_linker__dbxref_widget' => array(
  217. 'label' => t('Cross references'),
  218. 'field types' => array('chado_linker__dbxref'),
  219. 'description' => t('This record can be cross referenced with a record
  220. in another online database. This field is intended for the most
  221. prominent reference. At a minimum, the database and accession
  222. must be provided.'),
  223. ),
  224. 'chado_linker__cvterm_widget' => array(
  225. 'label' => t('Annotations'),
  226. 'field types' => array('chado_linker__cvterm'),
  227. 'description' => t('This record can be annotated with terms
  228. from other vocabularies.'),
  229. ),
  230. 'chado_linker__prop_widget' => array(
  231. 'label' => t('Property'),
  232. 'field types' => array('chado_linker__prop'),
  233. ),
  234. 'chado_linker__synonym_widget' => array(
  235. 'label' => t('Synonyms'),
  236. 'field types' => array('chado_linker__synonym'),
  237. ),
  238. /*
  239. * Fields that add new fields. These fields are not shown on
  240. * pages. They are avaiable to site curators when adding/updating
  241. * a record and allow the user to add new linker table fields.
  242. */
  243. 'chado_linker__prop_adder_widget' => array(
  244. 'label' => t('Add a Property'),
  245. 'field types' => array('chado_linker__prop_adder'),
  246. ),
  247. 'chado_linker__cvterm_adder_widget' => array(
  248. 'label' => t('Add an Annotation'),
  249. 'field types' => array('chado_linker__cvterm_adder'),
  250. ),
  251. /*
  252. * Field specific to the feature table of Chado.
  253. */
  254. 'chado_feature__md5checksum_widget' => array(
  255. 'label' => t('MD5 Checksum Checkbox'),
  256. 'field types' => array('chado_feature__md5checksum'),
  257. ),
  258. 'chado_feature__residues_widget' => array(
  259. 'label' => t('Residues'),
  260. 'field types' => array('chado_feature__residues'),
  261. ),
  262. 'chado_feature__seqlen_widget' => array(
  263. 'label' => t('Sequence Length'),
  264. 'field types' => array('chado_feature__seqlen'),
  265. ),
  266. );
  267. }
  268. /**
  269. * Implements hook_field_formatter_info().
  270. */
  271. function tripal_chado_field_formatter_info() {
  272. $formatters = array();
  273. $fields = field_info_fields();
  274. foreach ($fields as $field) {
  275. $field_type = $field['type'];
  276. if ($field['storage']['type'] == 'field_chado_storage') {
  277. module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
  278. $function = $field_type . '_formatter_info';
  279. if (function_exists($function)) {
  280. $formatters[$field_type . '_formatter'] = $function();
  281. }
  282. }
  283. }
  284. return $formatters;
  285. }
  286. /**
  287. * Implements hook_field_formatter_settings_summary().
  288. */
  289. function tripal_chado_field_formatter_settings_summary($field, $instance, $view_mode) {
  290. $summary = '';
  291. $field_type = $field['type'];
  292. module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
  293. $function = $field_type . '_formatter_settings_summary';
  294. if (function_exists($function)) {
  295. $summary = $function($field, $instance, $view_mode);
  296. }
  297. return $summary;
  298. }
  299. /**
  300. * Implements hook_field_formatter_settings_form().
  301. */
  302. function tripal_chado_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  303. $element = array();
  304. $field_type = $field['type'];
  305. form_load_include($form_state, 'inc', 'tripal_chado', 'includes/fields/' . $field_type);
  306. module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
  307. $function = $field_type . '_formatter_settings_form';
  308. if (function_exists($function)) {
  309. $element = $function($field, $instance, $view_mode, $form, $form_state);
  310. }
  311. return $element;
  312. }
  313. /**
  314. * Implements hook_field_formatter_view().
  315. */
  316. function tripal_chado_field_formatter_view($entity_type, $entity, $field,
  317. $instance, $langcode, $items, $display) {
  318. $element = array();
  319. $field_type = $field['type'];
  320. module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_type);
  321. $function = $display['type'];
  322. if (function_exists($function)) {
  323. $function($element, $entity_type, $entity, $field, $instance, $langcode, $items, $display);
  324. }
  325. return $element;
  326. }
  327. /**
  328. * Implements hook_field_widget_form().
  329. */
  330. function tripal_chado_field_widget_form(&$form, &$form_state, $field,
  331. $instance, $langcode, $items, $delta, $element) {
  332. $widget = $element;
  333. $field_name = $instance['field_name'];
  334. $field_type = $field['type'];
  335. form_load_include($form_state, 'inc', 'tripal_chado', 'includes/fields/' . $field_type);
  336. module_load_include('inc', 'tripal_chado', 'includes/fields/' . $field_name);
  337. $function = $field_type . '_widget';
  338. if (function_exists($function)) {
  339. $function($widget, $form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
  340. }
  341. return $widget;
  342. }
  343. /**
  344. * Returns the values of the field from the $form_state.
  345. */
  346. function tripal_chado_get_field_form_values($field_name, $form_state, $delta = 0, $child = NULL) {
  347. $value = NULL;
  348. // The form_state must have the 'values' key. If not then just return.
  349. if (!array_key_exists('values', $form_state)) {
  350. return $value;
  351. }
  352. // If the field name is not in the form_state['values'] then return.
  353. if (!array_key_exists($field_name, $form_state['values'])) {
  354. return $value;
  355. }
  356. // Iterate through the values looking for the field_name provided.
  357. foreach ($form_state['values'][$field_name] as $langcode => $items) {
  358. if (!array_key_exists($delta, $items)) {
  359. continue;
  360. }
  361. $item = $items[$delta];
  362. if ($child){
  363. if(array_key_exists($child, $item) and $item[$child] != '') {
  364. $value = $item[$child];
  365. }
  366. }
  367. else {
  368. $value = $item['value'];
  369. }
  370. }
  371. return $value;
  372. }
  373. /**
  374. * Sets the values of the field from the $form_state.
  375. */
  376. function tripal_chado_set_field_form_values($field_name, &$form_state, $newvalue, $delta = 0, $child = NULL) {
  377. // The form_state must have the 'values' key. If not then just return.
  378. if (!array_key_exists('values', $form_state)) {
  379. return FALSE;
  380. }
  381. // If the field name is not in the form_state['values'] then reutrn.
  382. if (!array_key_exists($field_name, $form_state['values'])) {
  383. return FALSE;
  384. }
  385. foreach ($form_state['values'][$field_name] as $langcode => $items) {
  386. if ($child) {
  387. $form_state['values'][$field_name][$langcode][$delta][$child] = $newvalue;
  388. }
  389. else {
  390. $form_state['values'][$field_name][$langcode][$delta]['value'] = $newvalue;
  391. }
  392. }
  393. return TRUE;
  394. }
  395. /**
  396. * Implements hook_field_widget_form_alter().
  397. */
  398. function tripal_chado_field_widget_form_alter(&$element, &$form_state, $context) {
  399. if (array_key_exists('#field_name', $element)) {
  400. $field_name = $element['#field_name'];
  401. $matches = array();
  402. if (preg_match('/(.+?)__(.+?)$/', $field_name, $matches)) {
  403. $tablename = $matches[1];
  404. $colname = $matches[2];
  405. $schema = chado_get_schema($tablename);
  406. // The timelastmodified field exists in many Chado tables. We want
  407. // the form element to update to the most recent time rather than the time
  408. // in the database.
  409. if ($colname == 'timelastmodified' and $schema['fields'][$colname]['type'] == 'datetime') {
  410. // We want the default value for the field to be the current time.
  411. $element['#default_value']['value'] = format_date(time(), 'custom', "Y-m-d H:i:s", 'UTC');
  412. $element['#date_items']['value'] = $element['#default_value']['value'];
  413. }
  414. // We want the date combo fieldset to be collaspible so we will
  415. // add our own theme_wrapper to replace the one added by the date
  416. // module.
  417. if (array_key_exists($colname, $schema['fields']) and $schema['fields'][$colname]['type'] == 'datetime') {
  418. $element['#theme_wrappers'] = array('tripal_chado_date_combo');
  419. }
  420. }
  421. }
  422. }
  423. /**
  424. * Returns a $field_info array for a field based on a database column.
  425. *
  426. */
  427. function tripal_chado_add_bundle_fields_base__fields_defaults($table_name, $schema, $column_name) {
  428. $details = $schema['fields'][$column_name];
  429. // Create an array with information about this field.
  430. $field = array(
  431. 'field_type' => '',
  432. 'widget_type' => '',
  433. 'description' => '',
  434. 'label' => ucwords(preg_replace('/_/', ' ', $column_name)),
  435. 'is_required' => 0,
  436. 'storage' => 'field_chado_storage',
  437. 'widget_settings' => array(
  438. 'display_label' => 1
  439. ),
  440. 'field_settings' => array(
  441. // The table in Chado where this field maps to.
  442. 'chado_table' => $table_name,
  443. // The column in the Chado table that this field maps to.
  444. 'chado_column' => $column_name,
  445. 'semantic_web' => array(
  446. // The type is the term from a vocabulary that desribes this field..
  447. 'type' => '',
  448. // The namepsace for the vocabulary (e.g. 'foaf').
  449. 'ns' => '',
  450. // The URL for the namespace. It must be that the type can be
  451. // appended to the URL.
  452. 'nsurl' => '',
  453. ),
  454. ),
  455. );
  456. // Alter the field info array depending on the column details.
  457. switch($details['type']) {
  458. case 'char':
  459. $field['field_type'] = 'text';
  460. $field['widget_type'] = 'text_textfield';
  461. $field['field_settings']['max_length'] = $details['length'];
  462. break;
  463. case 'varchar':
  464. $field['field_type'] = 'text';
  465. $field['widget_type'] = 'text_textfield';
  466. $field['field_settings']['max_length'] = $details['length'];
  467. break;
  468. case 'text':
  469. $field['field_type'] = 'text';
  470. $field['widget_type'] = 'text_textarea';
  471. $field['field_settings']['max_length'] = 17179869184;
  472. $field['field_settings']['text_processing'] = 1;
  473. $field['format'] = filter_default_format();
  474. break;
  475. case 'blob':
  476. // not sure how to support a blob field.
  477. continue;
  478. break;
  479. case 'int':
  480. $field['field_type'] = 'number_integer';
  481. $field['widget_type'] = 'number';
  482. break;
  483. case 'float':
  484. $field['field_type'] = 'number_float';
  485. $field['widget_type'] = 'number';
  486. $field['field_settings']['precision'] = 10;
  487. $field['field_settings']['scale'] = 2;
  488. $field['field_settings']['decimal_separator'] = '.';
  489. break;
  490. case 'numeric':
  491. $field['field_type'] = 'number_decimal';
  492. $field['widget_type'] = 'number';
  493. break;
  494. case 'serial':
  495. // Serial fields are most likely not needed as a field.
  496. break;
  497. case 'boolean':
  498. $field['field_type'] = 'list_boolean';
  499. $field['widget_type'] = 'options_onoff';
  500. $field['field_settings']['allowed_values'] = array(0 => "No", 1 => "Yes");
  501. break;
  502. case 'datetime':
  503. // Use the Drupal Date and Date API to create the field/widget
  504. $field['field_type'] = 'datetime';
  505. $field['widget_type'] = 'date_select';
  506. $field['widget_settings']['increment'] = 1;
  507. $field['widget_settings']['tz_handling'] = 'none';
  508. $field['widget_settings']['collapsible'] = TRUE;
  509. // TODO: Add settings so that the minutes increment by 1.
  510. // And turn off the timezone, as the Chado field doesn't support it.
  511. break;
  512. }
  513. // Set some default semantic web information
  514. if ($column_name == 'name') {
  515. $field['field_settings']['semantic_web']['type'] = 'name';
  516. $field['field_settings']['semantic_web']['ns'] = 'foaf';
  517. $field['field_settings']['semantic_web']['nsurl'] = 'http://xmlns.com/foaf/0.1/';
  518. }
  519. if ($column_name == 'description' or $column_name == 'definition' or
  520. $column_name == 'comment') {
  521. $field['field_settings']['semantic_web']['type'] = 'description';
  522. $field['field_settings']['semantic_web']['ns'] = 'hydra';
  523. $field['field_settings']['semantic_web']['nsurl'] = 'http://www.w3.org/ns/hydra/core#';
  524. }
  525. //
  526. // GENERIC COLUMNS
  527. //
  528. if ($field['field_settings']['chado_column'] == 'organism_id') {
  529. $field['field_type'] = 'chado_base__organism_id';
  530. $field['widget_type'] = 'chado_base__organism_id_widget';
  531. $field['label'] = 'Organism';
  532. $field['description'] = 'Select an organism.';
  533. $field['field_settings']['semantic_web']['type'] = 'organism';
  534. $field['field_settings']['semantic_web']['ns'] = 'local';
  535. $field['field_settings']['semantic_web']['nsurl'] = '';
  536. }
  537. elseif ($field['field_settings']['chado_column'] =='dbxref_id') {
  538. $field['field_type'] = 'chado_base__dbxref_id';
  539. $field['widget_type'] = 'chado_base_dbxref_id_widget';
  540. $field['label'] = 'Cross Reference';
  541. $field['description'] = 'This record can be cross referenced with a ' .
  542. 'record in another online database. The primary reference is for the ' .
  543. 'most prominent reference. At a minimum, the database and accession ' .
  544. 'must be provided. To remove a set reference, change the database ' .
  545. 'field to "Select a Database".';
  546. }
  547. elseif ($field['label'] == 'Timeaccessioned') {
  548. $field['label'] = 'Time Accessioned';
  549. $field['description'] = 'Please enter the time that this record was first added to the database.';
  550. }
  551. elseif ($field['label'] == 'Timelastmodified') {
  552. $field['label'] = 'Time Last Modified';
  553. $field['description'] = 'Please enter the time that this record was last modified. The default is the current time.';
  554. }
  555. //
  556. // ORGANISM TABLE
  557. //
  558. elseif ($field['field_settings']['chado_table'] == 'organism' and $field['field_settings']['chado_column'] == 'comment') {
  559. $field['label'] = 'Description';
  560. }
  561. //
  562. // FEATURE TABLE
  563. //
  564. elseif ($field['field_settings']['chado_table'] == 'feature' and $field['field_settings']['chado_column'] == 'uniquename') {
  565. $field['field_type'] = 'text';
  566. $field['widget_type'] = 'text_textfield';
  567. $field['field_settings']['text_processing'] = 0;
  568. $field['field_settings']['semantic_web']['type'] = 'name';
  569. $field['field_settings']['semantic_web']['ns'] = 'foaf';
  570. $field['field_settings']['semantic_web']['nsurl'] = 'http://xmlns.com/foaf/0.1/';
  571. }
  572. elseif ($field['field_settings']['chado_table'] == 'feature' and $field['field_settings']['chado_column'] == 'md5checksum') {
  573. $field['field_type'] = 'chado_feature__md5checksum';
  574. $field['widget_type'] = 'chado_feature__md5checksum_widget';
  575. $field['label'] = 'MD5 Checksum';
  576. $field['description'] = 'Generate an MD5 checksum for the sequence.';
  577. }
  578. elseif ($field['field_settings']['chado_table'] == 'feature' and $field['field_settings']['chado_column'] == 'seqlen') {
  579. $field['field_type'] = 'chado_feature__seqlen';
  580. $field['widget_type'] = 'chado_feature__seqlen_widget';
  581. $field['label'] = 'Seqlen';
  582. $field['description'] = 'The length of the residues.';
  583. }
  584. elseif ($field['field_settings']['chado_table'] == 'feature' and $field['field_settings']['chado_column'] == 'residues') {
  585. $field['field_type'] = 'chado_feature__residues';
  586. $field['widget_type'] = 'chado_feature__residues_widget';
  587. $field['label'] = 'Residues';
  588. $field['description'] = 'Please provide an IUPAC compatible residues for this feature. Spaces and new lines are allowed.';
  589. }
  590. //
  591. // ANALYSIS TABLE
  592. //
  593. elseif ($field['field_settings']['chado_table'] == 'analysis' and $field['field_settings']['chado_column'] == 'program') {
  594. $field['field_settings']['semantic_web']['type'] = 'SoftwareApplication';
  595. $field['field_settings']['semantic_web']['ns'] = 'schema';
  596. $field['field_settings']['semantic_web']['nsurl'] = 'https://schema.org/';
  597. $field['description'] = 'The program name (e.g. blastx, blastp, sim4, genscan. If the analysis was not derived from a software package then provide a very brief description of the pipeline, workflow or method.';
  598. $field['label'] = 'Program, Pipeline, Workflow or Method Name.';
  599. }
  600. elseif ($field['field_settings']['chado_table'] == 'analysis' and $field['field_settings']['chado_column'] == 'sourceuri') {
  601. $field['field_type'] = 'text';
  602. $field['widget_type'] = 'text_textfield';
  603. $field['field_settings']['text_processing'] = 0;
  604. $field['label'] = 'Source URL';
  605. $field['description'] = 'The URL where the original source data was derived. Ideally, this should link to the page where more information about the source data can be found.';
  606. }
  607. elseif ($field['field_settings']['chado_table'] == 'analysis' and $field['field_settings']['chado_column'] == 'sourcename') {
  608. $field['label'] = 'Source Name';
  609. $field['description'] = 'The name of the source data. This could be a file name, data set or a small description for how the data was collected. For long descriptions use the larger description field.';
  610. }
  611. elseif ($field['field_settings']['chado_table'] == 'analysis' and $field['field_settings']['chado_column'] == 'sourceversion') {
  612. $field['label'] = 'Source Version';
  613. $field['description'] = 'If hte source data set has a version include it here.';
  614. }
  615. elseif ($field['field_settings']['chado_table'] == 'analysis' and $field['field_settings']['chado_column'] == 'algorithm') {
  616. $field['label'] = 'Source Version';
  617. $field['description'] = 'The name of the algorithm used to produce the dataset if different from the program.';
  618. }
  619. elseif ($field['field_settings']['chado_table'] == 'analysis' and $field['field_settings']['chado_column'] == 'programversion') {
  620. $field['label'] = 'Program Version';
  621. $field['description'] = 'The version of the program used to perform this analysis. (e.g. TBLASTX 2.0MP-WashU [09-Nov-2000]. Enter "n/a" if no version is available or applicable.';
  622. }
  623. //
  624. // PROJECT TABLE
  625. //
  626. elseif ($field['field_settings']['chado_table'] == 'project' and $field['field_settings']['chado_column'] == 'description') {
  627. $field['label'] = 'Short Description';
  628. }
  629. return $field;
  630. }
  631. /**
  632. * Implements hook_form_FORM_ID_alter().
  633. *
  634. * The field_ui_display_overview_form is used for formatting the display
  635. * or layout of fields attached to an entity and shown on the entity view page.
  636. *
  637. * This function removes the cvterm class and property adder field as those are
  638. * really not meant for users to show or manage.
  639. */
  640. function tripal_chado_form_field_ui_display_overview_form_alter(&$form, &$form_state, $form_id) {
  641. // Remove the kvproperty_addr field as it isn't ever displayed. It's just used
  642. // on the add/edit form of an entity for adding new property fields.
  643. $fields_names = element_children($form['fields']);
  644. foreach ($fields_names as $field_name) {
  645. $field_info = field_info_field($field_name);
  646. if ($field_info['type'] == 'kvproperty_adder') {
  647. unset($form['fields'][$field_name]);
  648. }
  649. if ($field_info['type'] == 'cvterm_class_adder') {
  650. unset($form['fields'][$field_name]);
  651. }
  652. }
  653. }
  654. /**
  655. * Implements hook_form_FORM_ID_alter().
  656. *
  657. * The field_ui_field_overview_form is used for ordering and configuring the
  658. * fields attached to an entity.
  659. *
  660. * This function removes the property adder field as that is really not meant
  661. * for users to show or manage.
  662. */
  663. function tripal_chado_form_field_ui_field_overview_form_alter(&$form, &$form_state, $form_id) {
  664. // Remove the kvproperty_addr field as it isn't ever displayed. It's just used
  665. // on the add/edit form of an entity for adding new property fields.
  666. $fields_names = element_children($form['fields']);
  667. foreach ($fields_names as $field_name) {
  668. $field_info = field_info_field($field_name);
  669. if ($field_info['type'] == 'kvproperty_adder') {
  670. unset($form['fields'][$field_name]);
  671. }
  672. if ($field_info['type'] == 'cvterm_class_adder') {
  673. unset($form['fields'][$field_name]);
  674. }
  675. }
  676. }
  677. /**
  678. * Implements hook_field_is_empty().
  679. */
  680. function tripal_chado_field_is_empty($item, $field) {
  681. // If there is no value field then the field is empty.
  682. if (!array_key_exists('value', $item)) {
  683. return TRUE;
  684. }
  685. // Iterate through all of the fields and if at least one has a value
  686. // the field is not empty.
  687. foreach ($item as $form_field_name => $value) {
  688. if (isset($value) and $value != NULL and $value != '') {
  689. return FALSE;
  690. }
  691. }
  692. // Otherwise, the field is empty.
  693. return TRUE;
  694. }
  695. /**
  696. * Implements hook_add_bundle_fields().
  697. */
  698. function tripal_chado_add_bundle_fields($entity_type, $bundle, $term) {
  699. $bundle_name = $bundle->name;
  700. // This array will hold details that map the bundle to tables in Chado.
  701. $bundle_data = array();
  702. // Get the cvterm that corresponds to this TripalTerm object.
  703. $vocab = entity_load('TripalVocab', array($term->vocab_id));
  704. $vocab = reset($vocab);
  705. $match = array(
  706. 'dbxref_id' => array(
  707. 'db_id' => array(
  708. 'name' => $vocab->namespace,
  709. ),
  710. 'accession' => $term->accession
  711. ),
  712. );
  713. $cvterm = chado_generate_var('cvterm', $match);
  714. // The organism table does not have a type_id so we won't ever find
  715. // a record for it in the tripal_cv_defaults table.
  716. if ($cvterm->name == 'organism') {
  717. $bundle_data = array(
  718. 'cv_id' => $cvterm->cv_id->cv_id,
  719. 'cvterm_id' => $cvterm->cvterm_id,
  720. 'data_table' => 'organism',
  721. 'type_table' => 'organism',
  722. 'field' => '',
  723. );
  724. }
  725. // The analysis table does not have a type_id so we won't ever find
  726. // a record for it in the tripalcv_defaults table.
  727. else if ($cvterm->name == 'analysis') {
  728. $bundle_data = array(
  729. 'cv_id' => $cvterm->cv_id->cv_id,
  730. 'cvterm_id' => $cvterm->cvterm_id,
  731. 'data_table' => 'analysis',
  732. 'type_table' => 'analysis',
  733. 'field' => '',
  734. );
  735. }
  736. else if ($cvterm->name == 'project') {
  737. $bundle_data = array(
  738. 'cv_id' => $cvterm->cv_id->cv_id,
  739. 'cvterm_id' => $cvterm->cvterm_id,
  740. 'data_table' => 'project',
  741. 'type_table' => 'project',
  742. 'field' => '',
  743. );
  744. }
  745. else {
  746. // TODO: WHAT TO DO IF A VOCABULARY IS USED AS A DEFAULT FOR MULTIPLE
  747. // TABLES.
  748. // Look to see if this vocabulary is used as a default for any table.
  749. $default = db_select('tripal_cv_defaults', 't')
  750. ->fields('t')
  751. ->condition('cv_id', $cvterm->cv_id->cv_id)
  752. ->execute()
  753. ->fetchObject();
  754. if ($default) {
  755. $bundle_data = array(
  756. 'cv_id' => $cvterm->cv_id->cv_id,
  757. 'cvterm_id' => $cvterm->cvterm_id,
  758. 'data_table' => $default->table_name,
  759. 'type_table' => $default->table_name,
  760. 'field' => $default->field_name,
  761. );
  762. }
  763. }
  764. // Save the mapping information so that we can reuse it when we need to
  765. // look things up for later for an entity
  766. tripal_set_bundle_variable('chado_cvterm_id', $bundle->id, $bundle_data['cvterm_id']);
  767. tripal_set_bundle_variable('chado_table', $bundle->id, $bundle_data['data_table']);
  768. tripal_set_bundle_variable('chado_column', $bundle->id, $bundle_data['field']);
  769. //////////////////////////////////////////////////////////////////////////////
  770. // ADD FIELDS TO BUNDLE
  771. ////////////////////////////////////////////////////////////////////////////
  772. ////
  773. //
  774. // Base table fields.
  775. //
  776. // Adds the fields for the base table to the entity. Adds fields
  777. // for all columns including FK fields. Excludes primary key and the
  778. // type_id field (that's inherent in the bundle).
  779. tripal_chado_add_bundle_fields_base__fields($entity_type, $bundle_name, $bundle_data);
  780. ////
  781. //
  782. // Property table fields.
  783. //
  784. // Check to see if there are any property tables with FKs to this
  785. // base table. If so, add the fields for that type of table.
  786. $prop_table = $bundle_data['data_table'] . 'prop';
  787. if (chado_table_exists($prop_table)) {
  788. tripal_chado_add_bundle_fields_linker__prop_adder_field($entity_type, $bundle_name, $prop_table, $bundle_data['data_table']);
  789. }
  790. ////
  791. //
  792. // Dbxref table fields.
  793. //
  794. // Check to see if there are any dbxref tables with FKs to this
  795. // base table. If so, add the fields for that type of table.
  796. $dbxref_table = $bundle_data['data_table'] . '_dbxref';
  797. if (chado_table_exists($dbxref_table)) {
  798. tripal_chado_add_bundle_fields_linker__dbxref_field($entity_type, $bundle_name, $dbxref_table, $bundle_data['data_table']);
  799. }
  800. ////
  801. //
  802. // Cvterm table fields.
  803. //
  804. // Check to see if there are any cvterm tables with FKs to this
  805. // base table. If so, add the fields for that type of table.
  806. $cvterm_table = $bundle_data['data_table'] . '_cvterm';
  807. if (chado_table_exists($cvterm_table)) {
  808. tripal_chado_add_bundle_fields_linker__cvterm_adder_field($entity_type, $bundle_name, $cvterm_table, $bundle_data['data_table']);
  809. }
  810. ////
  811. //
  812. // Synonym table fields.
  813. //
  814. // Check to see if there are any synonym tables with FKs to this
  815. // base table. If so, add the fields for that type of table.
  816. $syn_table = $bundle_data['data_table'] . '_synonym';
  817. if (chado_table_exists($syn_table)) {
  818. tripal_chado_add_bundle_fields_linker__synonym_field($entity_type, $bundle_name, $syn_table, $bundle_data['data_table']);
  819. }
  820. ////
  821. //
  822. // Pub table fields.
  823. //
  824. // Check to see if there are any pub tables with FKs to this
  825. // base table. If so, add the fields for that type of table.
  826. $pub_table = $bundle_data['data_table'] . '_pub';
  827. if (chado_table_exists($pub_table)) {
  828. tripal_chado_add_bundle_fields_linker__pub_field($entity_type, $bundle_name, $pub_table, $bundle_data['data_table']);
  829. }
  830. }
  831. /**
  832. * Adds the fields for managing xrefs that are stored in a [base]_dbxref table.
  833. *
  834. * @param $entity_type
  835. * @param $bundle_name
  836. * @param $base_table
  837. * @param $dbxref_table
  838. */
  839. function tripal_chado_add_bundle_fields_linker__dbxref_field($entity_type_name, $bundle_name, $dbxref_table, $base_table) {
  840. // We already have a dbxref_id field.
  841. $field_name = $dbxref_table;
  842. $schema = chado_get_schema($dbxref_table);
  843. $pkey = $schema['primary key'][0];
  844. // Initialize the field array.
  845. $field_info = array(
  846. 'field_type' => 'chado_linker__dbxref',
  847. 'widget_type' => 'chado_linker__dbxref_widget',
  848. 'widget_settings' => array('display_label' => 1),
  849. 'description' => '',
  850. 'label' => 'Cross References',
  851. 'is_required' => 0,
  852. 'cardinality' => FIELD_CARDINALITY_UNLIMITED,
  853. 'storage' => 'field_chado_storage',
  854. 'field_settings' => array(
  855. // The Chado table that this field maps to.
  856. 'chado_table' => $dbxref_table,
  857. // The column in the chado table that this field maps to.
  858. 'chado_column' => $pkey,
  859. // The base table that this field is connected to.
  860. 'base_table' => $base_table,
  861. 'semantic_web' => array(
  862. // The type is the term from a vocabulary that desribes this field..
  863. 'type' => '',
  864. // The namepsace for the vocabulary (e.g. 'foaf').
  865. 'ns' => '',
  866. // The URL for the namespace. It must be that the type can be
  867. // appended to the URL.
  868. 'nsurl' => '',
  869. ),
  870. ),
  871. );
  872. // If the base table has a 'dbxref_id' then change the label to
  873. // indicate these are secondary cross references.
  874. $schema = chado_get_schema($base_table);
  875. if (array_key_exists('dbxref_id', $schema['fields'])) {
  876. $field_info['label'] = 'Secondary Cross References';
  877. }
  878. tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
  879. }
  880. /**
  881. * Adds the fields for managing xrefs that are stored in a [base]_dbxref table.
  882. *
  883. * @param $entity_type
  884. * @param $bundle_name
  885. * @param $base_table
  886. * @param $dbxref_table
  887. */
  888. function tripal_chado_add_bundle_fields_linker__synonym_field($entity_type_name, $bundle_name, $syn_table, $base_table) {
  889. // We already have a dbxref_id field.
  890. $field_name = $syn_table;
  891. $schema = chado_get_schema($syn_table);
  892. $pkey = $schema['primary key'][0];
  893. // Initialize the field array.
  894. $field_info = array(
  895. 'field_type' => 'chado_linker__synonym',
  896. 'widget_type' => 'chado_linker__synonym_widget',
  897. 'widget_settings' => array('display_label' => 1),
  898. 'description' => '',
  899. 'label' => 'Synonyms',
  900. 'is_required' => 0,
  901. 'cardinality' => FIELD_CARDINALITY_UNLIMITED,
  902. 'storage' => 'field_chado_storage',
  903. 'field_settings' => array(
  904. // The Chado table that this field maps to.
  905. 'chado_table' => $syn_table,
  906. // The column in the chado table that this field maps to.
  907. 'chado_column' => $pkey,
  908. // The base table that this field is connected to.
  909. 'base_table' => $base_table,
  910. 'semantic_web' => array(
  911. // The type is the term from a vocabulary that desribes this field..
  912. 'type' => '',
  913. // The namepsace for the vocabulary (e.g. 'foaf').
  914. 'ns' => '',
  915. // The URL for the namespace. It must be that the type can be
  916. // appended to the URL.
  917. 'nsurl' => '',
  918. ),
  919. ),
  920. );
  921. tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
  922. }
  923. /**
  924. * Adds the fields for managing xrefs that are stored in a [base]_dbxref table.
  925. *
  926. * @param $entity_type
  927. * @param $bundle_name
  928. * @param $base_table
  929. * @param $dbxref_table
  930. */
  931. function tripal_chado_add_bundle_fields_linker__pub_field($entity_type_name, $bundle_name, $pub_table, $base_table) {
  932. // We already have a dbxref_id field.
  933. $field_name = $pub_table;
  934. $schema = chado_get_schema($pub_table);
  935. $pkey = $schema['primary key'][0];
  936. // Initialize the field array.
  937. $field_info = array(
  938. 'field_type' => 'chado_linker__pub',
  939. 'widget_type' => 'chado_linker__pub_widget',
  940. 'widget_settings' => array('display_label' => 1),
  941. 'description' => '',
  942. 'label' => 'Publications',
  943. 'is_required' => 0,
  944. 'cardinality' => FIELD_CARDINALITY_UNLIMITED,
  945. 'storage' => 'field_chado_storage',
  946. 'field_settings' => array(
  947. // The Chado table that this field maps to.
  948. 'chado_table' => $pub_table,
  949. // The column in the chado table that this field maps to.
  950. 'chado_column' => $pkey,
  951. // The base table that this field is connected to.
  952. 'base_table' => $base_table,
  953. 'semantic_web' => array(
  954. // The type is the term from a vocabulary that desribes this field..
  955. 'type' => '',
  956. // The namepsace for the vocabulary (e.g. 'foaf').
  957. 'ns' => '',
  958. // The URL for the namespace. It must be that the type can be
  959. // appended to the URL.
  960. 'nsurl' => '',
  961. ),
  962. ),
  963. );
  964. tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
  965. }
  966. /**
  967. * Adds the fields for managing properties that are stored in a prop table.
  968. *
  969. * @param $entity_type_name
  970. * @param $bundle_name
  971. * @param $kv_table
  972. */
  973. function tripal_chado_add_bundle_fields_linker__prop_adder_field($entity_type_name, $bundle_name, $kv_table, $base_table) {
  974. $field_name = $kv_table;
  975. // Initialize the field array.
  976. $field_info = array(
  977. 'field_type' => 'chado_linker__prop_adder',
  978. 'widget_type' => 'chado_linker__prop_adder_widget',
  979. 'field_settings' => array(
  980. 'base_table' => $base_table,
  981. ),
  982. 'storage' => 'field_chado_storage',
  983. 'widget_settings' => array('display_label' => 1),
  984. 'description' => '',
  985. 'label' => 'Additional Properties',
  986. 'is_required' => 0,
  987. );
  988. tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
  989. }
  990. /**
  991. * Adds the fields for managing properties that are stored in a prop table.
  992. *
  993. * @param $entity_type_name
  994. * @param $bundle_name
  995. * @param $kv_table
  996. */
  997. function tripal_chado_add_bundle_fields_linker__cvterm_adder_field($entity_type_name, $bundle_name, $cvterm_table, $base_table) {
  998. // First add a generic property field so that users can add new property types.
  999. $field_name = $cvterm_table;
  1000. // Initialize the field array.
  1001. $field_info = array(
  1002. 'field_type' => 'chado_linker__cvterm_adder',
  1003. 'widget_type' => 'chado_linker__cvterm_adder_widget',
  1004. 'field_settings' => array(
  1005. 'base_table' => $base_table,
  1006. ),
  1007. 'storage' => 'field_chado_storage',
  1008. 'widget_settings' => array('display_label' => 1),
  1009. 'description' => '',
  1010. 'label' => 'Additional Annotation Types',
  1011. 'is_required' => 0,
  1012. );
  1013. tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
  1014. }
  1015. /**
  1016. * Adds the fields for the base table to the entity.
  1017. */
  1018. function tripal_chado_add_bundle_fields_base__fields($entity_type_name, $bundle_name, $bundle_data) {
  1019. $table_name = $bundle_data['data_table'];
  1020. $type_table = $bundle_data['type_table'];
  1021. $type_field = $bundle_data['field'];
  1022. // Iterate through the columns of the table and see if fields have been
  1023. // created for each one. If not, then create them.
  1024. $schema = chado_get_schema($table_name);
  1025. $columns = $schema['fields'];
  1026. foreach ($columns as $column_name => $details) {
  1027. $field_name = $table_name . '__' . $column_name;
  1028. // Skip the primary key field.
  1029. if ($column_name == $schema['primary key'][0]) {
  1030. continue;
  1031. }
  1032. // Skip the type field.
  1033. if ($table_name == $type_table and $column_name == $type_field) {
  1034. continue;
  1035. }
  1036. // Get the field defaults for this column.
  1037. $field_info = tripal_chado_add_bundle_fields_base__fields_defaults($table_name, $schema, $column_name);
  1038. // TODO: add in a call to drupal_alter to allow other modules to change
  1039. // the field settings.
  1040. // Determine if the field is required.
  1041. if (array_key_exists('not null', $details) and $details['not null'] === TRUE) {
  1042. $field_info['is_required'] = array_key_exists('default', $details) ? 0 : 1;
  1043. }
  1044. // If we don't have a field type then we don't need to create a field.
  1045. if (!$field_info['field_type']) {
  1046. // If we don't have a field type but it is required and doesn't have
  1047. // a default value then we are in trouble.
  1048. if ($field_info['is_required'] and !array_key_exists('default', $details)) {
  1049. throw new Exception(t('The %table.%field type, %type, is not yet supported for Entity fields, but it is required,',
  1050. array('%table' => $table_name, '%field' => $column_name, '%type' => $details['type'])));
  1051. }
  1052. continue;
  1053. }
  1054. // If this field is a foreign key field then we will have a custom field.
  1055. $is_fk = FALSE;
  1056. if (array_key_exists('foreign keys', $schema)) {
  1057. foreach ($schema['foreign keys'] as $remote_table => $fk_details) {
  1058. if (array_key_exists($column_name, $fk_details['columns'])) {
  1059. $is_fk = TRUE;
  1060. }
  1061. }
  1062. }
  1063. // Add the field to the bundle.
  1064. tripal_add_bundle_field($field_name, $field_info, $entity_type_name, $bundle_name);
  1065. }
  1066. }
  1067. /**
  1068. * Implements hook_field_validate().
  1069. *
  1070. * This function is used to validate any field. Fields with custom
  1071. * widgets will most likely have their own validate function but for all
  1072. * others we need a way to validate them.
  1073. *
  1074. */
  1075. function tripal_chado_field_validate($entity_type, $entity, $field, $instance,
  1076. $langcode, $items, &$errors) {
  1077. }
  1078. /**
  1079. * Implements hook_field_attach_validate().
  1080. *
  1081. * This function is used to validate entity-wide validation any of the fields
  1082. * attached to an entity.
  1083. */
  1084. function tripal_chado_field_attach_validate($entity_type, $entity, &$errors) {
  1085. $bundle_name = $entity->bundle;
  1086. $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
  1087. $term = tripal_load_term_entity(array('term_id' => $bundle->term_id));
  1088. // Provide some higher-level validation for the organism type.
  1089. if ($term->name == 'organism') {
  1090. }
  1091. }