sbo__database_cross_reference.inc

File

tripal_chado/includes/TripalFields/sbo__database_cross_reference/sbo__database_cross_reference.inc
View source
  1. <?php
  2. class sbo__database_cross_reference extends ChadoField {
  3. // --------------------------------------------------------------------------
  4. // EDITABLE STATIC CONSTANTS
  5. //
  6. // The following constants SHOULD be set for each descendent class. They are
  7. // used by the static functions to provide information to Drupal about
  8. // the field and it's default widget and formatter.
  9. // --------------------------------------------------------------------------
  10. // The default lable for this field.
  11. public static $default_label = 'Cross reference';
  12. // The default description for this field.
  13. public static $description = 'This record can be cross referenced with a record in
  14. another online database. This field is intended for one or more
  15. references. At a minimum, the database and accession must be provided.';
  16. // Provide a list of instance specific settings. These can be access within
  17. // the instanceSettingsForm. When the instanceSettingsForm is submitted
  18. // then Drupal with automatically change these settings for the instnace.
  19. // It is recommended to put settings at the instance level whenever possible.
  20. // If you override this variable in a child class be sure to replicate the
  21. // term_name, term_vocab, term_accession and term_fixed keys as these are
  22. // required for all TripalFields.
  23. public static $default_instance_settings = array(
  24. // The short name for the vocabulary (e.g. shcema, SO, GO, PATO, etc.).
  25. 'term_vocabulary' => 'SBO',
  26. // The name of the term.
  27. 'term_name' => 'Database Cross Reference',
  28. // The unique ID (i.e. accession) of the term.
  29. 'term_accession' => '0000554',
  30. // Set to TRUE if the site admin is allowed to change the term
  31. // type. This will create form elements when editing the field instance
  32. // to allow the site admin to change the term settings above.
  33. 'term_fixed' => FALSE,
  34. );
  35. // The default widget for this field.
  36. public static $default_widget = 'sbo__database_cross_reference_widget';
  37. // The default formatter for this field.
  38. public static $default_formatter = 'sbo__database_cross_reference_formatter';
  39. // --------------------------------------------------------------------------
  40. // PROTECTED CLASS MEMBERS -- DO NOT OVERRIDE
  41. // --------------------------------------------------------------------------
  42. // An array containing details about the field. The format of this array
  43. // is the same as that returned by field_info_fields()
  44. protected $field;
  45. // An array containing details about an instance of the field. A field does
  46. // not have to have an instance. But if dealing with an instance (such as
  47. // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
  48. protected $instance;
  49. /**
  50. * @see TripalField::elementInfo()
  51. */
  52. public function elementInfo() {
  53. $field_term = $this->getFieldTermID();
  54. $dbname_term = chado_get_semweb_term('db', 'name');
  55. $accession_term = chado_get_semweb_term('dbxref', 'accession');
  56. $dburl_term = chado_get_semweb_term('db', 'url');
  57. return array(
  58. $field_term => array(
  59. 'operations' => array(),
  60. 'label' => 'Cross Reference',
  61. 'sortable' => FALSE,
  62. 'searchable' => FALSE,
  63. 'type' => 'xs:complexType',
  64. 'readonly' => FALSE,
  65. 'elements' => array(
  66. $dbname_term => array(
  67. 'searchable' => TRUE,
  68. 'label' => 'Cross Reference Database Name',
  69. 'help' => 'The name of the remote database that houses the cross reference.',
  70. 'sortable' => TRUE,
  71. 'type' => 'xs:string',
  72. 'readonly' => FALSE,
  73. 'required' => TRUE,
  74. ),
  75. $accession_term => array(
  76. 'searchable' => TRUE,
  77. 'label' => 'Cross Reference Database Accession',
  78. 'help' => 'The unique accession (identifier) in the database that houses the cross reference.',
  79. 'sortable' => TRUE,
  80. 'type' => 'xs:string',
  81. 'readonly' => FALSE,
  82. 'required' => TRUE,
  83. ),
  84. $dburl_term => array(
  85. 'searchable' => FALSE,
  86. 'label' => 'Cross Reference Database URL',
  87. 'help' => 'The URL of the database that houses the cross reference.',
  88. 'sortable' => FALSE,
  89. 'type' => 'xs:anyURI',
  90. 'readonly' => TRUE,
  91. 'required' => FALSE,
  92. ),
  93. ),
  94. ),
  95. );
  96. }
  97. /**
  98. *
  99. * @see TripalField::load()
  100. */
  101. public function load($entity) {
  102. $record = $entity->chado_record;
  103. $field_name = $this->field['field_name'];
  104. $field_type = $this->field['type'];
  105. $field_table = $this->instance['settings']['chado_table'];
  106. $field_column = $this->instance['settings']['chado_column'];
  107. $base_table = $record->tablename;
  108. $schema = chado_get_schema($field_table);
  109. $pkey = $schema['primary key'][0];
  110. $fkey_lcolumn = key($schema['foreign keys'][$base_table]['columns']);
  111. $fkey_rcolumn = $schema['foreign keys'][$base_table]['columns'][$fkey_lcolumn];
  112. $dbname_term = chado_get_semweb_term('db', 'name');
  113. $accession_term = chado_get_semweb_term('dbxref', 'accession');
  114. $dburl_term = chado_get_semweb_term('db', 'url');
  115. // Set some defaults for the empty record.
  116. $entity->{$field_name}['und'][0] = array(
  117. 'value' => '',
  118. 'chado-' . $field_table . '__' . $pkey => '',
  119. 'chado-' . $field_table . '__' . $fkey_lcolumn => $record->$fkey_rcolumn,
  120. 'chado-' . $field_table . '__dbxref_id' => '',
  121. 'db_id' => '',
  122. 'accession' => '',
  123. );
  124. $linker_table = $base_table . '_dbxref';
  125. $options = array('return_array' => 1);
  126. $record = chado_expand_var($record, 'table', $linker_table, $options);
  127. if (count($record->$linker_table) > 0) {
  128. $i = 0;
  129. foreach ($record->$linker_table as $index => $linker) {
  130. $dbxref = $linker->dbxref_id;
  131. // Ignore the GFF_source database. This is a weird thing required by
  132. // GBrowse and is added by the GFF loader. We don't want to show it.
  133. if ($dbxref->db_id->name == 'GFF_source') {
  134. continue;
  135. }
  136. $URL = chado_get_dbxref_url($dbxref);
  137. $entity->{$field_name}['und'][$i] = array(
  138. 'value' => array(
  139. $dbname_term => $dbxref->db_id->name,
  140. $accession_term => $dbxref->accession,
  141. $dburl_term => $URL,
  142. ),
  143. 'chado-' . $field_table . '__' . $pkey => $linker->$pkey,
  144. 'chado-' . $field_table . '__' . $fkey_lcolumn => $linker->$fkey_lcolumn->$fkey_lcolumn,
  145. 'chado-' . $field_table . '__dbxref_id' => $dbxref->dbxref_id,
  146. 'db_id' => $dbxref->db_id->db_id,
  147. 'accession' => $dbxref->accession,
  148. );
  149. $i++;
  150. }
  151. }
  152. }
  153. /**
  154. * @see ChadoField::query()
  155. */
  156. public function query($query, $condition) {
  157. $dbxref_linker = $this->instance['settings']['chado_table'];
  158. $base_table = $this->instance['settings']['base_table'];
  159. $field_table = $this->instance['settings']['chado_table'];
  160. $bschema = chado_get_schema($base_table);
  161. $bpkey = $bschema['primary key'][0];
  162. $alias = $this->field['field_name'];
  163. $operator = $condition['operator'];
  164. $field_term_id = $this->getFieldTermID();
  165. $dbname_term = $field_term_id . ',' . chado_get_semweb_term('db', 'name');
  166. $accession_term = $field_term_id . ',' . chado_get_semweb_term('dbxref', 'accession');
  167. $dburl_term = $field_term_id . ',' . chado_get_semweb_term('db', 'url');
  168. $this->queryJoinOnce($query, $field_table, $alias, "base.$bpkey = $alias.$bpkey");
  169. $this->queryJoinOnce($query, 'dbxref', $alias . '_DBX', $alias . "_DBX.dbxref_id = $alias.dbxref_id");
  170. if ($condition['column'] == $dbname_term) {
  171. $this->queryJoinOnce($query, 'db', $alias . '_DB', $alias . "_DB.db_id = " . $alias . "_DBX.db_id");
  172. $query->condition($alias . "_DB.name", $condition['value'], $operator);
  173. }
  174. if ($condition['column'] == $accession_term) {
  175. $query->condition($alias . "_DBX.accession", $condition['value'], $operator);
  176. }
  177. }
  178. /**
  179. * @see ChadoField::queryOrder()
  180. */
  181. public function queryOrder($query, $order) {
  182. $dbxref_linker = $this->instance['settings']['chado_table'];
  183. $base_table = $this->instance['settings']['base_table'];
  184. $field_table = $this->instance['settings']['chado_table'];
  185. $bschema = chado_get_schema($base_table);
  186. $bpkey = $bschema['primary key'][0];
  187. $alias = $this->field['field_name'];
  188. $field_term_id = $this->getFieldTermID();
  189. $dbname_term = $field_term_id . ',' . chado_get_semweb_term('db', 'name');
  190. $accession_term = $field_term_id . ',' . chado_get_semweb_term('dbxref', 'accession');
  191. $dburl_term = $field_term_id . ',' . chado_get_semweb_term('db', 'url');
  192. $this->queryJoinOnce($query, $field_table, $alias, "base.$bpkey = $alias.$bpkey", "LEFT OUTER");
  193. $this->queryJoinOnce($query, 'dbxref', $alias . '_DBX', $alias . "_DBX.dbxref_id = $alias.dbxref_id", "LEFT OUTER");
  194. if ($order['column'] == $dbname_term) {
  195. $this->queryJoinOnce($query, 'db', $alias . '_DB', $alias . "_DB.db_id = " . $alias . "_DBX.db_id", "LEFT OUTER");
  196. $query->orderBy($alias . "_DB.name", $order['direction']);
  197. }
  198. if ($order['column'] == $accession_term) {
  199. $query->orderBy($alias . "_DBX.accession", $order['direction']);
  200. }
  201. }
  202. /**
  203. * @see TripalField::validate()
  204. */
  205. public function validate($entity_type, $entity, $langcode, $items, &$errors) {
  206. // If we don't have an entity then we don't want to validate. The case
  207. // where this could happen is when a user is editing the field settings
  208. // and trying to set a default value. In that case there's no entity and
  209. // we don't want to validate. There will always be an entity for creation
  210. // and update operations of a content type.
  211. if (!$entity) {
  212. return;
  213. }
  214. $field_name = $this->field['field_name'];
  215. $field_type = $this->field['type'];
  216. $table_name = $this->instance['settings']['chado_table'];
  217. $field_table = $this->instance['settings']['chado_table'];
  218. $field_column = $this->instance['settings']['chado_column'];
  219. $base_table = $this->instance['settings']['base_table'];
  220. $schema = chado_get_schema($table_name);
  221. $pkey = $schema['primary key'][0];
  222. $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
  223. $fkey = $fkeys[0];
  224. // Get the field values.
  225. foreach ($items as $delta => $values) {
  226. // Get the field values.
  227. $dbxref_id = $values['chado-' . $field_table . '__dbxref_id'];
  228. $db_id = $values['db_id'];
  229. $accession = $values['accession'];
  230. // Make sure that if a database ID is provided that an accession is also
  231. // provided. Here we use the form_set_error function rather than the
  232. // form_error function because the form_error will add a red_highlight
  233. // around all of the fields in the fieldset which is confusing as it's not
  234. // clear to the user what field is required and which isn't. Therefore,
  235. // we borrow the code from the 'form_error' function and append the field
  236. // so that the proper field is highlighted on error.
  237. if (!$db_id) {
  238. $errors[$field_name][$delta]['und'][] = array(
  239. 'message' => t("A database must be provided for the cross reference."),
  240. 'error' => 'sbo__database_cross_reference',
  241. );
  242. }
  243. if ($db_id and !$accession) {
  244. $errors[$field_name][$delta]['und'][] = array(
  245. 'message' => t("A database and the accession must both be provided."),
  246. 'error' => 'sbo__database_cross_reference',
  247. );
  248. }
  249. if (!$db_id and !$accession) {
  250. $errors[$field_name][$delta]['und'][] = array(
  251. 'message' => t("A database and the accession must both be provided."),
  252. 'error' => 'sbo__database_cross_reference',
  253. );
  254. }
  255. }
  256. }
  257. }