tripal_organism.module

  1. 2.x tripal_organism/tripal_organism.module
  2. 3.x legacy/tripal_organism/tripal_organism.module
  3. 1.x tripal_organism/tripal_organism.module

tripal_organism Organism Module

File

tripal_organism/tripal_organism.module
View source
  1. <?php
  2. require_once "api/tripal_organism.api.inc";
  3. require_once "includes/tripal_organism.admin.inc";
  4. /**
  5. * @file
  6. * @defgroup tripal_organism Organism Module
  7. * @ingroup tripal_modules
  8. */
  9. /**
  10. *
  11. * @ingroup tripal_organism
  12. */
  13. function tripal_organism_init() {
  14. // add the jGCharts JS and CSS
  15. drupal_add_js(drupal_get_path('theme', 'tripal') . '/js/tripal_organism.js');
  16. drupal_add_css(drupal_get_path('theme', 'tripal') . '/css/tripal_organism.css');
  17. }
  18. /**
  19. * Provide information to drupal about the node types that we're creating
  20. * in this module
  21. *
  22. * @ingroup tripal_organism
  23. */
  24. function tripal_organism_node_info() {
  25. $nodes = array();
  26. $nodes['chado_organism'] = array(
  27. 'name' => t('Organism'),
  28. 'module' => 'chado_organism',
  29. 'description' => t('An organism from the chado database'),
  30. 'has_title' => FALSE,
  31. 'title_label' => t('Organism'),
  32. 'has_body' => FALSE,
  33. 'body_label' => t('Organism Description'),
  34. 'locked' => TRUE
  35. );
  36. return $nodes;
  37. }
  38. /**
  39. * Display block with organisms
  40. * @param op - parameter to define the phase being called for the block
  41. * @param delta - id of the block to return (ignored when op is list)
  42. * @param edit - when op is save, contains the submitted form data
  43. *
  44. * @ingroup tripal_organism
  45. */
  46. function tripal_organism_block($op = 'list', $delta = '0', $edit = array()) {
  47. switch ($op) {
  48. case 'list':
  49. $blocks['base']['info'] = t('Tripal Organism Details');
  50. $blocks['base']['cache'] = BLOCK_NO_CACHE;
  51. $blocks['description']['info'] = t('Tripal Organism Description');
  52. $blocks['description']['cache'] = BLOCK_NO_CACHE;
  53. $blocks['image']['info'] = t('Tripal Organism Image');
  54. $blocks['image']['cache'] = BLOCK_NO_CACHE;
  55. return $blocks;
  56. case 'view':
  57. if (user_access('access chado_feature content') and arg(0) == 'node' and is_numeric(arg(1))) {
  58. $nid = arg(1);
  59. $node = node_load($nid);
  60. $block = array();
  61. switch ($delta) {
  62. case 'base':
  63. $block['subject'] = t('Organism Details');
  64. $block['content'] = theme('tripal_organism_base', $node);
  65. break;
  66. case 'description':
  67. $block['subject'] = t('Organism Description');
  68. $block['content'] = theme('tripal_organism_description', $node);
  69. break;
  70. case 'image':
  71. $block['subject'] = t('Organism Image');
  72. $block['content'] = theme('tripal_organism_image', $node);
  73. break;
  74. default:
  75. }
  76. return $block;
  77. }
  78. }
  79. }
  80. /**
  81. * Menu items are automatically added for the new node types created
  82. * by this module to the 'Create Content' Navigation menu item. This function
  83. * adds more menu items needed for this module.
  84. *
  85. * @ingroup tripal_organism
  86. */
  87. function tripal_organism_menu() {
  88. $items = array();
  89. // the administative settings menu
  90. $items['admin/tripal/tripal_organism'] = array(
  91. 'title' => 'Organisms',
  92. 'description' => 'Basic Description of Tripal Organism Module Functionality',
  93. 'page callback' => 'theme',
  94. 'page arguments' => array('tripal_organism_admin'),
  95. 'access arguments' => array('adminster tripal organism'),
  96. 'type' => MENU_NORMAL_ITEM,
  97. );
  98. $items['admin/tripal/tripal_organism/configuration'] = array(
  99. 'title' => 'Configuration',
  100. 'description' => 'Manage integration of Chado organisms including associated features',
  101. 'page callback' => 'drupal_get_form',
  102. 'page arguments' => array('tripal_organism_admin'),
  103. 'access arguments' => array('adminster tripal organism'),
  104. 'type' => MENU_NORMAL_ITEM,
  105. );
  106. return $items;
  107. }
  108. /**
  109. * We need to let drupal know about our theme functions and their arguments.
  110. * We create theme functions to allow users of the module to customize the
  111. * look and feel of the output generated in this module
  112. *
  113. * @ingroup tripal_organism
  114. */
  115. function tripal_organism_theme() {
  116. return array(
  117. 'tripal_organism_base' => array(
  118. 'arguments' => array('node' => NULL),
  119. 'template' => 'tripal_organism_base',
  120. ),
  121. 'tripal_organism_description' => array(
  122. 'arguments' => array('node' => NULL),
  123. 'template' => 'tripal_organism_description',
  124. ),
  125. 'tripal_organism_image' => array(
  126. 'arguments' => array('node' => NULL),
  127. 'template' => 'tripal_organism_image',
  128. ),
  129. 'tripal_organism_teaser' => array(
  130. 'arguments' => array('node' => NULL),
  131. 'template' => 'tripal_organism_teaser',
  132. ),
  133. 'tripal_organism_admin' => array(
  134. 'template' => 'tripal_organism_admin',
  135. 'arguments' => array(NULL),
  136. 'path' => drupal_get_path('module', 'tripal_organism') . '/theme'
  137. ),
  138. );
  139. }
  140. /**
  141. * Implement hook_access().
  142. *
  143. * This hook allows node modules to limit access to the node types they define.
  144. *
  145. * @param $op
  146. * The operation to be performed
  147. *
  148. * @param $node
  149. * The node on which the operation is to be performed, or, if it does not yet exist, the
  150. * type of node to be created
  151. *
  152. * @param $account
  153. * A user object representing the user for whom the operation is to be performed
  154. *
  155. * @return
  156. * If the permission for the specified operation is not set then return FALSE. If the
  157. * permission is set then return NULL as this allows other modules to disable
  158. * access. The only exception is when the $op == 'create'. We will always
  159. * return TRUE if the permission is set.
  160. *
  161. * @ingroup tripal_organism
  162. */
  163. function chado_organism_access($op, $node, $account) {
  164. if ($op == 'create') {
  165. if (!user_access('create chado_organism content', $account)) {
  166. return FALSE;
  167. }
  168. return TRUE;
  169. }
  170. if ($op == 'update') {
  171. if (!user_access('edit chado_organism content', $account)) {
  172. return FALSE;
  173. }
  174. }
  175. if ($op == 'delete') {
  176. if (!user_access('delete chado_organism content', $account)) {
  177. return FALSE;
  178. }
  179. }
  180. if ($op == 'view') {
  181. if (!user_access('access chado_organism content', $account)) {
  182. return FALSE;
  183. }
  184. }
  185. return NULL;
  186. }
  187. /**
  188. * Set the permission types that the chado module uses. Essentially we
  189. * want permissionis that protect creation, editing and deleting of chado
  190. * data objects
  191. *
  192. *
  193. @ingroup tripal_organism
  194. */
  195. function tripal_organism_perm() {
  196. return array(
  197. 'access chado_organism content',
  198. 'create chado_organism content',
  199. 'delete chado_organism content',
  200. 'edit chado_organism content',
  201. 'adminster tripal organism',
  202. );
  203. }
  204. /**
  205. *
  206. * @ingroup tripal_organism
  207. */
  208. function tripal_organism_nodeapi(&$node, $op, $teaser, $page) {
  209. switch ($op) {
  210. case 'view':
  211. switch ($node->type) {
  212. }
  213. }
  214. }
  215. /**
  216. *
  217. * @ingroup tripal_organism
  218. */
  219. function tripal_organism_cron() {
  220. // we want to make sure that any new organisms or features that were
  221. // added to the database external to drupal automatically get new
  222. // nodes created for themselves in drupal.
  223. // tripal_organism_sync_organisms();
  224. }
  225. /**
  226. *
  227. * @ingroup tripal_organism
  228. */
  229. function chado_organism_validate($node, &$form) {
  230. // if this is an update, we want to make sure that a different organism doesn't
  231. // already have this genus and speces
  232. if ($node->organism_id) {
  233. $sql = "SELECT *
  234. FROM {organism} O
  235. WHERE genus = '%s' and species = '%s' AND NOT organism_id = %d";
  236. $result = db_fetch_object(chado_query($sql, $node->genus, $node->species, $node->organism_id));
  237. if ($result) {
  238. form_set_error('genus', t("Update cannot proceed. The organism genus
  239. '$node->genus' and species '$node->species' is already present in the database."));
  240. watchdog('tripal_organism',
  241. 'Update organism: genus and species already exists: %values',
  242. array('%values' => "genus = $node->genus, species = $node->species"),
  243. WATCHDOG_WARNING);
  244. }
  245. }
  246. // if this is an insert then check to make sure the genus and species are unique
  247. else {
  248. $values = array(
  249. 'genus' => $node->genus,
  250. 'species' => $node->species,
  251. );
  252. $organism = tripal_core_chado_select('organism', array('organism_id'), $values);
  253. if (sizeof($organism) > 0) {
  254. form_set_error('genus', 'Cannot add the organism with this genus and species.
  255. The organism already exists.');
  256. watchdog('tripal_organism',
  257. 'Insert organism: genus and species already exists: %values',
  258. array('%values' => "genus = $node->genus, species = $node->species"),
  259. WATCHDOG_WARNING);
  260. }
  261. }
  262. }
  263. /**
  264. * When a new chado_organism node is created we also need to add information
  265. * to our chado_organism table. This function is called on insert of a new node
  266. * of type 'chado_organism' and inserts the necessary information.
  267. *
  268. * @ingroup tripal_organism
  269. */
  270. function chado_organism_insert($node) {
  271. $values = array(
  272. 'genus' => $node->genus,
  273. 'species' => $node->species,
  274. 'abbreviation' => $node->abbreviation,
  275. 'common_name' => $node->common_name,
  276. 'comment' => $node->description
  277. );
  278. // if there is an organism_id in the $node object then this must be a sync so
  279. // we can skip adding the organism as it is already there, although
  280. // we do need to proceed with the rest of the insert
  281. if (!$node->organism_id) {
  282. $organism = tripal_core_chado_insert('organism', $values);
  283. if (!$organism) {
  284. drupal_set_message(t('Unable to add organism.', 'warning'));
  285. watchdog('tripal_organism', 'Insert Organism: Unable to create organism where values:%values',
  286. array('%values' => print_r($values, TRUE)), WATCHDOG_ERROR);
  287. return;
  288. }
  289. $organism_id = $organism['organism_id'];
  290. }
  291. else {
  292. $organism_id = $node->organism_id;
  293. }
  294. // Make sure the entry for this organism doesn't already exist in the
  295. // chado_organism table if it doesn't exist then we want to add it.
  296. if (!chado_get_id_for_node('organism', $node) ) {
  297. // next add the item to the drupal table
  298. $sql = "INSERT INTO {chado_organism} (nid, vid, organism_id) ".
  299. "VALUES (%d, %d, %d)";
  300. db_query($sql, $node->nid, $node->vid, $organism_id);
  301. }
  302. // set the title for the node
  303. $record = new stdClass();
  304. $record->title = "$node->genus $node->species";
  305. $record->nid = $node->nid;
  306. drupal_write_record('node', $record, 'nid');
  307. drupal_write_record('node_revisions', $record, 'nid');
  308. // add the image
  309. chado_organism_add_image($node);
  310. }
  311. /**
  312. * Update organisms
  313. *
  314. * @ingroup tripal_organism
  315. */
  316. function chado_organism_update($node) {
  317. if ($node->revision) {
  318. // there is no way to handle revisions in Chado but leave
  319. // this here just to make not we've addressed it.
  320. }
  321. $match = array(
  322. 'organism_id' => chado_get_id_for_node('organism', $node),
  323. );
  324. $values = array(
  325. 'genus' => $node->genus,
  326. 'species' => $node->species,
  327. 'abbreviation' => $node->abbreviation,
  328. 'common_name' => $node->common_name,
  329. 'comment' => $node->description
  330. );
  331. $org_status = tripal_core_chado_update('organism', $match, $values);
  332. // set the title for the node
  333. $record = new stdClass();
  334. $record->title = "$node->genus $node->species";
  335. $record->nid = $node->nid;
  336. drupal_write_record('node', $record, 'nid');
  337. drupal_write_record('node_revisions', $record, 'nid');
  338. // add the image
  339. chado_organism_add_image($node);
  340. }
  341. /**
  342. * Delete organism from both drupal and chado databases. Check dependency before
  343. * deleting from chado.
  344. *
  345. * @ingroup tripal_organism
  346. */
  347. function chado_organism_delete($node) {
  348. $organism_id = chado_get_id_for_node('organism', $node);
  349. // if we don't have an organism id for this node then this isn't a node of
  350. // type chado_organism or the entry in the chado_organism table was lost.
  351. if (!$organism_id) {
  352. return;
  353. }
  354. // Remove data from the {chado_organism}, {node}, and {node_revisions} tables
  355. $sql_del = "DELETE FROM {chado_organism} ".
  356. "WHERE nid = %d ".
  357. "AND vid = %d";
  358. db_query($sql_del, $node->nid, $node->vid);
  359. $sql_del = "DELETE FROM {node} ".
  360. "WHERE nid = %d ".
  361. "AND vid = %d";
  362. db_query($sql_del, $node->nid, $node->vid);
  363. $sql_del = "DELETE FROM {node_revisions} ".
  364. "WHERE nid = %d ".
  365. "AND vid = %d";
  366. db_query($sql_del, $node->nid, $node->vid);
  367. // Test dependency before deleting from chado database. If a library or
  368. // feature depends on this organism, don't delete it
  369. $sql = "SELECT feature_id FROM {feature} WHERE organism_id = %d";
  370. $check_feature = db_result(chado_query($sql, $organism_id));
  371. $sql = "SELECT library_id FROM {library} WHERE organism_id = %d";
  372. $check_lib = db_result(chado_query($sql, $organism_id));
  373. if ($check_lib == 0 && $check_feature == 0) {
  374. tripal_core_chado_delete('organism', array('organism_id' => $organism_id));
  375. }
  376. else {
  377. drupal_set_message(t("Organism deleted from drupal. Warning: at least one ".
  378. "library or feature depends on this organism. It was ".
  379. "not removed from chado."));
  380. }
  381. }
  382. /**
  383. *
  384. *
  385. * @ingroup tripal_organism
  386. */
  387. function chado_organism_add_image($node) {
  388. // check to see if a file was uploaded. If so then copy it to the images
  389. // directory for display with the organism
  390. if (isset($_FILES['files']) && $_FILES['files']['name']['organism_image'] &&
  391. is_uploaded_file($_FILES['files']['tmp_name']['organism_image'])) {
  392. $dest = file_directory_path() . "/tripal/tripal_organism/images";
  393. $validators = array(
  394. 'file_validate_is_image' => array(),
  395. );
  396. file_check_directory($dest, FILE_CREATE_DIRECTORY, 'organism_image');
  397. if (!$file = file_save_upload('organism_image', $validators, $dest)) {
  398. drupal_set_message(t("Organism image was not uploaded."));
  399. }
  400. // move this image into the images directory
  401. file_move($file->filepath, $dest . "/" . $node->nid . ".jpg", FILE_EXISTS_REPLACE);
  402. }
  403. }
  404. /**
  405. * When editing or creating a new node of type 'chado_organism' we need
  406. * a form. This function creates the form that will be used for this.
  407. *
  408. * @ingroup tripal_organism
  409. */
  410. function chado_organism_form($node, $param) {
  411. $organism = $node->organism;
  412. // add in the comment since it is a text field and may not be included if too big
  413. $organism = tripal_core_expand_chado_vars($organism, 'field', 'organism.comment');
  414. // get form defaults
  415. $abbreviation = $node->abbreviation;
  416. if (!$abbreviation) {
  417. $abbreviation = $organism->abbreviation;
  418. }
  419. $genus = $node->genus;
  420. if (!$genus) {
  421. $genus = $organism->genus;
  422. }
  423. $species = $node->species;
  424. if (!$species) {
  425. $species = $organism->species;
  426. }
  427. $common_name = $node->common_name;
  428. if (!$common_name) {
  429. $common_name = $organism->common_name;
  430. }
  431. $description = $node->description;
  432. if (!$description) {
  433. $description = $organism->comment;
  434. }
  435. $organism_image = $node->organism_image;
  436. $form = array();
  437. $form['#attributes']['enctype'] = 'multipart/form-data';
  438. // keep track of the organism id if we have one. If we do have one then
  439. // this would indicate an update as opposed to an insert.
  440. $form['organism_id'] = array(
  441. '#type' => 'value',
  442. '#value' => $organism->organism_id,
  443. );
  444. $form['abbreviation']= array(
  445. '#type' => 'textfield',
  446. '#title' => t('Abbreviation'),
  447. '#required' => TRUE,
  448. '#default_value' => $organism->abbreviation,
  449. '#weight' => 3
  450. );
  451. $form['genus']= array(
  452. '#type' => 'textfield',
  453. '#title' => t('Genus'),
  454. '#required' => TRUE,
  455. '#default_value' => $organism->genus,
  456. '#weight' => 1
  457. );
  458. $form['species']= array(
  459. '#type' => 'textfield',
  460. '#title' => t('Species'),
  461. '#required' => TRUE,
  462. '#default_value' => $organism->species,
  463. '#weight' => 2
  464. );
  465. $form['common_name']= array(
  466. '#type' => 'textfield',
  467. '#title' => t('Common Name'),
  468. '#required' => TRUE,
  469. '#default_value' => $organism->common_name,
  470. '#weight' => 4
  471. );
  472. $form['description']= array(
  473. '#type' => 'textarea',
  474. '#rows' => 15,
  475. '#title' => t('Description'),
  476. '#required' => TRUE,
  477. '#default_value' => $organism->comment,
  478. '#weight' => 5
  479. );
  480. $form['organism_image']= array(
  481. '#type' => 'file',
  482. '#title' => t('Organism Image'),
  483. '#description' => 'Add an image for this organism',
  484. '#weight' => 6
  485. );
  486. return $form;
  487. }
  488. /**
  489. * When a node is requested by the user this function is called to allow us
  490. * to add auxiliary data to the node object.
  491. *
  492. * @ingroup tripal_organism
  493. */
  494. function chado_organism_load($node) {
  495. // find the organism and add in the details
  496. $organism_id = chado_get_id_for_node('organism', $node);
  497. $values = array('organism_id' => $organism_id);
  498. $organism = tripal_core_generate_chado_var('organism', $values);
  499. // add in the description field
  500. $organism = tripal_core_expand_chado_vars($organism, 'field', 'organism.comment');
  501. $additions = new stdClass();
  502. $additions->organism = $organism;
  503. return $additions;
  504. }
  505. /**
  506. * This function customizes the view of the chado_organism node. It allows
  507. * us to generate the markup.
  508. *
  509. * @ingroup tripal_organism
  510. */
  511. function chado_organism_view($node, $teaser = FALSE, $page = FALSE) {
  512. // use drupal's default node view:
  513. $node = node_prepare($node, $teaser);
  514. return $node;
  515. }
  516. /**
  517. * Display help and module information
  518. * @param path which path of the site we're displaying help
  519. * @param arg array that holds the current path as would be returned from arg()
  520. * function
  521. * @return help text for the path
  522. *
  523. * @ingroup tripal_organism
  524. */
  525. function tripal_organism_help($path, $arg) {
  526. $output = '';
  527. switch ($path) {
  528. case "admin/help#tripal_organism":
  529. $output = '<p>'.
  530. t("Displays links to nodes created on this date") .
  531. '</p>';
  532. break;
  533. }
  534. return $output;
  535. }
  536. /**
  537. * This function uses organism_id's of all drupal organism nodes as input and
  538. * pull the organism information (genus, species, common_name, comment) from
  539. * chado database. The return type is an object array that stores $organism
  540. * objects sorted by common_name
  541. *
  542. * @ingroup tripal_organism
  543. */
  544. function get_chado_organisms() {
  545. $sql_drupal = "SELECT COUNT (organism_id) FROM {chado_organism}";
  546. $no_orgs = db_result(db_query($sql_drupal));
  547. if ($no_orgs != 0) {
  548. $sql = "SELECT organism_id, nid FROM {chado_organism}";
  549. $result = chado_query($sql);
  550. $sql = "SELECT genus, species, common_name, comment ".
  551. "FROM {Organism} ".
  552. "WHERE organism_id=%d";
  553. $organisms = array();
  554. $count = 0;
  555. while ($data = db_fetch_object($result)) {
  556. $organism = db_fetch_object(chado_query($sql, $data->organism_id));
  557. $organism->node_id = $data->nid;
  558. // Use common_name plus $count as the key so we can sort by common
  559. // name later. Since common_name is not unique, we need to add $count
  560. // to the key
  561. $key = drupal_strtolower($organism->common_name) . $count;
  562. $organisms [$key] = $organism;
  563. $count ++;
  564. }
  565. //Sort organisms by common name
  566. ksort($organisms, SORT_STRING);
  567. return $organisms;
  568. }
  569. }
  570. /**
  571. * Implements hook_views_api()
  572. * Purpose: Essentially this hook tells drupal that there is views support for
  573. * for this module which then includes tripal_db.views.inc where all the
  574. * views integration code is
  575. *
  576. * @ingroup tripal_organism
  577. */
  578. function tripal_organism_views_api() {
  579. return array(
  580. 'api' => 2.0,
  581. );
  582. }
  583. /**
  584. *
  585. *
  586. * @ingroup tripal_organism
  587. */
  588. function tripal_organism_job_describe_args($callback, $args) {
  589. $new_args = array();
  590. if ($callback == 'tripal_organism_sync_organisms') {
  591. $organism = tripal_core_chado_select('organism', array('genus', 'species'), array('organism_id' => $args[0]));
  592. $new_args['Organism'] = $organism[0]->genus ." ". $organism[0]->species;
  593. }
  594. return $new_args;
  595. }

Related topics