obi__organism.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. <?php
  2. class obi__organism extends ChadoField {
  3. // The default label for this field.
  4. public static $default_label = 'Organism';
  5. // The default description for this field.
  6. public static $description = 'The organism to which this resource is associated.';
  7. // Provide a list of instance specific settings. These can be accessed within
  8. // the instanceSettingsForm. When the instanceSettingsForm is submitted
  9. // then Drupal will automatically change these settings for the instance.
  10. // It is recommended to put settings at the instance level whenever possible.
  11. // If you override this variable in a child class be sure to replicate the
  12. // term_name, term_vocab, term_accession and term_fixed keys as these are
  13. // required for all TripalFields.
  14. public static $default_instance_settings = [
  15. // The short name for the vocabulary (e.g. schema, SO, GO, PATO, etc.).
  16. 'term_vocabulary' => 'OBI',
  17. // The name of the term.
  18. 'term_name' => 'organism',
  19. // The unique ID (i.e. accession) of the term.
  20. 'term_accession' => '0100026',
  21. // Set to TRUE if the site admin is allowed to change the term
  22. // type. This will create form elements when editing the field instance
  23. // to allow the site admin to change the term settings above.
  24. 'term_fixed' => FALSE,
  25. // The format for display of the organism.
  26. 'field_display_string' => '<i>[organism.genus] [organism.species]</i>',
  27. ];
  28. // The default widget for this field.
  29. public static $default_widget = 'obi__organism_widget';
  30. // The default formatter for this field.
  31. public static $default_formatter = 'obi__organism_formatter';
  32. /**
  33. * @see TripalField::validate()
  34. */
  35. public function validate($entity_type, $entity, $langcode, $items, &$errors) {
  36. // If we don't have an entity then we don't want to validate. The case
  37. // where this could happen is when a user is editing the field settings
  38. // and trying to set a default value. In that case there's no entity and
  39. // we don't want to validate. There will always be an entity for creation
  40. // and update operations of a content type.
  41. if (!$entity) {
  42. return;
  43. }
  44. $settings = $this->field['settings'];
  45. $field_name = $this->field['field_name'];
  46. $field_type = $this->field['type'];
  47. $field_table = $this->instance['settings']['chado_table'];
  48. $field_column = $this->instance['settings']['chado_column'];
  49. // Set the linker field appropriately.
  50. if ($field_table == 'biomaterial') {
  51. $linker_field = 'chado-biomaterial__taxon_id';
  52. }
  53. else {
  54. $linker_field = 'chado-' . $field_table . '__organism_id';
  55. }
  56. // Get the field values.
  57. foreach ($items as $delta => $values) {
  58. // Get the field values.
  59. $organism_id = $values[$linker_field];
  60. if ((!$organism_id or $organism_id == 0) and !$field_table == 'biomaterial') {
  61. $errors[$field_name]['und'][0][] = [
  62. 'message' => t("Please specify an organism."),
  63. 'error' => 'obi__organism_id',
  64. ];
  65. }
  66. }
  67. }
  68. /**
  69. * @see TripalField::load()
  70. */
  71. public function load($entity) {
  72. $record = $entity->chado_record;
  73. $settings = $this->instance['settings'];
  74. $field_name = $this->field['field_name'];
  75. $field_type = $this->field['type'];
  76. $field_table = $this->instance['settings']['chado_table'];
  77. $field_column = $this->instance['settings']['chado_column'];
  78. // Get the terms for each of the keys for the 'values' property.
  79. $label_term = 'rdfs:label';
  80. $genus_term = chado_get_semweb_term('organism', 'genus');
  81. $species_term = chado_get_semweb_term('organism', 'species');
  82. $infraspecific_name_term = chado_get_semweb_term('organism', 'infraspecific_name');
  83. $infraspecific_type_term = chado_get_semweb_term('organism', 'type_id');
  84. // Set the linker field appropriately.
  85. if ($field_table == 'biomaterial') {
  86. $linker_field = 'chado-biomaterial__taxon_id';
  87. }
  88. else {
  89. $linker_field = 'chado-' . $field_table . '__organism_id';
  90. }
  91. // Set some defaults for the empty record.
  92. $entity->{$field_name}['und'][0] = [
  93. 'value' => [],
  94. ];
  95. if ($record) {
  96. if ($field_table == 'biomaterial') {
  97. $organism = $record->taxon_id;
  98. }
  99. else {
  100. $organism = $record->organism_id;
  101. }
  102. if (!$organism) {
  103. return;
  104. }
  105. $string = $settings['field_display_string'];
  106. $label = chado_replace_tokens($string, $organism);
  107. $entity->{$field_name}['und'][0]['value'] = [
  108. $label_term => $label,
  109. $genus_term => $organism->genus,
  110. $species_term => $organism->species,
  111. ];
  112. // The infraspecific fields were introduced in Chado v1.3.
  113. if (property_exists($organism, 'infraspecific_name')) {
  114. $entity->{$field_name}['und'][0]['value'][$infraspecific_type_term] = NULL;
  115. $entity->{$field_name}['und'][0]['value'][$infraspecific_name_term] = $organism->infraspecific_name;
  116. if ($organism->type_id) {
  117. $entity->{$field_name}['und'][0]['value'][$infraspecific_type_term] = $organism->type_id->name;
  118. }
  119. }
  120. $entity->{$field_name}['und'][0][$linker_field] = $organism->organism_id;
  121. // Is there a published entity for this organism?
  122. if (property_exists($record->{$field_column}, 'entity_id')) {
  123. $entity->{$field_name}['und'][0]['value']['entity'] = 'TripalEntity:' . $record->{$field_column}->entity_id;
  124. }
  125. }
  126. }
  127. /**
  128. * @see TripalField::globalSettingsForm()
  129. */
  130. public function instanceSettingsForm() {
  131. $element = parent::instanceSettingsForm();
  132. $settings = $this->instance['settings'];
  133. $element['instructions'] = [
  134. '#type' => 'item',
  135. '#markup' => 'You may rewrite the way this field is presented to the end-user.
  136. The Rewrite Value field allows you to use tokens to indicate how the
  137. value should be displayed. Tokens will be substituted with appriorate
  138. data from the database. See the Available tokens list for the
  139. tokens you may use.',
  140. ];
  141. $element['field_display_string'] = [
  142. '#type' => 'textfield',
  143. '#title' => 'Rewrite Value',
  144. '#description' => t('Provide a mixture of text and/or tokens for the format.
  145. For example: [organism.genus] [organism.species]. When displayed,
  146. the tokens will be replaced with the actual value.'),
  147. '#default_value' => $settings['field_display_string'],
  148. ];
  149. $element['tokens'] = [
  150. '#type' => 'fieldset',
  151. '#collapsed' => TRUE,
  152. '#collapsible' => TRUE,
  153. '#title' => 'Available Tokens',
  154. ];
  155. $headers = ['Token', 'Description'];
  156. $rows = [];
  157. // Here we use the chado_get_tokens rather than the
  158. // tripal_get_entity_tokens because we can't gurantee that all organisms
  159. // have entities.
  160. $tokens = chado_get_tokens('organism');
  161. foreach ($tokens as $token) {
  162. $rows[] = [
  163. $token['token'],
  164. $token['description'],
  165. ];
  166. }
  167. $table_vars = [
  168. 'header' => $headers,
  169. 'rows' => $rows,
  170. 'attributes' => [],
  171. 'sticky' => FALSE,
  172. 'caption' => '',
  173. 'colgroups' => [],
  174. 'empty' => 'There are no tokens',
  175. ];
  176. $element['tokens']['list'] = [
  177. '#type' => 'item',
  178. '#markup' => theme_table($table_vars),
  179. ];
  180. return $element;
  181. }
  182. /**
  183. * @see TripalField::elementInfo()
  184. */
  185. public function elementInfo() {
  186. $field_term = $this->getFieldTermID();
  187. $genus_term = chado_get_semweb_term('organism', 'genus');
  188. $species_term = chado_get_semweb_term('organism', 'species');
  189. $infraspecific_name_term = chado_get_semweb_term('organism', 'infraspecific_name');
  190. $infraspecific_type_term = chado_get_semweb_term('organism', 'type_id');
  191. return [
  192. $field_term => [
  193. 'operations' => ['eq', 'contains', 'starts'],
  194. 'sortable' => TRUE,
  195. 'searchable' => TRUE,
  196. 'readonly' => FALSE,
  197. 'type' => 'xs:complexType',
  198. 'elements' => [
  199. 'rdfs:label' => [
  200. 'searchable' => TRUE,
  201. 'name' => 'scientific_name',
  202. 'operations' => ['eq', 'ne', 'contains', 'starts'],
  203. 'sortable' => FALSE,
  204. 'type' => 'xs:string',
  205. 'readonly' => TRUE,
  206. 'required' => FALSE,
  207. ],
  208. $genus_term => [
  209. 'searchable' => TRUE,
  210. 'name' => 'genus',
  211. 'operations' => ['eq', 'ne', 'contains', 'starts'],
  212. 'sortable' => TRUE,
  213. 'readonly' => FALSE,
  214. 'type' => 'xs:string',
  215. 'required' => TRUE,
  216. ],
  217. $species_term => [
  218. 'searchable' => TRUE,
  219. 'name' => 'species',
  220. 'operations' => ['eq', 'ne', 'contains', 'starts'],
  221. 'sortable' => TRUE,
  222. 'readonly' => FALSE,
  223. 'type' => 'xs:string',
  224. 'required' => TRUE,
  225. ],
  226. $infraspecific_name_term => [
  227. 'searchable' => TRUE,
  228. 'name' => 'infraspecies',
  229. 'operations' => ['eq', 'ne', 'contains', 'starts'],
  230. 'sortable' => TRUE,
  231. 'readonly' => FALSE,
  232. 'type' => 'xs:string',
  233. 'required' => FALSE,
  234. ],
  235. $infraspecific_type_term => [
  236. 'searchable' => TRUE,
  237. 'name' => 'infraspecific_type',
  238. 'operations' => ['eq', 'ne', 'contains', 'starts'],
  239. 'sortable' => TRUE,
  240. 'readonly' => FALSE,
  241. 'type' => 'xs:integer',
  242. 'required' => FALSE,
  243. ],
  244. 'entity' => [
  245. 'searchable' => FALSE,
  246. ],
  247. ],
  248. ],
  249. ];
  250. }
  251. /**
  252. * @see ChadoField::query()
  253. */
  254. public function query($query, $condition) {
  255. $alias = $this->field['field_name'];
  256. $operator = $condition['operator'];
  257. $field_term_id = $this->getFieldTermID();
  258. $genus_term = $field_term_id . ',' . chado_get_semweb_term('organism', 'genus');
  259. $species_term = $field_term_id . ',' . chado_get_semweb_term('organism', 'species');
  260. $infraspecific_name_term = $field_term_id . ',' . chado_get_semweb_term('organism', 'infraspecific_name');
  261. $infraspecific_type_term = $field_term_id . ',' . chado_get_semweb_term('organism', 'type_id');
  262. // Join to the organism table for this field.
  263. $this->queryJoinOnce($query, 'organism', $alias, "base.organism_id = $alias.organism_id");
  264. // If the column is the field name then we're during a search on the full
  265. // scientific name.
  266. if ($condition['column'] == $field_term_id or
  267. $condition['column'] == $field_term_id . ',rdfs:label') {
  268. if (chado_get_version() <= 1.3) {
  269. $query->where("CONCAT($alias.genus, ' ', $alias.species) $operator :full_name", [':full_name' => $condition['value']]);
  270. }
  271. else {
  272. $this->queryJoinOnce($query, 'cvterm', $alias . '_cvterm', 'base.infraspecific_type = ' . $alias . '_cvterm.type_id', 'LEFT OUTER');
  273. $query->where("CONCAT($alias.genus, ' ', $alias.species, ' ', " . $alias . "'_cvterm.name', ' ', $alias.infraspecific_name) $operator :full_name", [':full_name' => $condition['value']]);
  274. }
  275. }
  276. // If the column is a subfield.
  277. if ($condition['column'] == $species_term) {
  278. $query->condition("$alias.species", $condition['value'], $operator);
  279. }
  280. if ($condition['column'] == $genus_term) {
  281. $query->condition("$alias.genus", $condition['value'], $operator);
  282. }
  283. if ($condition['column'] == $infraspecific_name_term) {
  284. $query->condition("$alias.infraspecific_name", $condition['value'], $operator);
  285. }
  286. if ($condition['column'] == $infraspecific_type_term) {
  287. $this->queryJoinOnce($query, 'cvterm', 'CVT', "base.type_id = CVT.cvterm_id");
  288. $query->condition("CVT.name", $condition['value'], $operator);
  289. }
  290. }
  291. /**
  292. * @see ChadoField::queryOrder()
  293. */
  294. public function queryOrder($query, $order) {
  295. $alias = $this->field['field_name'];
  296. $field_term_id = $this->getFieldTermID();
  297. $genus_term = $field_term_id . ',' . chado_get_semweb_term('organism', 'genus');
  298. $species_term = $field_term_id . ',' . chado_get_semweb_term('organism', 'species');
  299. $infraspecific_name_term = $field_term_id . ',' . chado_get_semweb_term('organism', 'infraspecific_name');
  300. $infraspecific_type_term = $field_term_id . ',' . chado_get_semweb_term('organism', 'type_id');
  301. // Join to the organism table for this field.
  302. $this->queryJoinOnce($query, 'organism', $alias, "base.organism_id = $alias.organism_id");
  303. // Now perform the sort.
  304. if ($order['column'] == $species_term) {
  305. $query->orderBy("$alias.species", $order['direction']);
  306. }
  307. if ($order['column'] == $genus_term) {
  308. $query->orderBy("$alias.genus", $order['direction']);
  309. }
  310. if ($order['column'] == $infraspecific_name_term) {
  311. $query->orderBy("$alias.infraspecific_name", $order['direction']);
  312. }
  313. if ($order['column'] == $infraspecific_type_term) {
  314. if (!in_array('CVT', $joins)) {
  315. $this->queryJoinOnce($query, 'cvterm', 'CVT', "base.type_id = CVT.cvterm_id");
  316. }
  317. $query->orderBy("CVT.name", $order['direction']);
  318. }
  319. }
  320. }