name variable. Therefore, the SQL statement used is 'SELECT name AS
* analysisname FROM Analysis', instead of 'SELECT name FROM Analysis'. All
* other node variables have exact same name as the column name.
******************************************************************************/
require('tripal_analysis.api.inc');
/*************************************************************************
*
*
* @ingroup tripal_analysis
*/
function tripal_analysis_register_child($modulename){
$sql = "INSERT INTO {tripal_analysis} (modulename) VALUES ('%s')";
db_query($sql, $modulename);
}
/*************************************************************************
*
*
* @ingroup tripal_analysis
*/
function tripal_analysis_unregister_child($modulename){
if (db_table_exists('tripal_analysis')) {
$sql = "DELETE FROM {tripal_analysis} WHERE modulename = '%s'";
db_query($sql, $modulename);
}
}
/******************************************************************************
*
* @ingroup tripal_analysis
*/
function tripal_analysis_init(){
drupal_add_js(drupal_get_path('theme', 'tripal').'/js/tripal_analysis.js');
}
/*******************************************************************************
* tripal_analysis_menu()
* HOOK: Implementation of hook_menu()
* Entry points and paths of the module
*
* @ingroup tripal_analysis
*/
function tripal_analysis_menu() {
// Display available analyses
$items['analyses'] = array(
'menu_name' => ('primary-links'), //Enable the 'Analysis' primary link
'title' => t('Analyses'),
'page callback' => 'tripal_analysis_show_analyses',
'access arguments' => array('access chado_analysis content'),
'type' => MENU_NORMAL_ITEM
);
//Sync analysis
$items['chado_sync_analyses'] = array(
'title' => t('Sync Data'),
'page callback' => 'tripal_analysis_sync_analyses',
'access arguments' => array('administer site configuration'),
'type' => MENU_CALLBACK
);
// Tripal Analysis administrative settings
$items['admin/tripal/tripal_analysis'] = array(
'title' => 'Analyses',
'description' => 'Basic Description of Tripal Analysis Module Functionality.',
'page callback' => 'tripal_analysis_module_description_page',
'access arguments' => array('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
'file' => 'tripal_analysis.admin.inc',
);
$items['admin/tripal/tripal_analysis/configuration'] = array(
'title' => 'Configuration',
'description' => 'Settings for the displays of analysis results.',
'page callback' => 'drupal_get_form',
'page arguments' => array('tripal_analysis_admin'),
'access arguments' => array('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
'file' => 'tripal_analysis.admin.inc',
);
return $items;
}
/*******************************************************************************
* Display the summary view of analyses when click on the 'Analyses'
* primary-link
*
* @ingroup tripal_analysis
*/
function tripal_analysis_show_analyses (){
// Show libraries stored in Drupal's {chado_analysis} table
$sql = "SELECT COUNT(analysis_id) FROM {chado_analysis}";
$no_ana = db_result(db_query ($sql));
if($no_ana != 0) {
$analyses = get_chado_analyses ();
return theme('tripal_analysis_analysis_page', $analyses);
} else {
return t("No analysis available at this time.");
}
}
/*******************************************************************************
* Provide information to drupal about the node types that we're creating
* in this module
*
* @ingroup tripal_analysis
*/
function tripal_analysis_node_info() {
$nodes = array();
$nodes['chado_analysis'] = array(
'name' => t('Analysis'),
'module' => 'chado_analysis',
'description' => t('An analysis from the chado database'),
'has_title' => FALSE,
'title_label' => t('Analysis'),
'has_body' => FALSE,
'body_label' => t('Analysis Description'),
'locked' => TRUE
);
return $nodes;
}
/*******************************************************************************
* When a new chado_analysis node is created we also need to add information
* to our chado_analysis table. This function is called on insert of a new
* node of type 'chado_analysis' and inserts the necessary information.
*
* @ingroup tripal_analysis
*/
function chado_analysis_insert($node){
global $user;
// Create a timestamp so we can insert it into the chado database
$time = $node->timeexecuted;
$month = $time['month'];
$day = $time['day'];
$year = $time['year'];
$timestamp = $month.'/'.$day.'/'.$year;
// If this analysis already exists then don't recreate it in chado
$analysis_id = $node->analysis_id;
if ($analysis_id) {
$sql = "SELECT analysis_id ".
"FROM {Analysis} ".
"WHERE analysis_id = %d ";
$previous_db = tripal_db_set_active('chado');
$analysis = db_fetch_object(db_query($sql, $node->analysis_id));
tripal_db_set_active($previous_db);
}
// If the analysis doesn't exist then let's create it in chado.
if(!$analysis){
// First add the item to the chado analysis table
$sql = "INSERT INTO {analysis} ".
" (name, description, program, programversion, algorithm, ".
" sourcename, sourceversion, sourceuri, timeexecuted) ".
"VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s')";
$previous_db = tripal_db_set_active('chado'); // use chado database
db_query($sql,$node->analysisname, $node->description,
$node->program,$node->programversion,$node->algorithm,
$node->sourcename, $node->sourceversion, $node->sourceuri,
$timestamp);
tripal_db_set_active($previous_db);
}
// Make sure the entry for this analysis doesn't already exist in the
// chado_analysis table if it doesn't exist then we want to add it.
$node_check_sql = "SELECT * FROM {chado_analysis} ".
"WHERE analysis_id = %d";
$node_check = db_fetch_object(db_query($node_check_sql, $analysis_id));
if(!$node_check){
// next add the item to the drupal table
$sql = "INSERT INTO {chado_analysis} (nid, vid, analysis_id) ".
"VALUES (%d, %d, %d)";
db_query($sql,$node->nid,$node->vid,$analysis_id);
// Create a title for the analysis node using the unique keys so when the
// node is saved, it will have a title
$record = new stdClass();
// If the analysis has a name, use it as the node title. If not, construct
// the title using program, programversion, and sourcename
if ($node->analysisname) {
$record->title = $node->analysisname;
} else {
//Construct node title as "program (version)
$record->title = "$node->program ($node->programversion)";
}
$record->nid = $node->nid;
drupal_write_record('node',$record,'nid');
drupal_write_record('node_revisions',$record,'nid');
}
}
/*******************************************************************************
*
* @ingroup tripal_analysis
*/
function chado_analysis_delete($node){
// Before removing, get analysis_id so we can remove it from chado database
// later
$sql_drupal = "SELECT analysis_id ".
"FROM {chado_analysis} ".
"WHERE nid = %d ".
"AND vid = %d";
$analysis_id = db_result(db_query($sql_drupal, $node->nid, $node->vid));
// Remove data from the {chado_analysis}, {node}, and {node_revisions} tables
$sql_del = "DELETE FROM {chado_analysis} ".
"WHERE nid = %d ".
"AND vid = %d";
db_query($sql_del, $node->nid, $node->vid);
$sql_del = "DELETE FROM {node} ".
"WHERE nid = %d ".
"AND vid = %d";
db_query($sql_del, $node->nid, $node->vid);
$sql_del = "DELETE FROM {node_revisions} ".
"WHERE nid = %d ".
"AND vid = %d";
db_query($sql_del, $node->nid, $node->vid);
//Remove from analysis and analysisprop tables of chado database as well
$previous_db = tripal_db_set_active('chado');
db_query("DELETE FROM {analysis} WHERE analysis_id = %d", $analysis_id);
tripal_db_set_active($previous_db);
}
/*******************************************************************************
* Update analyses
*
* @ingroup tripal_analysis
*/
function chado_analysis_update($node){
global $user;
if($node->revision){
// TODO -- decide what to do about revisions
} else {
// Create a timestamp so we can insert it into the chado database
$time = $node->timeexecuted;
$month = $time['month'];
$day = $time['day'];
$year = $time['year'];
$timestamp = $month.'/'.$day.'/'.$year;
// get the analysis_id for this node:
$sql = "SELECT analysis_id ".
"FROM {chado_analysis} ".
"WHERE vid = %d";
$analysis_id = db_fetch_object(db_query($sql, $node->vid))->analysis_id;
$sql = "UPDATE {analysis} ".
"SET name = '%s', ".
" description = '%s', ".
" program = '%s', ".
" programversion = '%s', ".
" algorithm = '%s', ".
" sourcename = '%s', ".
" sourceversion = '%s', ".
" sourceuri = '%s', ".
" timeexecuted = '%s' ".
"WHERE analysis_id = %d ";
$previous_db = tripal_db_set_active('chado'); // use chado database
db_query($sql, $node->analysisname, $node->description, $node->program,
$node->programversion,$node->algorithm,$node->sourcename,
$node->sourceversion, $node->sourceuri, $timestamp, $analysis_id);
tripal_db_set_active($previous_db); // switch back to drupal database
// Create a title for the analysis node using the unique keys so when the
// node is saved, it will have a title
$record = new stdClass();
// If the analysis has a name, use it as the node title. If not, construct
// the title using program, programversion, and sourcename
if ($node->analysisname) {
$record->title = $node->analysisname;
} else {
//Construct node title as "program (version)
$record->title = "$node->program ($node->programversion)";
}
$record->nid = $node->nid;
drupal_write_record('node',$record,'nid');
drupal_write_record('node_revisions',$record,'nid');
}
}
/*******************************************************************************
* When editing or creating a new node of type 'chado_analysis' we need
* a form. This function creates the form that will be used for this.
*
* @ingroup tripal_analysis
*/
function chado_analysis_form ($node){
$type = node_get_types('type', $node);
$form = array();
$form['title']= array(
'#type' => 'hidden',
'#default_value' => $node->title,
);
$form['analysisname']= array(
'#type' => 'textfield',
'#title' => t('Analysis Name'),
'#required' => FALSE,
'#default_value' => $node->analysisname,
'#description' => t("This should be a handy short identifier that
describes the analysis succintly as possible which helps the user find analyses."),
'#weight' => 1
);
$form['program']= array(
'#type' => 'textfield',
'#title' => t('Program'),
'#required' => TRUE,
'#default_value' => $node->program,
'#description' => t("Program name, e.g. blastx, blastp, sim4, genscan."),
'#weight' => 2
);
$form['programversion']= array(
'#type' => 'textfield',
'#title' => t('Program Version'),
'#required' => TRUE,
'#default_value' => $node->programversion,
'#description' => t("Version description, e.g. TBLASTX 2.0MP-WashU [09-Nov-2000]"),
'#weight' => 3
);
$form['algorithm']= array(
'#type' => 'textfield',
'#title' => t('Algorithm'),
'#required' => FALSE,
'#default_value' => $node->algorithm,
'#description' => t("Algorithm name, e.g. blast."),
'#weight' => 4
);
$form['sourcename']= array(
'#type' => 'textfield',
'#title' => t('Source Name'),
'#required' => TRUE,
'#default_value' => $node->sourcename,
'#description' => t('The name of the source data. This could be a file name, data set name or a
small description for how the data was collected. For long descriptions use the description field below'),
'#weight' => 5
);
$form['sourceversion']= array(
'#type' => 'textfield',
'#title' => t('Source Version'),
'#required' => FALSE,
'#default_value' => $node->sourceversion,
'#description' => t('If the source dataset has a version, include it here'),
'#weight' => 6
);
$form['sourceuri']= array(
'#type' => 'textfield',
'#title' => t('Source URI'),
'#required' => FALSE,
'#default_value' => $node->sourceuri,
'#description' => t("This is a permanent URL or URI for the source of the analysis.
Someone could recreate the analysis directly by going to this URI and
fetching the source data (e.g. the blast database, or the training model)."),
'#weight' => 7
);
// Get time saved in chado
$default_time = $node->timeexecuted;
$year = preg_replace("/^(\d+)-\d+-\d+ .*/", "$1", $default_time);
$month = preg_replace("/^\d+-0?(\d+)-\d+ .*/", "$1", $default_time);
$day = preg_replace("/^\d+-\d+-0?(\d+) .*/", "$1", $default_time);
// If the time is not set, use current time
if (!$default_time) {
$default_time = time();
$year = format_date($default_time, 'custom', 'Y');
$month = format_date($default_time, 'custom', 'n');
$day = format_date($default_time, 'custom', 'j');
}
$form['timeexecuted']= array(
'#type' => 'date',
'#title' => t('Time Executed'),
'#required' => TRUE,
'#default_value' => array(
'year' => $year,
'month' => $month,
'day' => $day,
),
'#weight' => 8
);
$form['description']= array(
'#type' => 'textarea',
'#rows' => 15,
'#title' => t('Description and/or Program Settings'),
'#required' => FALSE,
'#default_value' => check_plain($node->description),
'#description' => t('Please provide all necessary information to allow
someone to recreate the analysis, including materials and methods
for collection of the source data and performing the analysis'),
'#weight' => 9
);
return $form;
}
/*******************************************************************************
* When a node is requested by the user this function is called to allow us
* to add auxiliary data to the node object.
*
* @ingroup tripal_analysis
*/
function chado_analysis_load($node){
// get the analysis_id for this node:
$sql = "SELECT analysis_id FROM {chado_analysis} WHERE vid = %d";
$ana_node = db_fetch_object(db_query($sql, $node->vid));
$additions = new stdClass();
if ($ana_node) {
// get analysis information
$sql = "SELECT Analysis_id, name AS analysisname, description, program, ".
" programversion, algorithm, sourcename, sourceversion, ".
" sourceuri, timeexecuted ".
"FROM {Analysis} ".
"WHERE Analysis_id = $ana_node->analysis_id";
$previous_db = tripal_db_set_active('chado'); // use chado database
$additions = db_fetch_object(db_query($sql));
// get number of features assc with this analysis
// $sql = "SELECT count(feature_id) as featurecount ".
// "FROM {Analysisfeature} ".
// "WHERE Analysis_id = %d";
// $additions->featurecount = db_result(db_query($sql, $ana_node->analysis_id));
tripal_db_set_active($previous_db); // now use drupal database
}
// If the analysis has a name, use it as the node title. If not, construct
// the title using program programversion, and sourcename
if ($additions->analysisname) {
$additions->title = $additions->analysisname;
} else {
// Construct node title as "program version (source)
$additions->title = "$additions->program ($additions->programversion)";
}
return $additions;
}
/*******************************************************************************
* This function customizes the view of the chado_analysis node. It allows
* us to generate the markup.
*
* @ingroup tripal_analysis
*/
function chado_analysis_view ($node, $teaser = FALSE, $page = FALSE) {
// use drupal's default node view:
if (!$teaser) {
$node = node_prepare($node, $teaser);
// When previewing a node submitting form, it shows 'Array' instead of
// correct date format. We need to format the date here
$time = $node->timeexecuted;
if(is_array($time)){
$month = $time['month'];
$day = $time['day'];
$year = $time['year'];
$timestamp = $year.'-'.$month.'-'.$day;
$node->timeexecuted = $timestamp;
}
}
return $node;
}
/*******************************************************************************
* Synchronize analyses from chado to drupal
*
* @ingroup tripal_analysis
*/
function tripal_analysis_sync_analyses ($analysis_id = NULL, $job_id = NULL){
global $user;
$page_content = '';
if(!$analysis_id){
$sql = "SELECT Analysis_id, name AS analysisname, description, program, ".
" programversion, algorithm, sourcename, sourceversion, sourceuri, ".
" timeexecuted ".
"FROM {Analysis} ";
$previous_db = tripal_db_set_active('chado'); // use chado database
$results = db_query($sql);
tripal_db_set_active($previous_db); // now use drupal database
} else {
$sql = "SELECT Analysis_id, name AS analysisname, description, program, ".
" programversion, algorithm, sourcename, sourceversion, sourceuri, ".
" timeexecuted ".
"FROM {Analysis} ".
"WHERE analysis_id = %d";
$previous_db = tripal_db_set_active('chado'); // use chado database
$results = db_query($sql,$analysis_id);
tripal_db_set_active($previous_db); // now use drupal database
}
// We'll use the following SQL statement for checking if the analysis
// already exists as a drupal node.
$sql = "SELECT * FROM {chado_analysis} ".
"WHERE analysis_id = %d";
while($analysis = db_fetch_object($results)){
print "syncing analysis ";
print $analysis->analysisname;
print ", ";
print $analysis->analysis_id;
print "\n";
// check if this analysis already exists in the drupal database. if it
// does then skip this analysis and go to the next one.
if(!db_fetch_object(db_query($sql,$analysis->analysis_id))){
$new_node = new stdClass();
// try to access analysis type for this analysis
$sql = "SELECT * FROM {analysisprop}
WHERE analysis_id = %d
AND type_id =
(SELECT cvterm_id from {cvterm} where name = '%s')
";
$previous_db = tripal_db_set_active('chado');
$analysis_type = db_fetch_object(db_query($sql, $analysis->analysis_id, "analysis_type"));
tripal_db_set_active($previous_db);
// Get the type of analysis using cvterm_id
// Current possibilities: kegg, unigene, interpro, blast
if ($analysis_type) {
// This is a unigene analysis
if ($analysis_type->value == 'tripal_analysis_unigene') {
$new_node->type = 'chado_analysis_unigene';
// This is a blast analysis
} else if ($result->name == 'tripal_analysis_blast') {
$new_node->type = 'chado_analysis_blast';
// This is a interpro analysis
} else if ($result->name == 'tripal_analysis_interpro') {
$new_node->type = 'chado_analysis_interpro';
// This is a kegg analysis
} else if ($result->name == 'tripal_analysis_kegg' ){
$new_node->type = 'chado_analysis_kegg';
} else {
$new_node->type = 'chado_analysis';
}
// If it doesn't exist, this analysis is generic
} else {
$new_node->type = 'chado_analysis';
}
print "analysis type is $new_node->type\n";
$new_node->uid = $user->uid;
$new_node->analysis_id = $analysis->analysis_id;
$new_node->analysisname = $analysis->analysisname;
$new_node->description = $analysis->description;
$new_node->program = $analysis->program;
$new_node->programversion = $analysis->programversion;
$new_node->algorithm = $analysis->algorithm;
$new_node->sourcename = $analysis->sourcename;
$new_node->sourceversion = $analysis->sourceversion;
$new_node->sourceuri = $analysis->sourceuri;
$new_node->timeexecuted = $analysis->timeexecuted;
// If the analysis has a name, use it as the node title. If not,
// construct the title using program, programversion, and sourcename
if ($new_node->analysisname) {
$new_node->title = $new_node->analysisname;
} else {
//Construct node title as "program (version)"
$new_node->title = "$analysis->program ($analysis->programversion)";
}
node_validate($new_node);
$errors = form_get_errors();
if($errors){
print_r($errors);
}
else{
##if(!form_get_errors()){
$node = node_submit($new_node);
node_save($node);
if($node->nid){
$page_content .= "Added $new_node->title
";
}
}
} else {
$page_content .= "Skipped $new_node->title
";
}
}
return $page_content;
}
/*******************************************************************************
* Display help and module information
* @param path which path of the site we're displaying help
* @param arg array that holds the current path as would be returned from arg()
* function
* @return help text for the path
*
* @ingroup tripal_analysis
*/
function tripal_analysis_help($path, $arg) {
$output = '';
switch ($path) {
case "admin/help#tripal_analysis":
$output = '
'. t("Displays links to nodes created on this date"). '
'; break; } return $output; } /******************************************************************************* * The following function proves access control for users trying to * perform actions on data managed by this module * * @ingroup tripal_analysis */ function chado_analysis_access($op, $node, $account){ if ($op == 'create') { return user_access('create chado_analysis content', $account); } if ($op == 'update') { if (user_access('edit chado_analysis content', $account)) { return TRUE; } } if ($op == 'delete') { if (user_access('delete chado_analysis content', $account)) { return TRUE; } } if ($op == 'view') { if (user_access('access chado_analysis content', $account)) { return TRUE; } } return FALSE; } /******************************************************************************* * Set the permission types that the chado module uses. Essentially we * want permissionis that protect creation, editing and deleting of chado # data objects * * @ingroup tripal_analysis */ function tripal_analysis_perm(){ return array( 'access chado_analysis content', 'create chado_analysis content', 'delete chado_analysis content', 'edit chado_analysis content', ); } /******************************************************************************* * We need to let drupal know about our theme functions and their arguments. * We create theme functions to allow users of the module to customize the * look and feel of the output generated in this module * * @ingroup tripal_analysis */ function tripal_analysis_theme () { return array( 'tripal_analysis_analysis_page' => array ( 'arguments' => array('analyses'), ), ); } /******************************************************************************* * This function uses analysis_id's of all drupal analysis nodes as input and * pull the analysis information (name, description, program, programversion, * algorithm, sourcename, sourceversion, sourceuri, timeexecuted) from * chado database. The return type is an object array that stores $analysis * objects sorted by program * * @ingroup tripal_analysis */ function get_chado_analyses() { $sql_drupal = "SELECT COUNT (analysis_id) FROM {chado_analysis}"; $no_orgs = db_result(db_query($sql_drupal)); if ($no_orgs != 0) { $sql = "SELECT analysis_id, CA.nid, type FROM {chado_analysis} CA INNER JOIN node ON CA.nid = node.nid"; $result = db_query($sql); $previous_db = tripal_db_set_active('chado'); $sql = "SELECT Analysis_id, name AS analysisname, description, program, programversion, algorithm, sourcename, sourceversion, sourceuri, timeexecuted FROM {Analysis} WHERE analysis_id=%d"; $analyses = array(); $count = 0; while ($data = db_fetch_object($result)) { $analysis = db_fetch_object(db_query($sql, $data->analysis_id)); $analysis->node_id = $data->nid; $analysis->node_type = $data->type; // Use node_type as the key so we can sort by node type // Since node_type is not unique by itself, we need to add // $count to the key $sortedBy = $analysis->timeexecuted; $analyses ["$sortedBy$count"] = $analysis; $count ++; } tripal_db_set_active($previous_db); //Sort analyses by time, descending order krsort($analyses, SORT_STRING); return $analyses; } } /************************************************************************ * * * @ingroup tripal_analysis */ function theme_tripal_analysis_analysis_page($analyses) { $output = "