tripal_stock-administration.inc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. <?php
  2. // $Id$
  3. /**
  4. * Purpose: Provide Guidance to new Tripal Admin
  5. *
  6. * @return
  7. * HTML Formatted text
  8. *
  9. * @ingroup tripal_stock
  10. */
  11. function tripal_stock_module_description_page() {
  12. $text = '';
  13. $text .= '<h3>Description:</h3>';
  14. //================================================================================
  15. $text .= '<p>The Tripal Stock Module provides functionality for adding, editing, deleting and accessing chado stocks. The stock module was designed to store information about stock collections in a laboratory. What is called a stock could also be called a strain or an accession. There is a lot in common between a Drosophila stock and a Saccharomyces strain and an Arabidopsis line. They all come from some taxon, have genotypes, physical locations in the lab, some conceivable relationship with a publication, some conceivable relationship with a sequence feature (such as a transgene), and could be described by some ontology term. For more information about the chado Stock Module <a href="http://gmod.org/wiki/Chado_Stock_Module">see the GMOD Wiki Page</a></p>';
  16. $text .= '<h3>Post Installation Steps:</h3>';
  17. //================================================================================
  18. $text .= '<p>Since at the time of this modules developement there is no accepted ontology for describing stocks, their properties and relationships, this module allows you to select the controlled vocabularies (CVs) in your Chado Database you would like to govern these data.</p>';
  19. $text .= '<b>To Set the Controlled Vocabularies for Stocks:</b>';
  20. $text .= '<ol>';
  21. $text .= '<li>Ensure your Controlled Vocabulary is in Chado</li>';
  22. $text .= '<ol type="i">';
  23. $text .= '<li>Load your Ontology into Chado using the <a href="tripal_cv/ontology_loader">Tripal Ontology Loader</a></li>';
  24. $text .= '<li> Create your ontology from scratch by first <a href="tripal_cv/add_cv">creating a controlled vocabulary</a> and then <a href="tripal_cv/add_cvterm">adding terms to it</a>.</li>';
  25. $text .= '</ol>';
  26. $text .= '<li>Then go to the <a href="tripal_stock/configuration">Configuration Page for Stocks</a> and, in the "Set Stock Controlled Vocabularies" Fieldset, select the Controlled Vocaulary name for Stock Types, Stock Properties and Stock Relationship Types.</li>';
  27. $text .= '<ol type="i">';
  28. $text .= '<li>Stock Types: When you are creating stocks, the type of each stock must be indicated. This might include "DNA extraction", "Individual Plant/Animal" or even "Progeny Population".</li>';
  29. $text .= '<li>Stock Properties: This module also allows you to assign properties to any stock. Each property has a type and a value where type is required an value is not. Therefore, if you want to say that a stock was grown at 23 degrees Celcius then the Type would be "temperature grown at" and the value would be 23 degrees Celcius. As such the Stock Properties controlled vocabulary might include "temperature grown at", "diet", "extraction date", "stock location", etc.</li>';
  30. $text .= '<li>Stock Relationship Types: You can also specify relationships between stocks. For example, a stock of type="DNA extraction" (Stock 1a) is related to the stock of type="Individual Plant/Animal" (Stock 1) that it was extracted from. Thus you might specify the relationship Stock 1 is the source material for Stock 1a where the relationship type is "is the source material for". As such Stock Relationship Types might include "is the source material for", "is maternal parent of", "is individual of population", etc.</li>';
  31. $text .= '</ol>';
  32. $text .= '</ol>';
  33. $text .= '<p>This module also provides <b>User Permissions</b> to control which users or groups of users (roles) can view/access stock content (access chado_stock content), create stocks (create chado_stock content), edit or delete stocks (edit chado_stock content or delete chado_stock content). The default is that only the original administration account has these permissions. To allow additional users/roles any combination of the above permissions:</p>';
  34. $text .= '<ol>';
  35. $text .= '<li><a href="../user/roles">Add Roles</a> to provide permissions to. For example, you might want a "View Tripal Stock Content" and a "Manage Tripal Stock Content" Role. If you only want to provide permissions based on whether the user is logged in (authenticated) or not (anonymous) then you don\'t need to create roles.</li>';
  36. $text .= '<li><a href="../user/permissions">Assign permissions</a> to roles. Specically focus on those mentioned above, then for each permission add a checkmark to the rolw (columns) that you want to have this permission.</li>';
  37. $text .= '<li><a href="../user/user">Assign Users Roles</a>. This is what gives a given user the set of permissions associated with a given role. Notice that you can assign more than one role to a user and that each user is "Authenticated" by default. A user has permission is any of his/her roles have that permission.</li>';
  38. $text .= '</ol>';
  39. $text .= '<p>Another important step, <b>if you chado database already contains stocks, is to sync\' Chado with Drupal</b>. This creates Drupal Content including detail pages for each stock (known as nodes in Drupal). To sync\' Chado with Drupal simply go to the <a href="tripal_stock/configuration">Configuration Page for Stocks</a> and in the "Sync Stocks" Fieldset select the Organisms whose associated stocks you would like to sync. If this list doesn\'t contain an organism which you know is in Chado go to the Organism Configuration Page and make sure it is sync\'d with Drupal.</p>';
  40. $text .= '<h3>Features of this Module:</h3>';
  41. //================================================================================
  42. $text .= '<b><a href="../../node/add/chado_stock">Create a Generic Stock:</a></b>';
  43. $text .= '<p>This allows you to create content in your drupal and chado for a stock (only the unique stock identifier is duplicated). A Generic Stock must have a unique name, a type and an organism. In addition, you can optionally supply a more human-readable name, a primary database reference and even a short description. The Create Generic Stock form is a multistep form with the first step creating the Basic stock (stored in the stock table). All the remaining steps are optional and descriptions of each follow:</p>';
  44. $text .= '<ol type="i">';
  45. $text .= '<li>The Next Step is to Add Properties to the newly created stock. Properties allow you to specify additional details about a given stock. Since the types of properties you can add are goverened by a controlled vocaulary that you can create, you have complete control over what additional properties you want to allow.</li>';
  46. $text .= '<li>Then you can Add External Database References. A Database Reference can be thought of as a synonym for the current stock where you want to specify a source for that synonym. The source would then be thought of as the database where a database can either be online and provide automatic linking out to the synonymous record or offline and simply be a text name of the source. To create a database reference with a given source you must first add the database to chado <a href="tripal_db/add_db">here</a>.</li>';
  47. $text .= '<li>Finally you can Add Relationships between Stocks. This allows you to specify, for example, the source material of a stock or one of it\'s parents. To create a relationship between your newly added stock and another stock, the other stock must first be created as this one was. Also, since the types of relationships is governed by a controlled vocabulary, just like with properties you have complete control over which relationships you want to allow. Once you click "Finish" you will be re-directed to the Details Page of the new Stock.</li>';
  48. $text .= '</ol>';
  49. $text .= '<b>Details Page of a Stock:</b>';
  50. $text .= '<p>Each stock get\'s it\'s own page on this website. This page is meant to give an overall picture of the stock including listing the basic details, as well as, all properties, database references and relationships. To understand where it is -All page content in Drupal is known as a node and is given a unique identifier or nid. Thus every drupal page has a path of node/<nid>. You can get to the Details page for a given stock from either of the stock listings described below.</p>';
  51. $text .= '<p>If you want to customize the look of the stock Details page simply copy the PHP/HTML template node-chado_stock.tpl.php from theme_tripal to the base theme you are currently using. Then edit it as desired. There are plans to integrate this details page with Drupal Panels which will provide a much more user-friendly and no-programming-needed method to customize this page.</p>';
  52. $text .= '<b>Adding/Updating/Deleting Stocks and their Properties, Database References and Relationships:</b>';
  53. $text .= '<p>The Stock Details Page also acts as a landing pad for updating/deleting stocks. To <b>update a stock</b>, go to the stocks details page and click on the Edit tab near the top of the page. This tab will only be visable if you have permission to edit chado stock content (See post installation steps above for information on setting user permissions). If you want to <b>delete a stock</b>, click the Edit tab and then near the bottom of the form, click the Delete button. This will delete the entire stock including it\'s properties, database references and any relationships including it.</p>';
  54. $text .= '<p>To <b>update/delete a given property of a stock</b>, click the "Edit Properties" Tab near the top of the stock details page. This form provides a listing of all existing properties for the given stock with form elements allowing you to change their value. After editing the properties you wanted to, simply click the "Update Properties" button to update all the properties for that stock. To delete a given property simply click the "Delete" Button beside the property you want to delete. You cannot undo this action! To <b>add a property to the given stock</b> simply fill out the "Add Property" form at the bottom of the "Edit Properties" Tab.</p>';
  55. $text .= '<p><b>Adding, updating and deleting Database References and Relationships</b> for a given stock is exactly the same as the method for properties. To edit Database References, click the "Edit DB References" tab and to add/edit/update stock relationships, click the "Edit Relationships" tab.</p>';
  56. $text .= '<b><a href="../../stocks">Basic Listing of Stocks:</a></b>';
  57. $text .= '<p>This module also provides a basic listing of all stocks currently sync\'d with Drupal. To access this listing, there should be a Stocks Primary Menu item which links you to <a href="../../stocks">this page</a>. This page lists each stock on it\'s own row and provides a link to each stock by clicking on it\'s name. Currently there is no way to easily customize this listing.</p>';
  58. $text .= '<b><a href="../build/views/">Flexible Listing of Stocks using Drupal Views:</a></b>';
  59. $text .= '<p>In order to access a more flexible listing of stocks you must first install the <a href="http://drupal.org/project/views">Drupal Views2 module</a>. You should then be able to access the default views <a href="../build/views/">here</a>. Essentially, Views is a module which allows you to create custom SQL queries completely through the web interface without knowing SQL. Furthermore, it also does some formatting of the results allowing you to display them as HTML lists, tables or grids. You can also expose filters to the user to let them customize the results they see and even implement various sorting.</p>';
  60. $text .= '<p>To use one of the Default Views simply click "Enable" and then "Edit" to change it to show exactly what you want. To view the current listing simply clikc "View Page" at the top of the Edit user interface. There are a number of good tutorials out there for Views2, any of which can be used to help you create your own custom listings of biological content. (Note: there aren\'t any tutorials specifically for tripal content but any tutorial for Views2 will show you how to use the views interface.</p>';
  61. return $text;
  62. }
  63. /**
  64. * Purpose: Provide administration options for chado_stocks
  65. *
  66. * @return
  67. * Form array (as described by the drupal form api)
  68. *
  69. * @ingroup tripal_stock
  70. */
  71. function tripal_stock_admin() {
  72. $form = array();
  73. // before proceeding check to see if we have any
  74. // currently processing jobs. If so, we don't want
  75. // to give the opportunity to sync Stocks
  76. $active_jobs = FALSE;
  77. if(tripal_get_module_active_jobs('tripal_stock')){
  78. $active_jobs = TRUE;
  79. }
  80. if($active_jobs){
  81. $form['notice'] = array(
  82. '#type' => 'fieldset',
  83. '#title' => t('Stock Management Temporarily Unavailable')
  84. );
  85. $form['notice']['message'] = array(
  86. '#value' => t("Currently, stock management jobs are waiting or ".
  87. "are running. Managemment features have been hidden until these ".
  88. "jobs complete. Please check back later once these jobs have ".
  89. "finished. You can view the status of pending jobs in the Tripal ".
  90. "jobs page."),
  91. );
  92. } else {
  93. // SET Vocabularies -----------------------------------------------------------------------------------------
  94. $form['set_cv'] = array(
  95. '#type' => 'fieldset',
  96. '#title' => t('Set Stock Controlled Vocabularies'),
  97. '#weight' => -10
  98. );
  99. $form['set_cv']['message'] = array(
  100. '#value' => t("This setting allows you to set which chado controlled vocabularies (cv)"
  101. ." are used. Cvs are used to control user input for the type of stock,"
  102. ." any properties they enter for a stock & the types of relationships"
  103. ." between stocks. Only cvs already loaded into chado can be selected here.")
  104. );
  105. $cv_options = tripal_cv_get_cv_options();
  106. $form['set_cv']['stock_types_cv'] = array(
  107. '#type' => 'select',
  108. '#title' => t('Controlled Vocabulary governing Stock Types'),
  109. '#options' => $cv_options,
  110. '#default_value' => variable_get('chado_stock_types_cv', 0)
  111. );
  112. $form['set_cv']['stock_prop_types_cv'] = array(
  113. '#type' => 'select',
  114. '#title' => t('Controlled Vocabulary governing Types of Stock Properties'),
  115. '#description' => t("This cv must contain a cvterm entry where name='synonym'."),
  116. '#options' => $cv_options,
  117. '#default_value' => variable_get('chado_stock_prop_types_cv', 0)
  118. );
  119. $form['set_cv']['stock_relationship_cv'] = array(
  120. '#type' => 'select',
  121. '#title' => t('Controlled Vocabulary governing Types of Relationsips between Stocks'),
  122. '#options' => $cv_options,
  123. '#default_value' => variable_get('chado_stock_relationship_cv', 0)
  124. );
  125. $form['set_cv']['button'] = array(
  126. '#type' => 'submit',
  127. '#value' => t('Set Controlled Vacabularies')
  128. );
  129. // SYNC STOCKS-----------------------------------------------------------------------------------------------
  130. $form['sync'] = array(
  131. '#type' => 'fieldset',
  132. '#title' => t('Sync Stocks'),
  133. '#weight' => -10
  134. );
  135. $form['sync']['description'] = array(
  136. '#type' => 'item',
  137. '#value' => t("Click the 'Sync all Germplasm' button to create Drupal ".
  138. "content for stocks in chado. Depending on the ".
  139. "number of stocks in the chado database this may take a long ".
  140. "time to complete. ")
  141. );
  142. $form['sync']['organisms'] = array(
  143. '#type' => 'checkboxes',
  144. '#title' => t('Organisms for which Stocks should be sync\'d'),
  145. '#description' => t('Only sync\'d Organisms are listed. Leaving an organism unchecked does not delete already sync\'d Stocks.'),
  146. '#options' => tripal_organism_get_organism_options(),
  147. '#required' => FALSE,
  148. '#prefix' => '<div id="lib_boxes">',
  149. '#suffix' => '</div>'
  150. );
  151. $form['sync']['button'] = array(
  152. '#type' => 'submit',
  153. '#value' => t('Sync Stocks')
  154. );
  155. }
  156. return system_settings_form($form);
  157. }
  158. /**
  159. * Implements hook_form_validate(): Validates user input
  160. *
  161. * @param $form
  162. * An array describing the form that was rendered
  163. * @param $form_state
  164. * An array describing the current state of the form including user input
  165. *
  166. * @ingroup tripal_stock
  167. */
  168. function tripal_stock_admin_validate($form, &$form_state) {
  169. global $user; // we need access to the user info
  170. $job_args = array();
  171. // Sync Stocks
  172. if ($form_state['values']['op'] == t('Sync Stocks')) {
  173. // Array organism_id => organims common_name
  174. // which only includes those organisms which the user wants to select stocks for
  175. $organisms_2b_syncd = $form_state['values']['organisms'];
  176. //for each organism selected submit job (handled by tripal_stock_sync_stock_set)
  177. // which syncs all stocks with an organism_id equal to the selelcted organism
  178. foreach ( $organisms_2b_syncd as $organism_id ) {
  179. if($organism_id != 0) {
  180. $job_args[0] = $organism_id;
  181. tripal_add_job("Sync Stocks from Organism $organism_id",'tripal_stock',
  182. 'tripal_stock_sync_stock_set',$job_args,$user->uid);
  183. }
  184. }
  185. }
  186. if ($form_state['values']['op'] == t('Set Controlled Vacabularies')) {
  187. variable_set('chado_stock_types_cv', $form_state['values']['stock_types_cv']);
  188. variable_set('chado_stock_prop_types_cv', $form_state['values']['stock_prop_types_cv']);
  189. variable_set('chado_stock_relationship_cv', $form_state['values']['stock_relationship_cv']);
  190. }
  191. }
  192. /**
  193. * Syncs all Stocks associated with an organism
  194. *
  195. * Note: Handling of multiple organisms is done in tripal_stock_admin_validate()
  196. *
  197. * @param $organism_id
  198. * The chado primary key of the organism for which stocks should be sync'd
  199. * @param $job_id
  200. * The tripal job ID
  201. *
  202. * @return
  203. * TRUE if successful; FALSE otherwise
  204. *
  205. * @ingroup tripal_stock
  206. */
  207. function tripal_stock_sync_stock_set($organism_id, $job_id) {
  208. global $user;
  209. if(!$organism_id) {
  210. print '0 Stocks to Sync -No Organisms Selected.\n';
  211. } else {
  212. // Get list of stocks to sync
  213. $previous_db = tripal_db_set_active('chado');
  214. $result = db_query(
  215. "SELECT stock_id, uniquename, type_id, organism_id FROM stock WHERE organism_id=%d",
  216. $organism_id
  217. );
  218. tripal_db_set_active($previous_db);
  219. $stocks_created_count = 0; //keeps track of total number of stocks successfully created
  220. $stocks_attempted = 0;
  221. // foreach stock to be sync'd -> create node & add stock_id
  222. while ( $r = db_fetch_object($result) ) {
  223. // $r is the current stock to be sync'd
  224. $stocks_attempted++;
  225. print 'Processing '.$r->uniquename."\n";
  226. // check not already in drupal
  227. $in_drupal_query = db_query(
  228. "SELECT * FROM {chado_stock} WHERE stock_id=%d",
  229. $r->stock_id
  230. );
  231. if ( !db_fetch_object($in_drupal_query) ) {
  232. //create new chado_stock node
  233. $new_node = new stdClass();
  234. $new_node->type = 'chado_stock';
  235. $new_node->uid = $user->uid;
  236. $new_node->title = $r->uniquename;
  237. $new_node->type_id = $r->type_id;
  238. $new_node->organism_id = $r->organism_id;
  239. $new_node->stock_id = $r->stock_id;
  240. //print 'New Node:';
  241. //print_r($new_node);
  242. node_validate($new_node);
  243. if(!form_get_errors()){
  244. //print 'Try to Create Node ';
  245. $node = node_submit($new_node);
  246. node_save($node);
  247. if($node->nid){
  248. $stocks_created_count++;
  249. //Add stock id to chado_stock table
  250. db_query(
  251. "UPDATE {chado_stock} SET stock_id=%d WHERE nid=%d AND vid=%d",
  252. $r->stock_id,
  253. $node->nid,
  254. $node->vid
  255. );
  256. }
  257. } else {
  258. print "\tCreate Stock Form Errors: ";
  259. print_r(form_get_errors());
  260. }
  261. print "\n\tNid=".$node->nid."\n";
  262. } else {
  263. print "\tSkipped $r->uniquename because it's already in drupal.\n";
  264. } //end of if not already in drupal
  265. } //end of while still stocks to be sync'd
  266. } //end of if organism_id not supplied
  267. if ($stocks_attempted == 0) {
  268. print "No stocks retrieved for organism (".$organism_id.")\n";
  269. return 1;
  270. } else {
  271. if ($stocks_created_count > 0) {
  272. print "$stocks_created_count Stocks Successfully Created\n";
  273. return 1;
  274. } else {
  275. return 0;
  276. }
  277. }
  278. }