tripal_ws.rest.inc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. <?php
  2. /**
  3. *_a
  4. */
  5. function tripal_ws_rest() {
  6. global $base_url;
  7. $ws_path = func_get_args();
  8. $params = $_GET;
  9. unset($params['q']);
  10. // The web services should never be cached.
  11. drupal_page_is_cacheable(FALSE);
  12. // Set some initial variables.
  13. $response = array();
  14. $status = 'success';
  15. $version = 'v0.1';
  16. $message = '';
  17. $api_url = $base_url . '/ws/' . $version;
  18. $page_limit = 25;
  19. $pager_id = 0;
  20. // Set some defaults for the response.
  21. $response['@context'] = array();
  22. // Lump everything ito a try block so that if there is a problem we can
  23. // throw an error and have that returned in the response.
  24. try {
  25. // The services is the first argument
  26. $service = (count($ws_path) > 0) ? $ws_path[0] : '';
  27. switch ($service) {
  28. case 'doc':
  29. tripal_ws_handle_doc_service($api_url, $response);
  30. break;
  31. case 'content':
  32. tripal_ws_handle_content_service($api_url, $response, $ws_path, $params);
  33. break;
  34. case 'vocab':
  35. tripal_ws_handle_vocab_service($api_url, $response, $ws_path);
  36. break;
  37. default:
  38. tripal_ws_handle_no_service($api_url, $response);
  39. }
  40. }
  41. catch (Exception $e) {
  42. watchdog('tripal_ws', $e->getMessage(), array(), WATCHDOG_ERROR);
  43. $message = $e->getMessage();
  44. $status = 'error';
  45. }
  46. // The responses follow a similar format as the AGAVE API with a
  47. // status, message, version and all data in the 'result' object.
  48. /* $response['status'] = $status;
  49. $response['message'] = $message;
  50. $response['api_version'] = $version;
  51. $response['source'] = array(
  52. 'site_name' => variable_get('site_name', 'Unspecified'),
  53. 'site_url' => $base_url,
  54. 'site_slogan' => variable_get('site_slogan', 'Unspecified'),
  55. 'site_email' => variable_get('site_mail', 'Unspecified'),
  56. ); */
  57. // Rather than use the drupal_json_output() funciton we manually specify
  58. // content type because we want it to be 'ld+json'.
  59. drupal_add_http_header('Content-Type', 'application/ld+json');
  60. print drupal_json_encode($response);
  61. }
  62. /**
  63. *
  64. * @param $api_url
  65. * @param $response
  66. * @param $ws_path
  67. */
  68. function tripal_ws_handle_content_service($api_url, &$response, $ws_path, $params) {
  69. // Get the content type.
  70. $ctype = (count($ws_path) > 1) ? $ws_path[1] : '';
  71. $entity_id = (count($ws_path) > 2) ? $ws_path[2] : '';
  72. // If we have no content type then list all of the available content types.
  73. if (!$ctype) {
  74. tripal_ws_get_content_types($api_url, $response);
  75. }
  76. // If we don't have an entity ID then show a paged list of entities with
  77. // the given type.
  78. else if ($ctype and !$entity_id) {
  79. tripal_ws_get_content_type($api_url, $response, $ws_path, $ctype, $params);
  80. }
  81. // If we have a content type and an entity ID then show the entity
  82. else {
  83. tripal_ws_get_content($api_url, $response, $ws_path, $ctype, $entity_id);
  84. }
  85. }
  86. /**
  87. *
  88. * @param $api_url
  89. * @param $response
  90. * @param $ws_path
  91. */
  92. function tripal_ws_handle_vocab_service($api_url, &$response, $ws_path) {
  93. // Get the vocab name.
  94. $vocabulary = (count($ws_path) > 1) ? $ws_path[1] : '';
  95. $accession = (count($ws_path) > 2) ? $ws_path[2] : '';
  96. // If we have no $vocabulary type then list all of the available vocabs.
  97. if (!$vocabulary) {
  98. tripal_ws_get_vocabs($api_url, $response);
  99. }
  100. // If we don't have a $vocabulary then show a paged list of terms.
  101. else if ($vocabulary and !$accession) {
  102. tripal_ws_get_vocab($api_url, $response, $ws_path, $vocabulary);
  103. }
  104. // If we have a content type and an entity ID then show the entity
  105. else if ($vocabulary and $accession) {
  106. tripal_ws_get_term($api_url, $response, $ws_path, $vocabulary, $accession);
  107. }
  108. }
  109. /**
  110. *
  111. * @param $api_url
  112. * @param $response
  113. */
  114. function tripal_ws_get_vocabs($api_url, &$response) {
  115. // First, add the vocabularies used into the @context section.
  116. $response['@context']['rdfs'] = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
  117. $response['@context']['hydra'] = 'http://www.w3.org/ns/hydra/core#';
  118. // Next add in the ID for tihs resource.
  119. $response['@id'] = $api_url . '/vocab';
  120. // Start the list.
  121. $response['@type'] = 'Collection';
  122. $response['totalItems'] = 0;
  123. $response['label'] = 'Content Types';
  124. $response['member'] = array();
  125. $vocabs = db_select('tripal_vocab', 'tv')
  126. ->fields('tv')
  127. ->execute();
  128. // Iterate through the vocabularies and add an entry in the collection.
  129. $i = 0;
  130. while ($vocab = $vocabs->fetchObject()) {
  131. $term =
  132. // Add the bundle as a content type.
  133. $response['member'][] = array(
  134. '@id' => $api_url . '/vocab/' . urlencode($vocab->vocabulary),
  135. '@type' => 'vocabulary',
  136. 'vocabulary' => $vocab->vocabulary,
  137. );
  138. $i++;
  139. }
  140. $response['totalItems'] = $i;
  141. //$response['totalItems'] = $i;
  142. // Lastly, add in the terms used into the @context section.
  143. $response['@context']['Collection'] = 'hydra:Collection';
  144. $response['@context']['totalItems'] = 'hydra:totalItems';
  145. $response['@context']['member'] = 'hydra:member';
  146. $response['@context']['label'] = 'rdfs:label';
  147. $response['@context']['description'] = 'hydra:description';
  148. }
  149. /**
  150. *
  151. * @param $api_url
  152. * @param $response
  153. * @param $ws_path
  154. */
  155. function tripal_ws_get_vocab($api_url, &$response, $ws_path, $vocabulary) {
  156. // First, add the vocabularies used into the @context section.
  157. $response['@context']['rdfs'] = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
  158. $response['@context']['hydra'] = 'http://www.w3.org/ns/hydra/core#';
  159. $response['@context']['schema'] = 'https://schema.org/';
  160. // Next add in the ID for tihs resource.
  161. $response['@id'] = $api_url . '/vocab/' . $vocabulary;
  162. // Get the vocabulary
  163. $vocab = tripal_load_vocab_entity(array('vocabulary' => $vocabulary));
  164. // Start the list.
  165. $response['@type'] = 'Collection';
  166. $response['totalItems'] = 0;
  167. $response['label'] = vocabulary . " vocabulary collection";
  168. $response['comment'] = 'The following list of terms may not be the full ' .
  169. 'list for the vocabulary. The terms listed here are only those ' .
  170. 'that have associated content on this site.';
  171. // Get the list of terms for this vocab.
  172. $query = db_select('tripal_term', 'tt')
  173. ->fields('tt', array('id'))
  174. ->condition('vocab_id', $vocab->id)
  175. ->orderBy('accession', 'DESC');
  176. // Iterate through the entities and add them to the list.
  177. $terms = $query->execute();
  178. $i = 0;
  179. while($term = $terms->fetchObject()) {
  180. $term = tripal_load_term_entity(array('term_id' => $term->id));
  181. $response['member'][] = array(
  182. '@id' => $api_url . '/vocab/' . urlencode($vocabulary) . '/' . urlencode($term->accession),
  183. '@type' => 'vocabulary_term',
  184. 'vocabulary' => $vocab->vocabulary,
  185. 'accession' => $term->accession,
  186. 'name' => $term->name,
  187. 'definition' => $term->definition,
  188. );
  189. $i++;
  190. }
  191. $response['totalItems'] = $i;
  192. // Lastly, add in the terms used into the @context section.
  193. $response['@context']['Collection'] = 'hydra:Collection';
  194. $response['@context']['totalItems'] = 'hydra:totalItems';
  195. $response['@context']['member'] = 'hydra:member';
  196. $response['@context']['label'] = 'rdfs:label';
  197. $response['@context']['comment'] = 'rdfs:comment';
  198. $response['@context']['itemPage'] = 'schema:itemPage';
  199. }
  200. /**
  201. *
  202. * @param $api_url
  203. * @param $response
  204. * @param $ws_path
  205. */
  206. function tripal_ws_get_term($api_url, &$response, $ws_path, $vocabulary, $accession) {
  207. // First, add the vocabularies used into the @context section.
  208. $response['@context']['rdfs'] = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
  209. $response['@context']['hydra'] = 'http://www.w3.org/ns/hydra/core#';
  210. $response['@context']['schema'] = 'https://schema.org/';
  211. // Get the term.
  212. $term = tripal_load_term_entity(array('vocabulary' => $vocabulary, 'accession' => $accession));
  213. // Next add in the ID and Type for this resources.
  214. $response['@id'] = $api_url . '/vocab/' . urlencode($vocabulary) . '/' . urlencode($accession);
  215. $response['@type'] = 'vocabulary_term';
  216. $response['label'] = $term->name;
  217. $response['vocabulary'] = $vocabulary;
  218. $response['accession'] = $accession;
  219. $response['name'] = $term->name;
  220. $response['definition'] = $term->definition;
  221. if ($term->url) {
  222. $response['URL'] = $term->url;
  223. }
  224. // Lastly, add in the terms used into the @context section.
  225. $response['@context']['label'] = 'rdfs:label';
  226. $response['@context']['itemPage'] = 'schema:itemPage';
  227. }
  228. /**
  229. * Provides a collection (list) of all of the content types.
  230. *
  231. * @param $api_url
  232. * @param $response
  233. */
  234. function tripal_ws_get_content_types($api_url, &$response) {
  235. // First, add the vocabularies used into the @context section.
  236. $response['@context']['rdfs'] = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
  237. $response['@context']['hydra'] = 'http://www.w3.org/ns/hydra/core#';
  238. // Next add in the ID for tihs resource.
  239. $response['@id'] = $api_url . '/content';
  240. // Start the list.
  241. $response['@type'] = 'Collection';
  242. $response['totalItems'] = 0;
  243. $response['label'] = 'Content Types';
  244. $response['member'] = array();
  245. // Get the list of published terms (these are the bundle IDs)
  246. $bundles = db_select('tripal_bundle', 'tb')
  247. ->fields('tb')
  248. ->orderBy('tb.label', 'ASC')
  249. ->execute();
  250. $terms = array();
  251. // Iterate through the terms and add an entry in the collection.
  252. $i = 0;
  253. while ($bundle = $bundles->fetchObject()) {
  254. $entity = entity_load('TripalTerm', array('id' => $bundle->term_id));
  255. $term = reset($entity);
  256. $vocab = $term->vocab;
  257. if (!array_key_exists($vocab->vocabulary, $response['@context'])) {
  258. // If there is no URL prefix then use this API's vocabulary API
  259. if ($term->urlprefix) {
  260. $response['@context'][$vocab->vocabulary] = $term->urlprefix;
  261. }
  262. else {
  263. $response['@context'][$vocab->vocabulary] = $api_url . '/vocab/' . $vocab->vocabulary . '/';
  264. }
  265. }
  266. // Get the bundle description. If no description is provided then
  267. // use the term definition
  268. $description = tripal_get_bundle_variable('description', $bundle->id);
  269. if (!$description) {
  270. $description = $term->definition;
  271. }
  272. // Add the bundle as a content type.
  273. $response['member'][] = array(
  274. '@id' => $api_url . '/content/' . urlencode($bundle->label),
  275. '@type' => $vocab->vocabulary . ':' . $term->accession,
  276. 'label' => $bundle->label,
  277. 'description' => $description,
  278. );
  279. $i++;
  280. }
  281. $response['totalItems'] = $i;
  282. // Lastly, add in the terms used into the @context section.
  283. $response['@context']['Collection'] = 'hydra:Collection';
  284. $response['@context']['totalItems'] = 'hydra:totalItems';
  285. $response['@context']['member'] = 'hydra:member';
  286. $response['@context']['label'] = 'rdfs:label';
  287. $response['@context']['description'] = 'hydra:description';
  288. }
  289. /**
  290. *
  291. * @param $api_url
  292. * @param $response
  293. * @param $ws_path
  294. */
  295. function tripal_ws_get_content_type($api_url, &$response, $ws_path, $ctype, $params) {
  296. // First, add the vocabularies used into the @context section.
  297. $response['@context']['rdfs'] = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
  298. $response['@context']['hydra'] = 'http://www.w3.org/ns/hydra/core#';
  299. $response['@context']['schema'] = 'https://schema.org/';
  300. // Next add in the ID for tihs resource.
  301. $response['@id'] = $api_url . '/content/' . $ctype;
  302. // Get the TripalBundle, TripalTerm and TripalVocab type for this type.
  303. $bundle = tripal_load_bundle_entity(array('label' => $ctype));
  304. $term = entity_load('TripalTerm', array('id' => $bundle->term_id));
  305. $term = reset($term);
  306. $vocab = $term->vocab;
  307. if (!array_key_exists($vocab->vocabulary, $response['@context'])) {
  308. // If there is no URL prefix then use this API's vocabulary API
  309. if ($term->urlprefix) {
  310. $response['@context'][$vocab->vocabulary] = $term->urlprefix;
  311. }
  312. else {
  313. $response['@context'][$vocab->vocabulary] = $api_url . '/vocab/' . $vocab->vocabulary . '/';
  314. }
  315. }
  316. // Start the list.
  317. $response['@type'] = 'Collection';
  318. $response['totalItems'] = 0;
  319. $response['label'] = $bundle->label . " collection";
  320. // Organize the fields by their web service names.
  321. $fields = field_info_fields();
  322. $field_ws_names = array();
  323. foreach ($fields as $field_name => $details) {
  324. if (array_key_exists('settings', $details) and
  325. array_key_exists('semantic_web', $details['settings'])) {
  326. $sw_name = $details['settings']['semantic_web']['name'];
  327. $field_ws_names[$sw_name][] = $field_name;
  328. }
  329. }
  330. // Get the list of entities for this bundle.
  331. $query = new TripalFieldQuery();
  332. $query->fieldCondition('content_type', $term->id);
  333. foreach($params as $key => $value) {
  334. foreach ($field_ws_names[$key] as $field_name) {
  335. $query->fieldCondition($field_name, $value);
  336. }
  337. }
  338. $results = $query->execute();
  339. // Get the entities from the above search. We do a direct query of the
  340. // table because the load_entity() function is too slow.
  341. $query = db_select('tripal_entity', 'TE');
  342. $query->fields('TE');
  343. $query->condition('id', array_keys($results['TripalEntity']));
  344. $results = $query->execute();
  345. // Iterate through the entities and add them to the list.
  346. $i = 0;
  347. while($entity = $results->fetchObject()) {
  348. $response['member'][] = array(
  349. '@id' => $api_url . '/content/' . urlencode($ctype) . '/' . $entity->id,
  350. '@type' => $vocab->vocabulary . ':' . $term->accession,
  351. 'label' => $entity->title,
  352. 'itemPage' => url('/bio_data/' . $entity->id, array('absolute' => TRUE)),
  353. );
  354. $i++;
  355. }
  356. $response['totalItems'] = $i;
  357. // Lastly, add in the terms used into the @context section.
  358. $response['@context']['Collection'] = 'hydra:Collection';
  359. $response['@context']['totalItems'] = 'hydra:totalItems';
  360. $response['@context']['member'] = 'hydra:member';
  361. $response['@context']['label'] = 'rdfs:label';
  362. $response['@context']['itemPage'] = 'schema:itemPage';
  363. $response['operation'][] = array(
  364. '@type' => 'hydra:CreateResourceOperation',
  365. 'hydra:method' => 'PUT'
  366. );
  367. $response['query'] = array(
  368. '@id' => $response['@id'],
  369. '@type' => 'IriTemplate',
  370. "template" => $response['@id'] . "{?name,}",
  371. "mapping" => array(
  372. array(
  373. "hydra:variable" => 'name',
  374. "hydra:property" => 'name',
  375. )
  376. )
  377. );
  378. }
  379. /**
  380. *
  381. * @param $api_url
  382. * @param $response
  383. * @param $ws_path
  384. */
  385. function tripal_ws_get_content($api_url, &$response, $ws_path, $ctype, $entity_id) {
  386. $context_vocabs = array();
  387. $context_terms = array();
  388. // First, add the vocabularies used into the @context section.
  389. $response['@context']['rdfs'] = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
  390. $response['@context']['hydra'] = 'http://www.w3.org/ns/hydra/core#';
  391. $response['@context']['schema'] = 'https://schema.org/';
  392. // Get the TripalBundle, TripalTerm and TripalVocab type for this type.
  393. $bundle = tripal_load_bundle_entity(array('label' => $ctype));
  394. $term = entity_load('TripalTerm', array('id' => $bundle->term_id));
  395. $term = reset($term);
  396. $vocab = $term->vocab;
  397. // Add the vocabulary for this content type to the @context section.
  398. if (!array_key_exists($vocab->vocabulary, $response['@context'])) {
  399. // If there is no URL prefix then use this API's vocabulary API
  400. if (property_exists($term, 'urlprefix')) {
  401. $response['@context'][$vocab->vocabulary] = $term->urlprefix;
  402. }
  403. else {
  404. $response['@context'][$vocab->vocabulary] = $api_url . '/vocab/' . $vocab->vocabulary . '/';
  405. }
  406. }
  407. // Get the TripalEntity
  408. $entity = tripal_load_entity('TripalEntity', array('id' => $entity_id));
  409. $entity = reset($entity);
  410. // Next add in the ID and Type for this resources.
  411. $response['@id'] = $api_url . '/content/' . $ctype . '/' . $entity_id;
  412. $response['@type'] = $term->name;
  413. $context_terms[$term->name] = $term->url;
  414. $response['label'] = $entity->title;
  415. $response['itemPage'] = url('/bio_data/' . $entity->id, array('absolute' => TRUE));
  416. // Get information about the fields attached to this bundle and sort them
  417. // in the order they were set for the display.
  418. // TODO: should we allow for custom ordering of fields for web services
  419. // or use the default display ordering?
  420. $instances = field_info_instances('TripalEntity', $bundle->name);
  421. uasort($instances, function($a, $b) {
  422. $a_weight = (is_array($a) && isset($a['display']['default']['weight'])) ? $a['display']['default']['weight'] : 0;
  423. $b_weight = (is_array($b) && isset($b['display']['default']['weight'])) ? $b['display']['default']['weight'] : 0;
  424. if ($a_weight == $b_weight) {
  425. return 0;
  426. }
  427. return ($a_weight < $b_weight) ? -1 : 1;
  428. });
  429. // Iterate through the fields and add each value to the response.
  430. //$response['fields'] = $fields;
  431. foreach ($instances as $field_name => $instance) {
  432. // Ignore the content_type field provided by Tripal.
  433. if ($field_name == 'content_type') {
  434. continue;
  435. }
  436. // Skip hidden fields.
  437. if ($instance['display']['default']['type'] == 'hidden') {
  438. continue;
  439. }
  440. // Get the information about this field. It will have settings different
  441. // from the instance.
  442. $field = field_info_field($field_name);
  443. // Get the details for this field for the JSON-LD response.
  444. $details = tripal_ws_get_field_JSON_LD($entity, $field, $instance, $api_url, $ctype);
  445. //print_r($details);
  446. $context_vocabs += $details['context']['vocabs'];
  447. $context_terms += $details['context']['terms'];
  448. $response += $details['value'];
  449. }
  450. // Lastly, add in the terms used into the @context section.
  451. $context_terms['label'] = 'rdfs:label';
  452. $context_terms['itemPage'] = 'schema:itemPage';
  453. $response['@context'] = array_merge($context_vocabs, $context_terms);
  454. // $response['operation'][] = array(
  455. // '@type' => 'hydra:DeleteResourceOperation',
  456. // 'hydra:method' => 'DELETE'
  457. // );
  458. // $response['operation'][] = array(
  459. // '@type' => 'hydra:ReplaceResourceOperation',
  460. // 'hydra:method' => 'POST'
  461. // );
  462. }
  463. /**
  464. *
  465. */
  466. function tripal_ws_get_field_JSON_LD($entity, $field, $instance, $api_url, $ctype) {
  467. // Initialized the context array.
  468. $context = array();
  469. $context['vocabs'] = array();
  470. $context['terms'] = array();
  471. // Get the field settings.
  472. $field_name = $instance['field_name'];
  473. $field_settings = $field['settings'];
  474. // By default, the label for the key in the output should be the
  475. // term from the vocabulary that the field is assigned. But in the
  476. // case that the field is not assigned a term, we must use the field name.
  477. $key = $field_name;
  478. $key = strtolower(preg_replace('/ /', '_', $key));
  479. if (array_key_exists('semantic_web', $field_settings) and $field_settings['semantic_web']) {
  480. list($vocabulary, $accession) = explode(':', $field_settings['semantic_web']);
  481. $term = tripal_get_term_details($vocabulary, $accession);
  482. if ($term) {
  483. $key = $term['name'];
  484. $key = strtolower(preg_replace('/ /', '_', $key));
  485. //$context['vocabs'][$vocabulary] = ;
  486. $context['terms'][$key] = array(
  487. '@id' => $term['url'],
  488. // $field_settings['semantic_web'];
  489. );
  490. }
  491. }
  492. // Don't show fields that are not meant to be auto attached, even if the
  493. // loading of the entity pulled a value for the field from the cache.
  494. // We want the end-user to specifically load these.
  495. $value = array();
  496. $instance_settings = $instance['settings'];
  497. if (array_key_exists('auto_attach', $instance_settings) and
  498. $instance_settings['auto_attach'] == TRUE) {
  499. $items = field_get_items('TripalEntity', $entity, $field_name);
  500. for ($i = 0; $i < count($items); $i++) {
  501. // If the value for this key is an array with an 'entity_id' key then
  502. // we want to do a substitution.
  503. if (array_key_exists('entity_id', $items[$i]) and $items[$i]['entity_id']) {
  504. $lentity = entity_load($items[$i]['entity_type'], array($items[$i]['entity_id']));
  505. $lentity = reset($lentity);
  506. $lterm = tripal_load_term_entity(array('term_id' => $lentity->term_id));
  507. $lvocab = tripal_load_vocab_entity(array('vocab_id' => $lterm->vocab_id));
  508. $value[] = array(
  509. '@id' => $api_url . '/content/' . $lterm->name . '/' . $items[0]['entity_id'],
  510. '@type' => $lvocab->vocabulary . ':' . $lterm->accession,
  511. 'label' => $lentity->title,
  512. 'type' => $lterm->name,
  513. );
  514. if (property_exists($lvocab, 'vocabulary') and !array_key_exists($lvocab->vocabulary, $response['@context'])) {
  515. $lterm_details = tripal_get_term_details($lvocab->vocabulary, $lterm->vocabulary);
  516. if ($lterm_details) {
  517. $context[$lvocab->vocabulary] = $lterm_details->url;
  518. }
  519. }
  520. }
  521. else {
  522. $value[] = $items[$i]['value'];
  523. }
  524. }
  525. }
  526. // If the value shouldn't be attached by default then create a link for the
  527. // caller to retrieve the information.
  528. else {
  529. $context['terms'][$key]['@type'] = '@id';
  530. $value[] = $api_url . '/content/' . $ctype . '/' . $entity->id . '/' . urlencode($key);
  531. }
  532. // Convert a single value to not be an array.
  533. if (count($value) == 1) {
  534. $value = $value[0];
  535. }
  536. return array(
  537. 'context' => $context,
  538. 'value' => array(
  539. $key => $value
  540. ),
  541. );
  542. }
  543. /**
  544. * Provides the Hydra compatible apiDocumentation page that describes this API.
  545. *
  546. * @param $api_url
  547. * @param $response
  548. */
  549. function tripal_ws_handle_doc_service($api_url, &$response) {
  550. // First, add the vocabularies used into the @context section.
  551. $response['@context']['rdfs'] = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
  552. $response['@context']['hydra'] = 'http://www.w3.org/ns/hydra/core#';
  553. // Next add in the ID for tihs resource.
  554. $site_name = variable_get('site_name', '');
  555. $response['@id'] = $api_url . '/doc/';
  556. $response['title'] = $site_name . ": RESTful Web Services API";
  557. $response['entrypoint'] = $api_url;
  558. $response['description'] = "A fully queryable REST API using JSON-LD and " .
  559. "discoverable using the WC3 Hydra specification.";
  560. // Lastly, add in the terms used into the @context section.
  561. $response['@context']['title'] = 'hydra:title';
  562. $response['@context']['entrypoint'] = array(
  563. "@id" => "hydra:entrypoint",
  564. "@type" => "@id",
  565. );
  566. $response['@context']['description'] = 'hydra:description';
  567. }
  568. /**
  569. * This function specifies the types of resources avaiable via the API.
  570. *
  571. * @param $api_url
  572. * @param $response
  573. * @param $ws_path
  574. */
  575. function tripal_ws_handle_no_service($api_url, &$response) {
  576. // First, add the vocabularies used into the @context section.
  577. $response['@context']['rdfs'] = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
  578. $response['@context']['hydra'] = 'http://www.w3.org/ns/hydra/core#';
  579. $response['@context']['dc'] = 'http://purl.org/dc/dcmitype/';
  580. $response['@context']['schema'] = 'https://schema.org/';
  581. // Next add in the ID for tihs resource.
  582. $response['@id'] = $api_url;
  583. // Start the list.
  584. $response['@type'] = 'Collection';
  585. $response['totalItems'] = 0;
  586. $response['label'] = 'Services';
  587. $response['member'] = array();
  588. // Start the list.
  589. $response['member'][] = array(
  590. '@id' => $api_url . '/content/',
  591. '@type' => 'Service',
  592. 'label' => 'Content Types',
  593. 'description' => 'Provides acesss to the biological and ' .
  594. 'ancilliary data available on this site. Each content type ' .
  595. 'represents biological data that is defined in a controlled vocabulary '.
  596. '(e.g. Sequence Ontology term: gene (SO:0000704)).',
  597. );
  598. $response['member'][] = array(
  599. '@id' => $api_url . '/doc/',
  600. '@type' => 'Service',
  601. 'label' => 'API Documentation',
  602. 'description' => 'The WC3 Hydra compatible documentation for this API.',
  603. );
  604. $response['member'][] = array(
  605. '@id' => $api_url . '/vocab/',
  606. '@type' => 'Service',
  607. 'label' => 'Vocabulary',
  608. 'description' => 'Defines in-house locally defined vocabulary terms that ' .
  609. 'have been added specifically for this site. These terms are typically ' .
  610. 'added because no other appropriate term exists in another community-vetted '.
  611. 'controlled vocabulary.',
  612. );
  613. $response['totalItems'] = count($response['member']);
  614. $response['@context']['Collection'] = 'hydra:Collection';
  615. $response['@context']['totalItems'] = 'hydra:totalItems';
  616. $response['@context']['member'] = 'hydra:member';
  617. $response['@context']['Service'] = 'dc:Service';
  618. $response['@context']['label'] = 'rdfs:label';
  619. $response['@context']['description'] = 'hydra:description';
  620. }