tripal.term_lookup.inc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. <?php
  2. /**
  3. * Provides the content for the Controlled vocabulary home page.
  4. */
  5. function tripal_vocabulary_lookup_page() {
  6. // set the breadcrumb
  7. $breadcrumb = [];
  8. $breadcrumb[] = l('Home', '<front>');
  9. drupal_set_breadcrumb($breadcrumb);
  10. $vocabs = tripal_get_vocabularies();
  11. $rows = [];
  12. foreach ($vocabs as $vocabulary) {
  13. $rows[] = [
  14. l($vocabulary['short_name'], 'cv/lookup/' . $vocabulary['short_name']),
  15. $vocabulary['name'],
  16. $vocabulary['description'],
  17. [
  18. 'data' => number_format($vocabulary['num_terms']),
  19. 'style' => 'text-align: right;',
  20. ],
  21. ];
  22. }
  23. $headers = [
  24. 'Short Name',
  25. 'Vocabulary Name(s)',
  26. 'Description',
  27. 'Loaded Terms',
  28. ];
  29. $table = [
  30. 'header' => $headers,
  31. 'rows' => $rows,
  32. 'attributes' => [],
  33. 'sticky' => FALSE,
  34. 'caption' => '',
  35. 'colgroups' => [],
  36. 'empty' => t('There are no controlled vocabularies'),
  37. ];
  38. $content = [
  39. 'description' => [
  40. '#type' => 'markup',
  41. '#markup' => '<p>The following controlled vocabularies are used on this site. Click a vocabulary short name for more details.</p>',
  42. ],
  43. 'vocab_table' => [
  44. '#type' => 'item',
  45. '#markup' => theme_table($table),
  46. ],
  47. ];
  48. return $content;
  49. }
  50. /**
  51. * Provides the content for a single controlled vocabulary.
  52. */
  53. function tripal_vocabulary_lookup_vocab_page($vocabulary) {
  54. // set the breadcrumb
  55. $breadcrumb = [];
  56. $breadcrumb[] = l('Home', '<front>');
  57. $breadcrumb[] = l('Controlled Vocabularies', 'cv/lookup');
  58. drupal_set_breadcrumb($breadcrumb);
  59. $vocab = tripal_get_vocabulary_details($vocabulary);
  60. $vocab_table = tripal_vocabulary_get_vocab_details($vocab);
  61. if ($vocab['description']) {
  62. drupal_set_title($vocabulary . ': ' . $vocab['description']);
  63. }
  64. else {
  65. drupal_set_title($vocabulary);
  66. }
  67. // If we can't find the term then just return a message.
  68. if (!$vocab) {
  69. drupal_set_message('The vocabulary cannot be found on this site', 'error');
  70. return '';
  71. }
  72. $has_root = TRUE;
  73. $root_terms = tripal_get_vocabulary_root_terms($vocabulary);
  74. // If this vocabulary doesn't have root terms then it's either not an
  75. // ontology or not all of the terms are loaded. In this case, let's get
  76. // a paged list of all terms
  77. if (count($root_terms) == 0) {
  78. $root_terms = tripal_get_vocabulary_terms($vocabulary, 25);
  79. $has_root = FALSE;
  80. }
  81. $items = tripal_vocabulary_lookup_term_children_format($root_terms);
  82. if (count($root_terms) == 0) {
  83. $items = '<p>This vocabulary has no terms loaded</p>';
  84. }
  85. else {
  86. $items = '<p>Click the + icon (if present) to expand the tree. If ' .
  87. 'the full ontology or the term heirarchy is not loaded into this site, ' .
  88. 'then the tree will consist of all terms at the same level. ' .
  89. 'For some vocabularies, only a subset of terms are loaded</p>' . $items;
  90. }
  91. drupal_add_js([
  92. 'tripal' => [
  93. 'cv_lookup' => [
  94. 'vocabulary' => $vocabulary,
  95. ],
  96. ],
  97. ], 'setting');
  98. $content = [
  99. 'vocab_table' => [
  100. '#type' => 'item',
  101. '#title' => 'Details',
  102. '#markup' => '<p>A vocabulary is always identified by its short name ' .
  103. 'and sometimes it may offer multiple sub-vocabularies with different ' .
  104. 'names. Both are listed below.</p>' . $vocab_table,
  105. ],
  106. 'vocab_browser' => [
  107. '#type' => 'item',
  108. '#title' => 'Term Browser',
  109. '#markup' => $items,
  110. ],
  111. ];
  112. if (!$has_root) {
  113. $content['pager'] = [
  114. '#type' => 'markup',
  115. '#markup' => theme('pager'),
  116. ];
  117. }
  118. // Add support for our custom tree viewer
  119. drupal_add_css(drupal_get_path('module', 'tripal') . '/theme/css/tripal.cv_lookup.css');
  120. drupal_add_js(drupal_get_path('module', 'tripal') . '/theme/js/tripal.cv_lookup.js', 'file');
  121. return $content;
  122. }
  123. /**
  124. * Generates a table view of the vocabulary.
  125. *
  126. * @param $vocab
  127. * The vocabulary array.
  128. *
  129. * @return
  130. * An HTML rendered table describing the vocabulary.
  131. */
  132. function tripal_vocabulary_get_vocab_details($vocab) {
  133. $headers = [];
  134. $rows = [];
  135. $vocab_name = $vocab['name'];
  136. $short_name = $vocab['short_name'];
  137. if ($vocab['url']) {
  138. $short_name = l($vocab['short_name'], $vocab['url'], ['attributes' => ['target' => '_blank']]);
  139. }
  140. $vocab_desc = $vocab['description'];
  141. $rows[] = [
  142. [
  143. 'data' => 'Short Name',
  144. 'header' => TRUE,
  145. 'width' => '20%',
  146. ],
  147. $short_name,
  148. ];
  149. $rows[] = [
  150. [
  151. 'data' => 'Vocabulary Name(s)',
  152. 'header' => TRUE,
  153. 'width' => '20%',
  154. ],
  155. $vocab_name,
  156. ];
  157. $rows[] = [
  158. [
  159. 'data' => 'Description',
  160. 'header' => TRUE,
  161. 'width' => '20%',
  162. ],
  163. $vocab_desc,
  164. ];
  165. $rows[] = [
  166. [
  167. 'data' => 'Number of Terms Loaded on This Site',
  168. 'header' => TRUE,
  169. 'width' => '20%',
  170. ],
  171. number_format($vocab['num_terms']),
  172. ];
  173. $table = [
  174. 'header' => $headers,
  175. 'rows' => $rows,
  176. 'attributes' => [],
  177. 'sticky' => FALSE,
  178. 'caption' => '',
  179. 'colgroups' => [],
  180. 'empty' => '',
  181. ];
  182. return theme_table($table);
  183. }
  184. /**
  185. * A helper function to format an array of terms into a list for the web page.
  186. *
  187. * @param $children
  188. * A list of children terms.
  189. */
  190. function tripal_vocabulary_lookup_term_children_format($children) {
  191. $items = '<ul id="tripal-cv-lookup-tree">';
  192. foreach ($children as $child) {
  193. $grand = tripal_get_term_children($child['vocabulary']['short_name'], $child['accession']);
  194. $num_grand = count($grand);
  195. $items .= '<li vocabulary = "' . $child['vocabulary']['short_name'] . '" ' .
  196. 'accession = "' . $child['accession'] . '" ' .
  197. 'children = "' . $num_grand . '" ' .
  198. 'state = "closed" ' .
  199. 'class = "cv-lookup-tree-node">';
  200. $class = 'tree-node-closed';
  201. if ($num_grand == 0) {
  202. $class = 'tree-node-single';
  203. }
  204. $items .= '<i class = "tree-node-icon ' . $class . '"></i>';
  205. $items .= l($child['name'], 'cv/lookup/' . $child['vocabulary']['short_name'] . '/' . $child['accession'], ['attributes' => ['target' => '_blank']]);
  206. if ($child['accession'] != $child['name']) {
  207. $items .= ' [' . $child['vocabulary']['short_name'] . ':' . $child['accession'] . '] ';
  208. }
  209. $items .= '</li>';
  210. }
  211. $items .= '</ul>';
  212. if (count($children) == 0) {
  213. $items = '';
  214. }
  215. return $items;
  216. }
  217. /**
  218. * An ajax callback to get the children of a term.
  219. *
  220. * @param $vocabulary
  221. * The short name of the vocabulary (e.g. SO, GO, etc.)
  222. * @param $accession
  223. * The term accession.
  224. *
  225. * @return
  226. * A JSON array compatible with the JSTree library.
  227. * https://www.jstree.com/docs/json/
  228. */
  229. function tripal_vocabulary_lookup_term_children_ajax($vocabulary, $accession) {
  230. $term = tripal_get_term_details($vocabulary, $accession);
  231. $children = tripal_get_term_children($vocabulary, $accession);
  232. $response = [
  233. 'vocabulary' => $vocabulary,
  234. 'accession' => $accession,
  235. 'content' => tripal_vocabulary_lookup_term_children_format($children),
  236. ];
  237. drupal_json_output($response);
  238. }
  239. /**
  240. *
  241. * @param $vocabulary
  242. * @param $accession
  243. *
  244. * @return
  245. */
  246. function tripal_vocabulary_lookup_term_page($vocabulary, $accession) {
  247. // set the breadcrumb
  248. $breadcrumb = [];
  249. $breadcrumb[] = l('Home', '<front>');
  250. $breadcrumb[] = l('Controlled Vocabularies', 'cv/lookup');
  251. $breadcrumb[] = l($vocabulary, 'cv/lookup/' . $vocabulary);
  252. drupal_set_breadcrumb($breadcrumb);
  253. $vocab = tripal_get_vocabulary_details($vocabulary);
  254. $vocab_table = tripal_vocabulary_get_vocab_details($vocab);
  255. $term = tripal_get_term_details($vocabulary, $accession);
  256. // If we can't find the term then just return a message.
  257. if (!$term) {
  258. drupal_set_message('The term cannot be found on this site', 'error');
  259. return '';
  260. }
  261. // Build the Term table.
  262. $headers = [];
  263. $rows = [];
  264. $term_name = $term['name'];
  265. $accession = $term['vocabulary']['short_name'] . ':' . $term['accession'];
  266. drupal_set_title($accession);
  267. // Create a URL to point this term to it's source page, but only if the
  268. // source is not this site.
  269. if ($term['url'] and !preg_match('/cv\/lookup/', $term['url'])) {
  270. $accession = l($accession, $term['url'], ['attributes' => ['target' => '_blank']]);
  271. }
  272. $rows[] = [
  273. [
  274. 'data' => 'Term',
  275. 'header' => TRUE,
  276. 'width' => '20%',
  277. ],
  278. $accession,
  279. ];
  280. $rows[] = [
  281. [
  282. 'data' => 'Name',
  283. 'header' => TRUE,
  284. 'width' => '20%',
  285. ],
  286. $term_name,
  287. ];
  288. $rows[] = [
  289. [
  290. 'data' => 'Definition',
  291. 'header' => TRUE,
  292. 'width' => '20%',
  293. ],
  294. $term['definition'],
  295. ];
  296. // Now iterate through any other columns in the term array and add those
  297. // details.
  298. foreach ($term as $key => $value) {
  299. if (in_array($key, [
  300. 'name',
  301. 'definition',
  302. 'vocabulary',
  303. 'accession',
  304. 'url',
  305. ])) {
  306. continue;
  307. }
  308. // Convert thisto an array so we can alter it.
  309. if (!is_array($value)) {
  310. $new_values[] = $value;
  311. $value = $new_values;
  312. }
  313. // If this is a relationship key then let's try to rewrite the GO
  314. // term in the relationship as a link.
  315. if ($key == 'relationship') {
  316. foreach ($value as $index => $v) {
  317. $matches = [];
  318. if (preg_match('/^(.+)\s(.+?):(.+?)$/', $v, $matches)) {
  319. $rel = $matches[1];
  320. $voc = $matches[2];
  321. $acc = $matches[3];
  322. $v = $rel . ' ' . l($voc . ':' . $acc, 'cv/lookup/' . $voc . '/' . $acc, ['attributes' => ['target' => '_blank']]);
  323. $t = tripal_get_term_details($voc, $acc);
  324. if ($t) {
  325. $v .= ' (' . $t['name'] . ')';
  326. }
  327. $value[$index] = $v;
  328. }
  329. }
  330. }
  331. if (count($value) > 1) {
  332. $value_str = theme_item_list([
  333. 'items' => $value,
  334. 'type' => 'ul',
  335. 'attributes' => [],
  336. 'title' => '',
  337. ]);
  338. }
  339. else {
  340. $value_str = $value[0];
  341. }
  342. $rows[] = [
  343. [
  344. 'data' => ucfirst($key),
  345. 'header' => TRUE,
  346. 'width' => '20%',
  347. ],
  348. $value_str,
  349. ];
  350. }
  351. $table = [
  352. 'header' => $headers,
  353. 'rows' => $rows,
  354. 'attributes' => [],
  355. 'sticky' => FALSE,
  356. 'caption' => '',
  357. 'colgroups' => [],
  358. 'empty' => '',
  359. ];
  360. $content['cvterm'] = [
  361. '#type' => 'item',
  362. '#title' => 'Term Details',
  363. '#markup' => theme_table($table),
  364. ];
  365. $content['vocabulary'] = [
  366. '#type' => 'item',
  367. '#title' => 'Vocabulary Details',
  368. '#markup' => $vocab_table,
  369. ];
  370. drupal_add_js([
  371. 'tripal' => [
  372. 'cv_lookup' => [
  373. 'vocabulary' => $vocabulary,
  374. 'accession' => $accession,
  375. ],
  376. ],
  377. ], 'setting');
  378. return $content;
  379. }