tripal_ws.module 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <?php
  2. /**
  3. * Implements hook_init()
  4. */
  5. function tripal_ws_init() {
  6. global $base_url;
  7. $version = 'v0.1';
  8. $api_url = $base_url . '/ws/' . $version;
  9. // Following the WC3 Hydra documentation, we want to add LINK to the header
  10. // of the site that indicates where the API documentation can be found.
  11. // This allows a hydra-enabled client to discover the API and use it.
  12. $attributes = array(
  13. 'rel' => 'http://www.w3.org/ns/hydra/core#apiDocumentation',
  14. 'href' => $api_url . '/ws-doc/',
  15. );
  16. drupal_add_html_head_link($attributes, $header = FALSE);
  17. }
  18. /**
  19. * Implements hook_menu().
  20. * Defines all menu items needed by Tripal Core
  21. *
  22. * @ingroup tripal_ws
  23. */
  24. function tripal_ws_menu() {
  25. // Web Services API callbacks.
  26. $items['ws'] = array(
  27. 'title' => 'Tripal Web Services API',
  28. 'page callback' => 'tripal_ws_services',
  29. 'access arguments' => array('access content'),
  30. 'type' => MENU_CALLBACK,
  31. );
  32. $items['remote/%/%/%/%'] = array(
  33. 'page callback' => 'tripal_ws_load_remote_entity',
  34. 'page arguments' => array(1, 2, 3, 4),
  35. 'access arguments' => array('access content'),
  36. 'type' => MENU_CALLBACK,
  37. );
  38. // Tripal Web Services setting groups
  39. $items['admin/tripal/storage/ws'] = array(
  40. 'title' => 'Remote Tripal Sites',
  41. 'description' => t("Create mashups of content using data from this site and remote Tripal sites."),
  42. 'weight' => 20,
  43. 'page callback' => 'system_admin_menu_block_page',
  44. 'access arguments' => array('administer tripal'),
  45. 'file' => 'system.admin.inc',
  46. 'file path' => drupal_get_path('module', 'system'),
  47. );
  48. $items['admin/tripal/storage/ws/tripal_sites'] = array(
  49. 'title' => 'Configuration',
  50. 'description' => t('Provides information about other Tripal sites.
  51. This allows data exchange and communication betwen Tripal
  52. enabled sites through the web services.'),
  53. 'page callback' => 'drupal_get_form',
  54. 'page arguments' => array('tripal_ws_tripal_sites_form'),
  55. 'access arguments' => array('administer tripal'),
  56. 'type' => MENU_NORMAL_ITEM,
  57. 'weight' => 0,
  58. 'file' => 'includes/tripal_ws.admin.inc',
  59. 'file path' => drupal_get_path('module', 'tripal_ws'),
  60. );
  61. $items['admin/tripal/storage/ws/tripal_sites/edit'] = array(
  62. 'title' => 'Add Tripal Site',
  63. 'description' => 'Add a Tripal site',
  64. 'page callback' => 'drupal_get_form',
  65. 'page arguments' => array('tripal_ws_tripal_sites_edit_form'),
  66. 'access arguments' => array('administer tripal'),
  67. 'file' => 'includes/tripal_ws.admin.inc',
  68. 'file path' => drupal_get_path('module', 'tripal_ws'),
  69. 'type' => MENU_LOCAL_ACTION,
  70. 'weight' => 2
  71. );
  72. $items['admin/tripal/storage/ws/tripal_sites/remove/%'] = array(
  73. 'title' => 'Remove Tripal Site',
  74. 'description' => 'Remove a Tripal site',
  75. 'page callback' => 'drupal_get_form',
  76. 'page arguments' => array('tripal_ws_tripal_sites_remove_form', 6),
  77. 'access arguments' => array('administer tripal'),
  78. 'file' => 'includes/tripal_ws.admin.inc',
  79. 'file path' => drupal_get_path('module', 'tripal_ws'),
  80. 'type' => MENU_CALLBACK,
  81. 'weight' => 2
  82. );
  83. return $items;
  84. }
  85. /**
  86. * The callback function for all RESTful web services.
  87. *
  88. */
  89. function tripal_ws_services() {
  90. $ws_path = func_get_args();
  91. $params = $_GET;
  92. unset($params['q']);
  93. // The web services should never be cached.
  94. drupal_page_is_cacheable(FALSE);
  95. // Using the provided version number, determine which web services
  96. // verion to call.
  97. $version = array_shift($ws_path);
  98. if ($version and preg_match('/v\d+\.\d+/', $version)) {
  99. $api_url = 'ws/' . $version;
  100. // Add the file with the appropriate web services.
  101. module_load_include('inc', 'tripal_ws', 'includes/tripal_ws.rest_' . $version);
  102. $version = preg_replace('/\./', '_', $version);
  103. $function = 'tripal_ws_services_' . $version;
  104. $response = array();
  105. if (function_exists($function)) {
  106. $response = $function($api_url, $ws_path, $params);
  107. }
  108. }
  109. else {
  110. // TODO: What do we do if no version is provided?
  111. }
  112. drupal_add_http_header('Content-Type', 'application/json');
  113. print drupal_json_encode($response);
  114. }
  115. /**
  116. *
  117. * @param $entities
  118. * @param $type
  119. */
  120. function tripal_ws_entity_load($entities, $type) {
  121. foreach ($entities as $entity) {
  122. //if ($entiy->type = 'TripalEntity') {
  123. // dpm($entity);
  124. //}
  125. }
  126. }
  127. /**
  128. *
  129. * @param $site_id
  130. * @param $api_version
  131. * @param $ctype
  132. * @param $id
  133. *
  134. * @return
  135. */
  136. function tripal_ws_load_remote_entity($site_id, $api_version, $ctype, $id) {
  137. // Get the content type on this site
  138. $bundle = tripal_load_bundle_entity(array('label' => $ctype));
  139. $term = entity_load('TripalTerm', array('id' => $bundle->term_id));
  140. $term = reset($term);
  141. $vocab = $term->vocab;
  142. $query = db_select('tripal_sites', 'ts');
  143. $query->fields('ts');
  144. $query->condition('id', $site_id);
  145. $site = $query->execute()->fetchObject();
  146. if (!$site) {
  147. return 'Could not find specified site.';
  148. }
  149. // Get the content from the web services of the remote site.
  150. $url = $site->url . "/ws/v0.1/content/" . $ctype . "/" . $id;
  151. $json = file_get_contents($url);
  152. $response = json_decode($json, TRUE);
  153. // Set the title for this page to match the title provided.
  154. drupal_set_title($response['label']);
  155. // Attribute this data to the proper source.
  156. $source_url = l($response['label'], $response['itemPage'], array('attributes' => array('target' => '_blank')));
  157. $content = '<div><strong>Source:</strong> ' . $site->name . ': ' . $source_url . '</div>';
  158. // Fake an entity so we can display this content using the same
  159. // entity type on this site.
  160. $entity = new TripalEntity(array(), 'TripalEntity');
  161. $entity->id = 807;
  162. $entity->type = 'TripalEntity';
  163. $entity->bundle = $bundle->name;
  164. $entity->term_id = $term->id;
  165. $entity->title = $response['label'];
  166. $entity->uid = 1;
  167. $entity->status = 1;
  168. // Get the fields and create a list of those that are attached to the bundle.
  169. $fields = field_info_fields();
  170. $my_fields = array();
  171. foreach ($fields as $field) {
  172. if (isset($field['bundles']['TripalEntity'])) {
  173. foreach ($field['bundles']['TripalEntity'] as $bundle_name) {
  174. if ($bundle_name == $bundle->name) {
  175. $my_fields[] = $field;
  176. }
  177. }
  178. }
  179. }
  180. // Add in the value for the 'content_type' field.
  181. $entity->content_type = array();
  182. $entity->content_type['und'][0]['value'] = $bundle->label;
  183. // For each field we know about that should be attached to our bundle,
  184. // see if we can find a corresponding entry in the results returned from
  185. // the web service call. If so, then add the field to our fake entity.
  186. foreach ($my_fields as $field) {
  187. // Get the semantic web term for this field.
  188. $field_name = $field['field_name'];
  189. $settings = $field['settings'];
  190. // If the field does not have a semantic web mapping, then skip it.
  191. if (!isset($settings['semantic_web'])) {
  192. continue;
  193. }
  194. // Convert the term into it's db and accession elements and look it up
  195. // for more details.
  196. list($vocabulary, $accession) = explode(':', $settings['semantic_web']);
  197. $term = tripal_get_term_details($vocabulary, $accession);
  198. // Convert the term to lowercase and remove spaces so we can compare
  199. // correctly.
  200. $term_name = strtolower(preg_replace('/ /', '_', $term['name']));
  201. // TODO: check for the term in the response makes the assumption
  202. // that the term is the same on both sides. This may not be true. The
  203. // acutal vocab and accession for both terms should be compared.
  204. if (isset($response[$term_name])) {
  205. // If this field is of type '@id' then this links out to another
  206. // URL where that information can be retrieved. We'll have to
  207. // handle that separately.
  208. if (isset($response['@context'][$term_name]['@type']) and
  209. $response['@context'][$term_name]['@type'] == '@id') {
  210. $subquery = json_decode(file_get_contents($response[$term_name]), TRUE);
  211. // If the result is a collection then we want to add each value with
  212. // it's own delta value.
  213. if (array_key_exists('@type', $subquery) and $subquery['@type'] == 'Collection') {
  214. $i = 0;
  215. $f = array();
  216. foreach ($subquery['member'] as $member) {
  217. $f['und'][$i]['value'] = $member;
  218. $i++;
  219. }
  220. $entity->$field_name = $f;
  221. }
  222. // If the result is not a collection then just add it.
  223. else {
  224. unset($subquery['@context']);
  225. unset($subquery['@id']);
  226. $f = array();
  227. $f['und'][0]['value'] = $subquery;
  228. $entity->$field_name = $f;
  229. }
  230. }
  231. // For all fields that are currently attached, add the field and
  232. // value to the entity.
  233. else {
  234. $f = array();
  235. $f['und'][0]['value'] = $response[$term_name];
  236. $entity->$field_name = $f;
  237. }
  238. }
  239. }
  240. // Generate the View for this entity
  241. $entities = array();
  242. $entities[] = $entity;
  243. $view = entity_view('TripalEntity', $entities);
  244. $content .= drupal_render($view['TripalEntity'][807]);
  245. return $content;
  246. }