+ However, syncing an analyses will always create a generic analysis content type. If you would like
+ to use a specialized analysis module for visualization of data then do not sync the analysis but recreate it
+ using the appropriate specialized analysis content type.</p></li>
+
+ </ol>
+ </p>';
+
+
+ $text .= '<h3>Features of this Module:</h3>';
+ $text .= '<p>Aside from providing a generic content type the Tripal Analysis module also provides the following functionality
+ <ul>
+
+ <li><p><b>Basic Analysis Lookup View</b>: This module provides a basic <a href="'.url('analyses').'">analysis search
+ tool</a> for finding or listing analyses in Chado. It does not require indexing for Drupal searching but relies
+ on Drupal Views. <a href="http://drupal.org/project/views">Drupal Views</a> must be installed. </p></li>
+
+ </ul>
+ </p>';
+
+ $text .= '<h3>Page Customizations</h3>';
+ $text .= '<p>There are several ways to customize the look-and-feel for the way Chado data is presented through Tripal.
+ Below is a description of several methods. These methods may be used in conjunction with one another to
+ provide fine-grained control.
+ <ul>
+
+ <li><p><b>Integration with Drupal Panels</b>: <a href="http://drupal.org/project/views">Drupal Panels</a>
+ allows for customization of a page layout if you don\'t want to do PHP/Javascript/CSS programming.
+ Tripal comes with pre-set layouts for analysis pages. However,
+ Panels become useful if you prefer a layout that is different from the pre-set layouts. Chado content
+ is provided to Panels in the form of Drupal "blocks" which you can then place anywhere on a page using the
+ Panel\'s GUI.</p></li>
+
+ <li><p><b>Drupal\'s Content Construction Kit (CCK)</b>: the
+ <a href="http://drupal.org/project/cck">Content Construction Kit (CCK) </a> is a powerful way to add non-Chado content
+ to any page without need to edit template files or knowing PHP. You must first download and install CCK.
+ With CCK, the site administartor can create a new field to appear on the page. For example, currently,
+ the Chado publication module is not yet supported by Tripal. Therefore, the site administrator can add a text
+ field to the analysis pages. This content is not stored in Chado, but will appear on the analysis page. A field
+ added by CCK will also appear in the form when editing a analysis to allow users to manually enter the appropriate
+ text. If the default pre-set layout and themeing for Tripal is used, it is better to create the CCK element,
+ indicate that it is not to be shown (using the CCK interface), then manually add the new content type
+ where desired by editing the templates (as described below). If using Panels, the CCK field can be added to the
+ location desired using the Panels interface.</p></li>
+
+ <li><p><b>Drupal Node Templates</b>: The Tripal packages comes with a "theme_tripal" directory that contains the
+ themeing for Chado content. The analysis module has a template file for analysis "nodes" (Tripal analysis pages). This file
+ is named "node-chado_analysis.tpl.php", and provides javascript, HTML and PHP code for display of the analysis
+ pages. Specialized analysis modules will have their own template files as well, such as "node-chado_analysis-blast.tpl.php" for the
+ Tripal Analysis Blast module. You can edit the template file to control which types of information (or which analysis "blocks") are displayed
+ for analysis. Be sure to
+ copy these template to your primary theme directory for editing. Do not edit them in the "theme_tripal" directory as
+ future Tripal updates may overwrite your customizations. See the <a href="http://tripal.sourceforge.net/">Tripal website </a>
+ for instructions on how to access variables and other Chado content within the template file.</p></li>
+
+ <li><p><b>Analysis "Block" Templates</b>: In the "theme_tripal" directory are subdirectories named after each tripal module (e.g. "tripal_feature", "tripal_library", etc.).
+ Inside each directory is a set of templates that control distinct types of information for each content type. For example,
+ there is a "base" template for displaying of data directly from the Chado feature table, and a "references"
+ template for showing external site references for a feature (data from the feature_dbxref table).
+ These templates are used both by Drupal blocks
+ for use in Drupal Panels (as described above) or for use in the default pre-set layout that the node template
+ provides (also desribed above). Analyses block templates can exist in any of these directories. For example, the Tripal Analysis Unigene
+ module uses templates in the tripal_analysis_unigene, tripal_organism, and tripal_feature directories. Content for a unigene is then
+ cusotmizable within each of these contexts.
+ You can customize block template as you desire. Be sure to copy the
+ template to your primary theme directory for editing. Do not edit them in the "theme_tripal" directory as
+ future Tripal updates may overwrite your customizations. See the <a href="http://tripal.sourceforge.net/">Tripal website </a>
+ for instructions on how to access variables and other Chado content within the template files.</p></li>
+ </li>
+
+ <li><p><b>Adding Links to the "Resources" Sidebar</b>: If you use the pre-set default Tripal layout for theming, you
+ will see a "Resources" sidebar on each page. The links that appear on the sidebar are automatically generated
+ using Javascript for all of the analysis "Blocks" that appear on the page. If you want to add additional links
+ (e.g. a dynamic link to GBrowse for the analysis) and you want that link to appear in the
+ "Resources" sidebar, simply edit the Drupal Node Template (as described above) and add the link to the
+ section at the bottom of the template file where the resources section is found.</p></li>
+ '#value' => t('Currently, analysis management jobs are waiting or are running. . Managemment features have been hidden until these jobs complete. Please check back later once these jobs have finished. You can view the status of pending jobs in the Tripal jobs page.'),
+ );
+ }
+
+ // Add sub-module settings. Pull all sub-module information from
+ // {tripal_analysis} table
+ $sql = "SELECT modulename FROM {tripal_analysis}";
+ $result = db_query($sql);
+ $counter = 0; //keep track of the number of sub-modules
+ while ($data = db_fetch_object($result)) {
+
+ // Check if the hook_get_settings() function is already defined.
+ $func = $data->modulename."_get_settings";
+ $functions = get_defined_functions();
+ $settings;
+ foreach($functions['user'] as $function) {
+ if ($function == $func) {
+ $settings = $func();
+ }
+ }
+
+ // Add sub-module's specific settings to the administrative view
+ '#value' => t("Drupal allows for assignment of \"taxonomy\" or catagorical terms to " .
+ "nodes. These terms allow for advanced filtering during searching. This option allows ".
+ "for setting taxonomy only for features that belong to the selected analyses below. All other features will be unaffected. To set taxonomy for all features in the site see the Feature Administration page."),
+ '#weight' => 1,
+ );
+
+ $form['taxonify']['tx-analyses'] = array (
+ '#title' => t('Analyses'),
+ '#type' => t('checkboxes'),
+ '#description' => t("Check the analyses whose features you want to reset taxonomy. Note: this list contains all analyses, even those that may not be synced."),
+ '#value' => t("This option allows for reindexing of only those features that belong to the selected analyses below. All other features will be unaffected. To reindex all features in the site see the Feature Administration page."),
+ '#weight' => 1,
+ );
+
+ $form['reindex']['re-analyses'] = array (
+ '#title' => t('Libraries'),
+ '#type' => t('checkboxes'),
+ '#description' => t("Check the analyses whoee features you want to reindex. Note: this list contains all analyses, even those that may not be synced."),
+ // if we have analyses we need to add to the checkbox then
+ // build that form element
+ if($added > 0){
+ $ana_boxes['all'] = "All analyses";
+
+ $form['sync']['analyses'] = array (
+ '#title' => t('Available analyses'),
+ '#type' => t('checkboxes'),
+ '#description' => t("Check the analyses you want to sync. Drupal ".
+ "content will be created for each of the analyses listed above. ".
+ "Select 'All analyses' to sync all of them."),
+ '#required' => FALSE,
+ '#prefix' => '<div id="ana_boxes">',
+ '#suffix' => '</div>',
+ '#options' => $ana_boxes,
+ );
+ $form['sync']['button'] = array(
+ '#type' => 'submit',
+ '#value' => t('Submit Sync Job')
+ );
+ }
+ // we don't have any analyses to select from
+ else {
+ $form['sync']['value'] = array(
+ '#value' => t('All analyses in Chado are currently synced with Drupal.')
+ );
+ }
+ }
+ // we don't want to present a form since we have an active job running
+ else {
+ $form['sync']['value'] = array(
+ '#value' => t('Currently, jobs exist related to chado analyses. Please check back later for analyses that can by synced once these jobs have finished. You can view the status of pending jobs in the Tripal jobs page.')
+description = A module that controls the display of all analysis sub-modules. This module also interfaces the GMOD chado database with Drupal, providing viewing, inserting and editing of chado analyses.
+ tripal_add_cvterms('analysis_type','The type of analysis was performed. This value is automatically set by each Tripal Analysis module and should be equal to the module name (e.g. tripal_analysis_blast, tripal_analysis_go).');
+ tripal_add_cvterms('analysis_date','The date that an analysis was performed.');
+ tripal_add_cvterms('analysis_short_name','A computer legible (no spaces '.
+ 'or special characters) abbreviation for the analysis.');
+ tripal_add_cvterms('based_on_analysis','The analysis that this analysis was based on. For example, blast/kegg/interpro analyses are based on a unigene analysis. The unigene analysis_id should be stored in analysisprop as the rank using this cvterm. The name of said unigene analysis can be inserted as the value in analysisprop.');
+ tripal_add_cvterms('additional_files', 'Additional files for this analysis. Each file should be separated by a semi-colon and have this format: <file description>, <file path>;');
+ $output = "<br>Analyses are listed in the descending order of their execution time.<br><a id=\"tripal_expandableBox_toggle_button\" onClick=\"toggleExpandableBoxes()\">[-] Collapse All</a>";
+ 'help' => t("An analysis is a particular type of a computational analysis; it may be a blast of one sequence against another, or an all by all blast, or a different kind of analysis altogether. It is a single unit of computation."),
+ // Remove the records from the database that were already inserted
+ $resource = db_query('SELECT * FROM {tripal_bulk_loader_inserted} WHERE nid=%d ORDER BY tripal_bulk_loader_inserted_id DESC', $form_state['values']['nid']);
+ while ($r = db_fetch_object($resource)) {
+ $ids = preg_split('/,/',$r->ids_inserted);
+ db_query('DELETE FROM %s WHERE %s IN (%s)',$r->table_inserted_into, $r->table_primary_key, $r->ids_inserted);
+ $result = db_fetch_object(db_query('SELECT true as present FROM %s WHERE %s IN (%s)', $r->table_inserted_into, $r->table_primary_key, $r->ids_inserted));
+ if (!$result->present) {
+ drupal_set_message('Successfully Removed data Inserted into the '.$r->table_inserted_into.' table.');
+ db_query('DELETE FROM {tripal_bulk_loader_inserted} WHERE tripal_bulk_loader_inserted_id=%d',$r->tripal_bulk_loader_inserted_id);
+ } else {
+ drupal_set_message('Unable to remove data Inserted into the '.$r->table_inserted_into.' table!', 'error');
+ }
+ }
+
+ // reset status
+ db_query("UPDATE tripal_bulk_loader SET job_status='%s' WHERE nid=%d",'Reverted -Data Deleted', $form_state['values']['nid']);
+ }
+
+}
+
+/**
+ * Tripal Bulk Loader
+ *
+ * This is the function that's run by tripal_launch_jobs to bulk load chado data.
+ *
+ * @param $nid
+ * The Node ID of the bulk loading job node to be loaded. All other needed data is expected to be
+ * in the node (ie: template ID and file)
+ *
+ * Note: Instead of returning a value this function updates the tripal_bulk_loader.status.
+ * Errors are thrown through watchdog and can be viewed at admin/reports/dblog.
+ */
+function tripal_bulk_loader_load_data($nid) {
+
+ // ensure no timeout
+ set_time_limit(0);
+
+ // set the status of the job (in the node not the tripal jobs)
+ db_query("UPDATE tripal_bulk_loader SET job_status='%s' WHERE nid=%d",'Loading...', $nid);
+ $msg = $table_data['record_id'].' ('.$table_data['mode'].') Aborted due to error in previous record. Values of current record:'.print_r($table_data['values_array'],TRUE);
+ '#description' => t("Loader template needs to be created before any bulk loader can be added. Go to 'Tripal Management > Bulk Loader Template' to create the template."),
+ '#weight' => -10,
+ );
+
+ return $form;
+ }
+
+ $form['loader_name'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Loading Job Name'),
+ '#weight' => -10,
+ '#required' => TRUE,
+ '#default_value' => $node->loader_name
+ );
+
+ $form['template_id'] = array(
+ '#type' => 'select',
+ '#title' => t('Template'),
+ '#description' => t('Please specify a template for this loader'),
+ '#options' => $templates,
+ '#weight' => -9,
+ '#required' => TRUE,
+ '#default_value' => $node->template_id
+ );
+
+ $form['file']= array(
+ '#type' => 'textfield',
+ '#title' => t('Data File'),
+ '#description' => t('Please specify the data file to be loaded.'),
+ '#weight' => -8,
+ '#default_value' => $node->file
+ );
+
+ $form['has_header'] = array(
+ '#type' => 'radios',
+ '#title' => 'File has a Header',
+ '#options' => array( 1 => 'Yes', 2 => 'No'),
+ '#weight' => -7,
+ '#default_value' => $node->file_has_header,
+ );
+
+ return $form;
+}
+
+/**
+ * Implements node_load
+ */
+function tripal_bulk_loader_load($node){
+ $sql = "SELECT * FROM {tripal_bulk_loader} WHERE nid = %d";
+ drupal_set_message('After reviewing the details, please Submit this Job (by clicking the "Submit Job" button below). No data will be loaded until the submitted job is reached in the queue.');
+
+}
+
+/**
+ * Implements node_delete
+ * Deletes the data when the delete button on the node form is clicked
+ */
+function tripal_bulk_loader_delete ($node) {
+ $sql = "DELETE FROM {tripal_bulk_loader} WHERE nid = %d";
+ db_query($sql, $node->nid);
+}
+
+/**
+ * Implements node_update
+ * Updates the data submitted by the node form on edit
+ */
+function tripal_bulk_loader_update ($node) {
+ $sql = "UPDATE {tripal_bulk_loader} SET nid = %d, loader_name = '%s', template_id = %d, file = '%s', file_has_header = '%s' WHERE nid = %d";
+ '#value' => t("Click the submit button below to install Chado into the Drupal database. <br><font color=\"red\">WARNING:</font> use this only for a new chado installation or reinstall completely. This will erase any data currently in the chado database. If you are
+using chado in a database external to the Drupal database with a 'chado' entry in the 'settings.php' \$db_url argument then this option will intall chado but it will not be usable. The external database specified in the settings.php file takes precedence."),
+insert into contact (name) values ('Affymetrix');
+insert into contact (name,description) values ('null','null');
+insert into cv (name) values ('null');
+insert into cv (name,definition) values ('local','Locally created terms');
+insert into cv (name,definition) values ('Statistical Terms','Locally created terms for statistics');
+insert into db (name, description) values ('null','a fake database for local items');
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'local:null');
+insert into cvterm (name,cv_id,dbxref_id) values ('null',(select cv_id from cv where name = 'null'),(select dbxref_id from dbxref where accession='local:null'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'local:computer file');
+insert into cvterm (name,cv_id,dbxref_id) values ('computer file', (select cv_id from cv where name = 'null'),(select dbxref_id from dbxref where accession='local:computer file'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'local:glass');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('glass','glass array',(select cv_id from cv where name = 'local'),(select dbxref_id from dbxref where accession='local:glass'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'local:photochemical_oligo');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('photochemical_oligo','in-situ photochemically synthesized oligoes',(select cv_id from cv where name = 'local'),(select dbxref_id from dbxref where accession='local:photochemical_oligo'));
+
+insert into pub (miniref,uniquename,type_id) values ('null','null',(select cvterm_id from cvterm where name = 'null'));
+insert into db (name, description) values ('GFF_source', 'A collection of sources (ie, column 2) from GFF files');
+
+insert into db (name) values ('ATCC');
+
+insert into db (name) values ('DB:refseq');
+insert into db (name) values ('DB:genbank');
+insert into db (name) values ('DB:EMBL');
+insert into db (name) values ('DB:TIGR');
+insert into db (name) values ('DB:ucsc');
+insert into db (name) values ('DB:ucla');
+insert into db (name) values ('DB:SGD');
+
+insert into db (name) values ('DB:PFAM');
+insert into db (name) values ('DB:SUPERFAMILY');
+insert into db (name) values ('DB:PROFILE');
+insert into db (name) values ('DB:PRODOM');
+insert into db (name) values ('DB:PRINTS');
+insert into db (name) values ('DB:SMART');
+insert into db (name) values ('DB:TIGRFAMs');
+insert into db (name) values ('DB:PIR');
+
+insert into db (name) values ('DB:Affymetrix_U133');
+insert into db (name) values ('DB:Affymetrix_U133PLUS');
+insert into db (name) values ('DB:Affymetrix_U95');
+insert into db (name) values ('DB:LocusLink');
+insert into db (name) values ('DB:RefSeq_protein');
+insert into db (name) values ('DB:GenBank_protein');
+insert into db (name) values ('DB:OMIM');
+insert into db (name) values ('DB:Swiss');
+insert into db (name) values ('DB:RefSNP');
+insert into db (name) values ('DB:TSC');
+--insert into db (name, contact_id, description, urlprefix) values ('DB:affy:U133',(select contact_id from contact where name = 'null'),'Affymetrix U133','http://https://www.affymetrix.com/analysis/netaffx/fullrecord.affx?pk=HG-U133_PLUS_2:');
+--insert into db (name, contact_id, description, urlprefix) values ('DB:affy:U95',(select contact_id from contact where name = 'null'),'Affymetrix U95','http://https://www.affymetrix.com/analysis/netaffx/fullrecord.affx?pk=HG-U95AV2:');
+
+insert into db (name, description) values ('DB:GR','Gramene');
+insert into db (name, description, urlprefix) values ('DB:uniprot','UniProt/TrEMBL','http://us.expasy.org/cgi-bin/niceprot.pl?');
+insert into db (name, description, urlprefix) values ('DB:refseq:mrna','RefSeq mRNA','http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=search&db=nucleotide&dopt=GenBank&term=');
+insert into db (name, description, urlprefix) values ('DB:refseq:protein','RefSeq Protein','http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=search&db=protein&dopt=GenBank&term=');
+insert into db (name, description, urlprefix) values ('DB:unigene','Unigene','http://www.ncbi.nih.gov/entrez/query.fcgi?db=unigene&cmd=search&term=');
+insert into db (name, description, urlprefix) values ('DB:omim','OMIM','http://www.ncbi.nlm.nih.gov/entrez/dispomim.cgi?id=');
+insert into db (name, description, urlprefix) values ('DB:locuslink','LocusLink','http://www.ncbi.nlm.nih.gov/LocusLink/LocRpt.cgi?l=');
+insert into db (name, description, urlprefix) values ('DB:genbank:mrna','GenBank mRNA','http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=search&db=nucleotide&dopt=GenBank&term=');
+insert into db (name, description, urlprefix) values ('DB:genbank:protein','GenBank Protein','http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=search&db=protein&dopt=GenBank&term=');
+insert into db (name, description, urlprefix) values ('DB:swissprot:display','SwissProt','http://us.expasy.org/cgi-bin/niceprot.pl?');
+insert into db (name, description, urlprefix) values ('DB:pfam','Pfam','http://www.sanger.ac.uk/cgi-bin/Pfam/dql.pl?query=');
+
+insert into analysis (name,program,programversion) values ('dabg' ,'dabg' ,'dabg' );
+insert into analysis (name,program,programversion) values ('dchip','dchip','dchip');
+insert into analysis (name,program,programversion) values ('gcrma','gcrma','gcrma');
+insert into analysis (name,program,programversion) values ('mas5' ,'mas5' ,'mas5' );
+insert into analysis (name,program,programversion) values ('mpam' ,'mpam' ,'mpam' );
+insert into analysis (name,program,programversion) values ('plier','plier','plier');
+insert into analysis (name,program,programversion) values ('rma' ,'rma' ,'rma' );
+insert into analysis (name,program,programversion) values ('sea' ,'sea' ,'sea' );
+insert into analysis (name,program,programversion) values ('vsn' ,'vsn' ,'vsn' );
+
+insert into arraydesign (name,manufacturer_id,platformtype_id) values ('unknown' , (select contact_id from contact where name = 'null'),(select cvterm_id from cvterm where name = 'null'));
+insert into arraydesign (name,manufacturer_id,platformtype_id) values ('virtual array' , (select contact_id from contact where name = 'null'),(select cvterm_id from cvterm where name = 'null'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U133_Plus_2' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U133A' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U133A_2' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U133B' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U95Av2' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U95B' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U95C' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U95D' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U95E' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HuExon1' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HuGeneFL' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_U74Av2' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_MG-U74Av2' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_MG-U74Bv2' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_MG-U74Cv2' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RG-U34A' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RG-U34B' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RG-U34C' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RT-U34' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RN-U34' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_YG-S98' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Yeast_2' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RAE230A' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RAE230B' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Rat230_2' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_MOE430A' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_MOE430B' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mouse430_2' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mouse430A_2' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_ATH1-121501' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mapping100K_Hind240' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mapping100K_Xba240' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mapping10K_Xba131' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mapping10K_Xba142' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mapping500K_NspI' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mapping500K_StyI' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
+
+insert into cv (name) values ('developmental stages');
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'developmental stages:fetus');
+insert into cvterm (name,cv_id,dbxref_id) values ('fetus', (select cv_id from cv where name = 'local'),(select dbxref_id from dbxref where accession='developmental stages:fetus'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'developmental stages:neonate');
+insert into cvterm (name,cv_id,dbxref_id) values ('neonate', (select cv_id from cv where name = 'developmental stages'), (select dbxref_id from dbxref where accession='developmental stages:neonate'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'developmental stages:child');
+insert into cvterm (name,cv_id,dbxref_id) values ('child', (select cv_id from cv where name = 'developmental stages'), (select dbxref_id from dbxref where accession='developmental stages:child'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'developmental stages:adult_young');
+insert into cvterm (name,cv_id,dbxref_id) values ('adult_young',(select cv_id from cv where name = 'developmental stages'),(select dbxref_id from dbxref where accession='developmental stages:adult_young'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'developmental stages:adult');
+insert into cvterm (name,cv_id,dbxref_id) values ('adult', (select cv_id from cv where name = 'developmental stages'),(select dbxref_id from dbxref where accession='developmental stages:adult'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'developmental stages:adult_old');
+insert into cvterm (name,cv_id,dbxref_id) values ('adult_old', (select cv_id from cv where name = 'developmental stages'), (select dbxref_id from dbxref where accession='developmental stages:adult_old'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'local:survival_time');
+insert into cvterm (name,cv_id,dbxref_id) values ('survival_time',(select cv_id from cv where name = 'local'),(select dbxref_id from dbxref where accession='local:survival_time'));
+
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:n');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('n','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:n'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:minimum');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('minimum','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:minimum'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:maximum');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('maximum','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:maximum'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:modality');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('modality','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:modality'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:modality p');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('modality p','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:modality p'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:mean');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('mean','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:mean'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:median');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('median','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:median'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:mode');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('mode','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:mode'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:quartile 1');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('quartile 1','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:quartile 1'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:quartile 3');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('quartile 3','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:quartile 3'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:skewness');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('skewness','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:skewness'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:kurtosis');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('kurtosis','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:kurtosis'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:chi square p');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('chi square p','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:chi square p'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:standard deviation');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('standard deviation','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:standard deviation'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:expectation maximization gaussian mean');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('expectation maximization gaussian mean','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:expectation maximization gaussian mean'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:expectation maximization p');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('expectation maximization p','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:expectation maximization p'));
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:histogram');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('histogram','sensu statistica', (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:histogram'));
+
+insert into cv (name,definition) values ('autocreated','Terms that are automatically inserted by loading software');
+ '#description' => t('Please enter the name for this materialized view.'),
+ '#required' => TRUE,
+ '#default_value' => $default_name,
+ '#weight' => 1
+ );
+
+ $form['mv_table']= array(
+ '#type' => 'textfield',
+ '#title' => t('Table Name'),
+ '#description' => t('Please enter the Postgres table name that this view will generate in the database. You can use the schema and table name for querying the view'),
+ '#required' => TRUE,
+ '#default_value' => $default_mv_table,
+ '#weight' => 3
+ );
+ $form['mv_specs']= array(
+ '#type' => 'textarea',
+ '#title' => t('Table Definition'),
+ '#description' => t('Please enter the field definitions for this view. Each field should be separated by a comma or enter each field definition on each line.'),
+ '#required' => TRUE,
+ '#default_value' => $default_mv_specs,
+ '#weight' => 4
+ );
+ $form['indexed']= array(
+ '#type' => 'textarea',
+ '#title' => t('Indexed Fields'),
+ '#description' => t('Please enter the field names (as provided in the table definition above) that will be indexed for this view. Separate by a comma or enter each field on a new line.'),
+ '#required' => FALSE,
+ '#default_value' => $default_indexed,
+ '#weight' => 5
+ );
+ $form['mvquery']= array(
+ '#type' => 'textarea',
+ '#title' => t('Query'),
+ '#description' => t('Please enter the SQL statement used to populate the table.'),
+ '#required' => TRUE,
+ '#default_value' => $default_mvquery,
+ '#weight' => 6
+ );
+/**
+ $form['special_index']= array(
+ '#type' => 'textarea',
+ '#title' => t('View Name'),
+ '#description' => t('Please enter the name for this materialized view.'),
+ watchdog('tripal_core', 'tripal_core_chado_insert: Too many records match the criteria supplied for !foreign_key foreign key constraint (!criteria)', array('!foreign_key' => $field, '!criteria' => print_r($value,TRUE)), WATCHDOG_ERROR);
+ } elseif (sizeof($results) < 1) {
+ //watchdog('tripal_core', 'tripal_core_chado_insert: no record matches criteria supplied for !foreign_key foreign key constraint (!criteria)', array('!foreign_key' => $field, '!criteria' => print_r($value,TRUE)), WATCHDOG_ERROR);
+ } else {
+ $insert_values[$field] = $results[0];
+ }
+ }
+ else {
+ $insert_values[$field] = $value;
+ }
+ }
+
+ // check for violation of any unique constraints
+ $ukeys = $table_desc['unique keys'];
+ $ukselect_cols = array();
+ $ukselect_vals = array();
+ if ($ukeys) {
+ foreach($ukeys as $name => $fields){
+ foreach($fields as $index => $field){
+ // build the arrays for performing a select that will check the contraint
+ watchdog('tripal_core', 'tripal_core_chado_delete: When trying to find record to delete, too many records match the criteria supplied for !foreign_key foreign key constraint (!criteria)', array('!foreign_key' => $field, '!criteria' => print_r($value,TRUE)), WATCHDOG_ERROR);
+ } elseif (sizeof($results) < 1) {
+ //watchdog('tripal_core', 'tripal_core_chado_delete: When trying to find record to delete, no record matches criteria supplied for !foreign_key foreign key constraint (!criteria)', array('!foreign_key' => $field, '!criteria' => print_r($value,TRUE)), WATCHDOG_ERROR);
+ } else {
+ $delete_matches[$field] = $results[0];
+ }
+ }
+ }
+ else {
+ $delete_matches[$field] = $value;
+ }
+ }
+ // now build the SQL statement
+ $sql = "DELETE FROM {$table} WHERE ";
+ $dargs = array();
+ foreach($delete_matches as $field => $value){
+ if (count($value) > 1) {
+ $sql .= "$field IN (".db_placeholders($value,'varchar').") AND ";
+ foreach ($value as $v) { $dargs[] = $v; }
+ } else {
+ if(strcmp($value,'__NULL__')==0){
+ $sql .= " $field = NULL AND ";
+ }
+ elseif(strcmp($fields[$field]['type'],'serial')==0 or
+ strcmp($fields[$field]['type'],'int')==0){
+ $sql .= " $field = %d AND ";
+
+ }
+ else {
+ $sql .= " $field = '%s' AND ";
+ }
+ array_push($dargs,$value);
+ }
+ }
+ $sql = substr($sql,0,-4); // get rid of the trailing 'AND'
+
+ // finally perform the delete. If successful, return the updated record
+ $previous_db = tripal_db_set_active('chado'); // use chado database
+ $result = db_query($sql,$dargs);
+ tripal_db_set_active($previous_db); // now use drupal database
+ if($result){
+ return true;
+ }
+ else {
+ watchdog('tripal_core',"Cannot delete record in $table table. Match:" . print_r($match,1) . ". Values: ". print_r($values,1),array(),'WATCHDOG_ERROR');
+ return false;
+ }
+ return false;
+}
+
+/**
+* Provides a generic routine for updating into any Chado table
+*
+* Use this function to update a record in any Chado table. The first
+* argument specifies the table for inserting, the second is an array
+* of values to matched for locating the record for updating, and the third
+* argument give the values to update. The arrays are mutli-dimensional such
+* that foreign key lookup values can be specified.
+*
+* @param $table
+* The name of the chado table for inserting
+* @param $match
+* An associative array containing the values for locating a record to update.
+* @param $values
+* An associative array containing the values for updating.
+*
+* @return
+* On success this function returns TRUE. On failure, it returns FALSE.
+ watchdog('tripal_core', 'tripal_core_chado_update: When trying to find record to update, too many records match the criteria supplied for !foreign_key foreign key constraint (!criteria)', array('!foreign_key' => $field, '!criteria' => print_r($value,TRUE)), WATCHDOG_ERROR);
+ } elseif (sizeof($results) < 1) {
+ //watchdog('tripal_core', 'tripal_core_chado_update: When trying to find record to update, no record matches criteria supplied for !foreign_key foreign key constraint (!criteria)', array('!foreign_key' => $field, '!criteria' => print_r($value,TRUE)), WATCHDOG_ERROR);
+ watchdog('tripal_core', 'tripal_core_chado_update: When trying to find update values, too many records match the criteria supplied for !foreign_key foreign key constraint (!criteria)', array('!foreign_key' => $field, '!criteria' => print_r($value,TRUE)), WATCHDOG_ERROR);
+ } elseif (sizeof($results) < 1) {
+ //watchdog('tripal_core', 'tripal_core_chado_update: When trying to find update values, no record matches criteria supplied for !foreign_key foreign key constraint (!criteria)', array('!foreign_key' => $field, '!criteria' => print_r($value,TRUE)), WATCHDOG_ERROR);
+ } else {
+ $update_values[$field] = $results[0];
+ }
+ }
+ else {
+ $update_values[$field] = $value;
+ }
+ }
+
+ // now build the SQL statement
+ $sql = "UPDATE {$table} SET ";
+ $fields = $table_desc['fields'];
+ $uargs = array();
+ foreach($update_values as $field => $value){
+ if(strcmp($value,'__NULL__')==0){
+ $sql .= " $field = NULL, ";
+ }
+ elseif(strcmp($fields[$field]['type'],'serial')==0 or
+ strcmp($fields[$field]['type'],'int')==0){
+ $sql .= " $field = %d, ";
+ } else {
+ $sql .= " $field = '%s', ";
+ }
+ array_push($uargs,$value);
+ }
+ $sql = substr($sql,0,-2); // get rid of the trailing comma & space
+ $sql .= " WHERE ";
+ foreach($update_matches as $field => $value){
+ if(strcmp($value,'__NULL__')==0){
+ $sql .= " $field = NULL AND ";
+ }
+ elseif(strcmp($fields[$field]['type'],'serial')==0 or
+ strcmp($fields[$field]['type'],'int')==0){
+ $sql .= " $field = %d AND ";
+ }
+ else {
+ $sql .= " $field = '%s' AND ";
+ }
+ array_push($uargs,$value);
+ }
+ $sql = substr($sql,0,-4); // get rid of the trailing 'AND'
+
+ // finally perform the update. If successful, return the updated record
+ $previous_db = tripal_db_set_active('chado'); // use chado database
+ $result = db_query($sql,$uargs);
+ tripal_db_set_active($previous_db); // now use drupal database
+ if($result){
+ return true;
+ }
+ else {
+ watchdog('tripal_core',"Cannot update record in $table table. Match:" . print_r($match,1) . ". Values: ". print_r($values,1),array(),'WATCHDOG_ERROR');
+ return false;
+ }
+ return false;
+}
+
+/**
+* Provides a generic routine for selecting data from a Chado table
+*
+* Use this function to perform a simple select from any Chado table.
+*
+* @param $table
+* The name of the chado table for inserting
+* @param $columns
+* An array of column names
+* @param $values
+* An associative array containing the values for filtering the results. In the
+* case where multiple values for the same time are to be selected an additional
+* entry for the field should appear for each value
+* @param $options
+* An associative array of additional options where the key is the option
+* and the value is the value of that option.
+*
+* Additional Options Include:
+* - has_record
+* Set this argument to 'true' to have this function return a numeric
+* value for the number of recrods rather than the array of records. this
+* can be useful in 'if' statements to check the presence of particula records.
+* - return_sql
+* Set this to 'true' to have this function return an array where the first
+* element is the sql that would have been run and the second is an array of
+* arguments.
+* - case_insensitive_columns
+* An array of columns to do a case insensitive search on.
+* - regex_columns
+* An array of columns where the value passed in should be treated as a regular expression
+* - order_by
+* An associative array containing the column names of the table as keys
+* and the type of sort (i.e. ASC, DESC) as the values. The results in the
+* query will be sorted by the key values in the direction listed by the value
+*
+* @return
+* A database query result resource, FALSE if the query was not executed
+* correctly, or the number of records in the dataset if $has_record is set.
+ // thus if none matched then return false and alert the admin through watchdog
+ //watchdog('tripal_core',
+ // 'tripal_core_chado_select: no record in the table referenced by the foreign key (!field) exists. tripal_core_chado_select table=!table, columns=!columns, values=!values',
+ if (!is_array($options)) { $options = array(); }
+ if (!$options['case_insensitive_columns']) { $options['case_insensitive_columns'] = array(); }
+ if (!$options['regex_columns']) { $options['regex_columns'] = array(); }
+
+ // get the list of foreign keys for this table description and
+ // iterate through those until we find the one we're looking for
+ $fkeys = $table_desc['foreign keys'];
+ if($fkeys){
+ foreach($fkeys as $name => $def){
+ if (is_array($def['table'])) {
+ //foreign key was described 2X
+ $message = "The foreign key ".$name." was defined twice. Please check modules to determine if hook_chado_".$table_desc['table']."_schema() was implemented and defined this foreign key when it wasn't supposed to. Modules this hook was implemented in: ".implode(', ', module_implements("chado_".$table_desc['table']."_schema")).".";
+ watchdog('tripal_core', $message);
+ drupal_set_message($message,'error');
+ continue;
+ }
+ $table = $def['table'];
+ $columns = $def['columns'];
+ // iterate through the columns of the foreign key relationship
+ foreach($columns as $left => $right){
+ // does the left column in the relationship match our field?
+ if(strcmp($field,$left)==0){
+ // the column name of the foreign key matches the field we want
+ // so this is the right relationship. Now we want to select
+description = The core module for the Tripal package that integrates Drupal and GMOD chado. This module provides common support for all Tripal modules.
+ 'modulename' => array('type' => 'varchar','length' => 50, 'not null' => TRUE, 'description' => 'The module name that provides the callback for this job'),
+ 'mlock' => array ('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'description' => 'If set to 1 then all jobs for the module are held until this one finishes'),
+ 'lock' => array ('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'description' => 'If set to 1 then all jobs are held until this one finishes'),
+ 'modulename' => array('type' => 'varchar','length' => 50, 'not null' => TRUE, 'description' => 'The module name that provides the callback for this job'),
+ drupal_set_message("The field definition ( in hook_views_data() ) needs to specify the 'table_to_query' in order for this fields to work. Field:".$this->field." in the ".$this->table." table definition", 'error');
+ drupal_set_message('The Relationship by Type handler cannot be used with this table since the '.$this->table.'_relationship table doesn\'t exist', 'error');
+ '#description' => t('If "Custom", see <a href="http://us.php.net/manual/en/function.date.php" target="_blank">the PHP docs</a> for date formats. If "Time ago" this is the the number of different units to display, which defaults to two.'),
+remark: Initially generated by Chris Mungall, sourced from FB and Rice chado. TODO: TIGR Chado; TODO: GFF3
+subsetdef: fpo_sgd "SGD and related dbs subset"
+subsetdef: fpo_gff "GFF3 specific tags"
+subsetdef: fpo_apollo "properties with fixed semantics in apollo"
+
+[Typedef]
+id: SOFP:feature_property
+name: feature_property
+namespace: feature_property
+def: "A general purpose relation between a biological feature and some value" [so:cjm]
+
+[Typedef]
+id: SOFP:aminoacid
+name: aminoacid
+namespace: feature_property
+def: "amino acid coded for by a tRNA transcript feature" [so:cjm]
+is_a: SOFP:feature_property
+domain: SO:0000253
+range: CHEBI:22477
+
+[Typedef]
+id: SOFP:anticodon
+name: anticodon
+namespace: feature_property
+def: "anticodon coded for by a tRNA transcript feature" [so:cjm]
+is_a: SOFP:feature_property
+domain: SO:0000253
+range: xsd:string
+range_def: "A 3 character string representing the anticodon using the IUPAC DNA Sequence alphabet; for example ATG. RNA seqs MUST be converted to DNA seqs" []
+comments: Note the difference between GENBANK_SOFP:anticodon and SOFP:anticodon; the former includes the base range
+
+[Typedef]
+id: SOFP:citation
+name: citation
+namespace: feature_property
+is_a: SOFP:feature_property
+domain: SO:0000110
+
+[Typedef]
+id: SOFP:comment
+name: comment
+namespace: feature_property
+def: "Annotation comments, from a human curator" []
+is_a: SOFP:feature_property
+domain: SO:0000110
+range: xsd:string
+
+[Typedef]
+id: SOFP:cyto_range
+name: cyto_range
+namespace: feature_property
+def: "The cytological range covered by a feature. May be auto-generated from sequence coordinates, or determined by experimental methods" [so:cjm]
+is_a: SOFP:feature_property
+domain: SO:0000110
+range: xsd:string
+range_def: "Must conform to naming standard for that species; typically fly-style (eg 41A2-B3) or normal (eg 14p28.1-q32.2)" [so:cjm]
+comments: If auto-derived, may be redundant with feature location
+
+[Typedef]
+id: SOFP:description
+name: description
+namespace: feature_property
+def: "Free-text description of feature" []
+is_a: SOFP:feature_property
+domain: SO:0000110
+range: xsd:string
+comments: Often sourced from fasta header, in which case it includes everything after the > symbol
+
+[Typedef]
+id: SOFP:dicistronic
+name: dicistronic
+namespace: feature_property
+def: "true if transcript codes for >1 non-overlapping CDSs" []
+is_a: SOFP:feature_property
+domain: SO:0000115 ! transcript_feature
+range: xsd:boolean
+comments: redundant with secondary classification term SO:0000079
+
+[Typedef]
+id: SOFP:element
+name: element
+namespace: feature_property
+def: "name of transposable element class" []
+is_a: SOFP:feature_property
+domain: SO:0000110
+range: xsd:string
+comment: in chado or gff, this may also be indicated by a reference to a class in an ontology of TE classes
+
+[Typedef]
+id: SOFP:encoded_symbol
+name: encoded_symbol
+namespace: feature_property
+def: "dicistronic CDS/proteins are attached to a single gene feature representing the whole cassette - in which case the symbol refers to the cassette. encoded_symbol refers to a gene in the sense of non-overlapping CDS set. cf Adh and Adhr in dmel" []
+is_a: SOFP:feature_property
+domain: SO:0000110
+range: xsd:string
+
+[Typedef]
+id: SOFP:evidenceGB
+name: evidenceGB
+namespace: feature_property
+is_a: SOFP:feature_property
+domain: SO:0000110
+range: xsd:string
+range_def: "'experimental'"
+comment: same as GENBANK_SOFP:experimental??
+
+[Typedef]
+id: SOFP:linked_to
+name: linked_to
+namespace: feature_property
+is_a: SOFP:feature_property
+domain: SO:0000110
+range: xsd:string
+comment: someone please define.. to do with restriction fragments?
+
+[Typedef]
+id: SOFP:missing_start_codon
+name: missing_start_codon
+namespace: feature_property
+def: "true if start of CDS is unknown" []
+is_a: SOFP:feature_property
+domain: SO:0000110
+range: xsd:boolean
+comment: in chado, redundant with featureloc.is_{fmin,fmax}_partial
+
+[Typedef]
+id: SOFP:missing_stop_codon
+name: missing_stop_codon
+namespace: feature_property
+def: "true if end of CDS is unknown" []
+is_a: SOFP:feature_property
+domain: SO:0000110
+range: xsd:boolean
+comment: in chado, redundant with featureloc.is_{fmin,fmax}_partial
+
+[Typedef]
+id: SOFP:na_change
+name: na_change
+namespace: feature_property
+def: "A nucleic acid modification in some variant feature relative to the reference sequence" []
+description = The controlled vocabulary module for the Tripal package that integrates Drupal and GMOD chado. This module provides support for managing and viewing controlled vocabularies.
+ db_query($isql,'Plant Growth and Development Stages Ontology','http://palea.cgrb.oregonstate.edu/viewsvn/Poc/trunk/ontology/OBO_format/po_temporal.obo?view=co');
+ 'description' => 'The Chado cvtermpath table provides lineage for terms and is useful for quickly finding any ancestor parent of a term. However, this table must be populated. This page allows for populating of this table one vocabulary at a time',
+ functionality for managing controlled vocabularies and the terms they are
+ comprised of. The flexibility and extendibility of the chado schema depends
+ on controlled vocabularies. For example, by using a controlled vocabulary for
+ feature types the chado schema can describe features of any type, even those
+ we have not concieved of yet.</p>';
+
+ $text .= '<h3>Setup Instructions:</h3>';
+ $text .= '<p>After installation of the controlled vocabulary module, the following tasks should be performed:</p>';
+ $text .= '<ol>';
+ $text .= '<li><p><b>Set Permissions</b>: The cv module supports the Drupal user permissions interface for
+ controlling access to cv content and functions. These permissions include viewing,
+ creating, editing or administering of
+ cv content. The default is that only the original site administrator has these
+ permissions. You can <a href="'.url('admin/user/roles').'">add roles</a> for classifying users,
+ <a href="'.url('admin/user/user').'">assign users to roles</a> and
+ <a href="'.url('admin/user/permissions').'">assign permissions</a> for the cv content to
+ those roles. For a simple setup, allow anonymous users access to view organism content and
+ allow the site administrator all other permissions.</p></li>';
+ $text .= '<li><b>Loading of Ontologies/Controlled Vocabularies</b>: You can access this loader at '.
+ l('Admin->Tripal Management->Tripal CV->Add/Update Ontology With OBO File', 'admin/tripal/tripal_cv/obo_loader')
+ .'. This loader allows you to choose from a list of common ontologies or
+ enter the URL or location to an OBO file. Even the list of common
+ ontologies is using a URL ensuring you get the most up to date ontology.</p>';
+ $text .= '<p>This loader adds a Tripal Job which then waits in a queue to
+ be launched. To launch Tripal Jobs either navidate to the root of your
+ drupal installation and execute "php sites/all/modules/tripal/tripal_core/
+ tripal_launch_jobs.php <drupal user>" or set up a cron job (See user manual
+ for more details).</p>';
+ $text .= '<p>NOTE: in some cases, community developed ontologies for your
+ data may not yet be developed. In this case, it is suggested that you begin
+ developement of an ontology using one of the online tools. You might find
+ that many researchers are trying to deal with the same data and are willing
+ to help you in this endevor. You can '.l('create a controlled vocabulary','admin/tripal/tripal_cv/add_cv').' and '
+ . l('add terms to it', 'admin/tripal/tripal_cv/add_cvterm') .' to provide functionality to your site while you are waiting
+ for the ontology to be developed.</p></li>';
+ $text .= '</ol>';
+
+ $text .= '<h3>Features of this Module:</h3>';
+ $text .= '<p>Aside from the data loading described above, the Tripal Controlled Vocabulary (CV) module also provides the following functionality:</p>';
+ $text .= '<ul>';
+ $text .= '<li><b>Create/Update/Delete A Controlled Vocaulbulary</b>: to create your own controlled vocabulary go to '.
+ l('Admin->Tripal Management->Tripal CV->Add a Controlled Vocabulary','admin/tripal/tripal_cv/add_cv')
+ .' and fill out the form provided.To Update/Delete a controlled vocabulary
+ go to '.l('Admin->Tripal Management->Tripal CV->Update/Delete Controlled Vocabulary', 'admin/tripal/tripal_cv/edit_cv')
+ .', select the existing controlled vocabulary you want to modify and then
+ edit it as desired. This only modifies the name, description of a
+ controlled vocabulary. See the next section for adding, removing, editing
+ the term a controlled vocabulary contains.</li>';
+
+ $text .= '<li><b>Create a Controlled Vocaulbulary Term</b>: To Add a term to an already existing controlled vocabulary
+ go to '.l('Admin->Tripal Management->Tripal CV->Add a Controlled Vocabulary Term','admin/tripal/tripal_cv/add_cvterm')
+ .', select the controlled vocabulary you want to add terms to and then fill
+ out the form.</li>';
+ $text .= '<li><b>Controlled Vocabulary Term Browser</b>: This module provides a '.l('basic listing','admin/tripal/tripal_cv/list_cvterms').' of controlled vocabulry terms for
+ for all vocabularies currently in chado. It does not require indexing for Drupal searching but relies on Drupal Views.
+ <a href="http://drupal.org/project/views">Drupal Views</a> must be installed.</li>';
+ $text .= '<li><p><b>Integration with Drupal Views</b>: <a href="http://drupal.org/project/views">Drupal Views</a> is
+ a powerful tool that allows the site administrator to create lists or basic searching forms of Chado content.
+ It provides a graphical interface within Drupal to allow the site admin to directly query the Chado database
+ and create custom lists without PHP programming or customization of Tripal source code. Views can also
+ be created to filter content that has not yet been synced with Druapl in order to protect access to non
+ published data (only works if Chado was installed using Tripal). You can see a list of available pre-existing
+ Views <a href="'.url('admin/build/views/').'">here</a>, as well as create your own. </p></li>';
+ $text .= '</ul>';
+ return $text;
+}
+
+///////////////////////////////////////////
+// Edit/Delete CVs
+//////////////////////////////////////////
+
+/**
+ * Purpose: Provides the form for Updating and Deleteing existing
+ * chado controlled vocabularies (See chado cv table)
+ $handler->override_option('empty', 'There are no terms associated with the selected controlled vocabulary. Please select a different vocabulary from the list above.');
+description = The database module for the Tripal package that integrates Drupal and GMOD chado. This module provides support for managing and viewing external databases.
+ $text .= '<p>The Tripal DB Module provides functionality for linking the data in your Tripal Website with other biological websites out there. Essentially you register an enternal database with your website and then associate any of your data (usually sequence features) with that external database by providing the accession for your data in the other database. If the other database is online and you provided a URL prefix when you registered the external database with your site then there will be a link on the details page for your data that takes the user to the same record in the external database.</p>';
+
+ $text .= '<h3>Setup Instructions:</h3>';
+ $text .= '<ol>';
+ $text .= '<li><p><b>Set Permissions</b>: The feature module supports the Drupal user permissions interface for
+ controlling access to feature content and functions. These permissions include viewing,
+ creating, editing or administering of
+ feature content. The default is that only the original site administrator has these
+ permissions. You can <a href="'.url('admin/user/roles').'">add roles</a> for classifying users,
+ <a href="'.url('admin/user/user').'">assign users to roles</a> and
+ <a href="'.url('admin/user/permissions').'">assign permissions</a> for the feature content to
+ those roles. For a simple setup, allow anonymous users access to view organism content and
+ allow the site administrator all other permissions.</p></li>';
+ $text .= '<li><b>Register any external databases</b> with data pertinent to your site.</li>';
+ $text .= '<li><b>Create Database References</b>: Then as you load in your data, create database references linking your data to the external database.</li>';
+ $text .= 'By entering the name and any additional details into the <a href="tripal_db/add_db">add database form</a> you register an external database with your website. This allows you to specify that a sequence feature or other data is also stored in an external database. This is escpecially useful if the external database may contain additional details not stored in yours. If the external database is online you can even provide a URL prefix which will automatically link any data in your website to theirs via a web link.</li>';
+ $text .= 'To edit the details of an external database record or to delete an already existing external database, go to the <a href="tripal_db/edit_db">Update/Delete DBs form</a>. This will allow you to change details or enter new details.</li>';
+
+ $text .= '<li><b>List all External Database References</b>';
+ $text .= 'If you have views installed, there will be a link to a default listing of all database references currently in your database. This listing can be accessed <a href="tripal_db/list_dbxrefs">here</a>. It requires the Drupal Module Views version 2 to be installed (<a href="http://drupal.org/project/views">Drupal Views</a>)</li>';
+ '#description' => t('Please enter the name for this external database.'),
+ '#required' => TRUE,
+ '#default_value' => $default_db,
+ '#weight' => 1
+ );
+
+ $form['description']= array(
+ '#type' => 'textarea',
+ '#title' => t('Description'),
+ '#description' => t('Please enter a description for this database'),
+ '#default_value' => $default_desc,
+ '#weight' => 2
+ );
+ $form['url']= array(
+ '#type' => 'textfield',
+ '#title' => t('URL'),
+ '#description' => t('Please enter the web address for this database.'),
+ '#default_value' => $default_url,
+ '#weight' => 3
+ );
+ $form['urlprefix']= array(
+ '#type' => 'textfield',
+ '#title' => t('URL prefix'),
+ '#description' => t('Tripal can provide links to external databases when accession numbers or unique identifiers are known. Typically, a database will provide a unique web address for each accession and the accession usually is the last component of the page address. Please enter the web address, minus the accession number for this database. When an accession number is present, Tripal will combine this web address with the accession and provide a link to the external site.'),
+ $handler->override_option('empty', 'There are no database references matching the above criteria. Please select a database in order to display all references to that database.');
+ '#description' => t("Choose the analysis to which these features are associated "),
+ '#required' => TRUE,
+ '#options' => $analyses,
+ );
+
+ // Advanced Options
+ $form['advanced'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Advanced Options'),
+ '#collapsed' => TRUE
+ );
+ $form['advanced']['re_help']= array(
+ '#type' => 'item',
+ '#value' => t('A regular expression is an advanced method for extracting information from a string of text.
+ Your FASTA file may contain both a human-readable name and a unique name for each sequence.
+ If you want to import
+ both the name and unique name for all sequences, then you must provide regular expressions
+ so that the loader knows how to separate them.
+ Otherwise the name and uniquename will be the same.
+ By default, this loader will use the first word in the definition
+ lines of the FASTA file
+ as the name or unique name of the feature.'),
+ );
+ $form['advanced']['re_name']= array(
+ '#type' => 'textfield',
+ '#title' => t('Regular expression for the name'),
+ '#required' => FALSE,
+ '#description' => t('Enter the regular expression that will extract the
+ feature name from the FASTA definition line. For example, for a
+ defintion line with a name and unique name separated by a bar \'|\' (>seqname|uniquename),
+ the regular expression for the name would be, "^(.*?)\|.*$".'),
+ );
+ $form['advanced']['re_uname']= array(
+ '#type' => 'textfield',
+ '#title' => t('Regular expression for the unique name'),
+ '#required' => FALSE,
+ '#description' => t('Enter the regular expression that will extract the
+ feature name from the FASTA definition line. For example, for a
+ defintion line with a name and unique name separated by a bar \'|\' (>seqname|uniquename),
+ the regular expression for the unique name would be "^.*?\|(.*)$").'),
+ );
+
+
+ // Advanced database cross-reference optoins
+ $form['advanced']['db'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('External Database Reference'),
+ '#weight'=> 6,
+ '#collapsed' => TRUE
+ );
+ $form['advanced']['db']['re_accession']= array(
+ '#type' => 'textfield',
+ '#title' => t('Regular expression for the accession'),
+ '#required' => FALSE,
+ '#description' => t('Enter the regular expression that will extract the accession for the external database for each feature from the FASTA definition line.'),
+ '#weight' => 2
+ );
+
+ // get the list of databases
+ $sql = "SELECT * FROM {db} ORDER BY name";
+ $previous_db = tripal_db_set_active('chado'); // use chado database
+ $db_rset = db_query($sql);
+ tripal_db_set_active($previous_db); // now use drupal database
+ $dbs = array();
+ $dbs[''] = '';
+ while($db = db_fetch_object($db_rset)){
+ $dbs[$db->db_id] = "$db->name";
+ }
+ $form['advanced']['db']['db_id'] = array (
+ '#title' => t('External Database'),
+ '#type' => t('select'),
+ '#description' => t("Plese choose an external database for which these sequences have a cross reference."),
+ // if not local to Drupal, the file must be someplace else, just use
+ // the full path provided
+ $dfile = $fasta_file;
+ }
+ if(!file_exists($dfile)){
+ form_set_error('fasta_file',t("Cannot find the file on the system. Check that the file exists or that the web server has permissions to read the file."));
+ }
+
+ // make sure if a relationship is specified that all fields are provided.
+ if(($rel_type or $parent_type) and !$re_subject){
+ form_set_error('re_subject',t("Please provide a regular expression for the parent"));
+ }
+ if(($rel_type or $re_subject) and !$parent_type){
+ form_set_error('parent_type',t("Please provide a SO term for the parent"));
+ }
+ if(($parent_type or $re_subject) and !$rel_type){
+ form_set_error('rel_type',t("Please select a relationship type"));
+ }
+
+
+ // make sure if a database is specified that all fields are provided
+ if($db_id and !$re_accession){
+ form_set_error('re_accession',t("Please provide a regular expression for the accession"));
+ }
+ if($re_accession and !$db_id){
+ form_set_error('db_id',t("Please select a database"));
+ }
+
+ // check to make sure the types exists
+ $cvtermsql = "SELECT CVT.cvterm_id
+ FROM {cvterm} CVT
+ INNER JOIN {cv} CV on CVT.cv_id = CV.cv_id
+ LEFT JOIN {cvtermsynonym} CVTS on CVTS.cvterm_id = CVT.cvterm_id
+ WHERE cv.name = '%s' and (CVT.name = '%s' or CVTS.synonym = '%s')";
+ form_set_error('type',t("The Sequence Ontology (SO) term selected for the sequence type is not available in the database. Please check spelling or select another."));
+ form_set_error('parent_type',t("The Sequence Ontology (SO) term selected for the parent relationship is not available in the database. Please check spelling or select another."));
+ }
+ }
+
+ // check to make sure the 'relationship' and 'sequence' ontologies are loaded
+ // if not local to Drupal, the file must be someplace else, just use
+ // the full path provided
+ $dfile = $gff_file;
+ }
+ if(!file_exists($dfile)){
+ form_set_error('gff_file',t("Cannot find the file on the system. Check that the file exists or that the web server has permissions to read the file."));
+ }
+
+ if (($add_only and ($update or $refresh or $remove)) or
+ ($update and ($add_only or $refresh or $remove)) or
+ ($refresh and ($update or $add_only or $remove)) or
+ ($remove and ($update or $refresh or $add_only))){
+ form_set_error('add_only',t("Please select only one checkbox from the import options section"));
+ '#value' => t("Use one or more of the following fields to identify sets of features to be deleted."),
+ );
+
+ $form['feature_names']= array(
+ '#type' => 'textarea',
+ '#title' => t('Feature Names'),
+ '#description' => t('Please provide a list of feature names or unique names,
+ separated by spaces or by new lines to be delete. If you specify feature names then
+ all other options below will be ignored (except the unique checkbox).'),
+ );
+ $form['is_unique'] = array(
+ '#title' => t('Names are Unique Names'),
+ '#type' => 'checkbox',
+ '#description' => t('Select this checbox if the names listed in the feature
+ names box above are the unique name of the feature rather than the human readable names.'),
+ );
+ $form['seq_type']= array(
+ '#type' => 'textfield',
+ '#title' => t('Sequence Type'),
+ '#description' => t('Please enter the Sequence Ontology term that describes the features to be deleted. Use in conjunction with an organism or anaylysis.'),
+ );
+
+ $form['organism_id'] = array (
+ '#title' => t('Organism'),
+ '#type' => t('select'),
+ '#description' => t("Choose the organism for which features will be deleted."),
+ '#options' => $organisms,
+ );
+
+
+ // get the list of analyses
+ $sql = "SELECT * FROM {analysis} ORDER BY name";
+ $previous_db = tripal_db_set_active('chado'); // use chado database
+ $org_rset = db_query($sql);
+ tripal_db_set_active($previous_db); // now use drupal database
+ form_set_error('seq_type',t("The Sequence Ontology (SO) term selected for the sequence type is not available in the database. Please check spelling or select another."));
+ '#value' => t('Relationships are specified as follows: (Subject) (Type of Relationship) (Object). For example, X part_of Y, where X & Y are genomic features.')
+ $message = "Too many stocks match '".$form_state['values']['subject_id']."'! "
+ . " Please refine your input to match ONLY ONE stock. <br>"
+ . "To aid in this process, here are the stocks that match your initial input: "
+ .join(', ',$links);
+ form_set_error('subject_id', $message);
+ } elseif (sizeof($subject_results) < 1) {
+ form_set_error('subject_id', "There are no stocks matching your input. Please check your input for typos and/or lookup the stock ".l('here', 'stocks'));
+ $message = "Too many stocks match '".$form_state['values']['object_id']."'! "
+ . "Please refine your input to match ONLY ONE stock. <br>"
+ . "To aid in this process, here are the stocks that match your initial input: "
+ .join(', ',$links);
+ form_set_error('object_id', $message);
+ } elseif (sizeof($object_results) < 1) {
+ form_set_error('object_id', "There are no stocks matching your input. Please check your input for typos and/or lookup the stock ".l('here', 'stocks'));
+ $message = "Too many stocks match '".$form_state['values']["subject_id-$i"]."'! "
+ . "Please refine your input to match ONLY ONE stock. <br>"
+ . "To aid in this process, here are the stocks that match your initial input: "
+ .join(', ',$links);
+ form_set_error("subject_id-$i", $message);
+ } elseif (sizeof($subject_results) < 1) {
+ form_set_error("subject_id-$i", "There are no stocks matching your input. Please check your input for typos and/or lookup the stock ".l('here', 'stocks'));
+ $message = "Too many stocks match '".$form_state['values']["object_id-$i"]."'! "
+ . "Please refine your input to match ONLY ONE stock. <br>"
+ . "To aid in this process, here are the stocks that match your initial input: "
+ .join(', ',$links);
+ form_set_error("object_id-$i", $message);
+ } elseif (sizeof($object_results) < 1) {
+ form_set_error("object_id-$i", "There are no stocks matching your input. Please check your input for typos and/or lookup the stock ".l('here', 'stocks'));
+ $text .= '<p>This module provides an interface for the Chado feature module which stores information
+ related to genomic features. This module provides support for bulk loading of data in
+ FASTA or GFF format, visualization of "feature" pages, editing and updating.
+ </p>';
+
+ $text .= '<h3>Setup Instructions:</h3>';
+ $text .= '<p>After installation of the feature module. The following tasks should be performed
+ <ol>
+ <li><p><b>Set Permissions</b>: The feature module supports the Drupal user permissions interface for
+ controlling access to feature content and functions. These permissions include viewing,
+ creating, editing or administering of
+ feature content. The default is that only the original site administrator has these
+ permissions. You can <a href="'.url('admin/user/roles').'">add roles</a> for classifying users,
+ <a href="'.url('admin/user/user').'">assign users to roles</a> and
+ <a href="'.url('admin/user/permissions').'">assign permissions</a> for the feature content to
+ those roles. For a simple setup, allow anonymous users access to view organism content and
+ allow the site administrator all other permissions.</p></li>
+
+ <li><p><b>Themeing</b>: Before content from Chado can be visualized the Tripal base theme must
+ be installed. This should have been done prior to this point. But is mentioned here in the event you
+ follow the instructions below and cannot see content. In this case, if you do not see content
+ check that Tripal theming is properly installed</p></li>
+
+ <li><p><b>Loading of Ontologies</b>: If you
+ used Tripal to create the Chado database, then you must load ontologies before proceeding. Visit the
+ page to <a href="'.url('admin/tripal/tripal_cv/obo_loader').'">load ontologies</a> and load at
+ least the following ontologies:
+ <ul>
+ <li>Chado Feature Properties</li>
+ <li>Relationship Ontology</li>
+ <li>Sequence Ontology</li>
+ <li>Gene Ontology (if loading GO terms for features)</li>
+ </ul></p></li>
+
+ <li><p><b>Create Organisms</b>: Before adding feature data you must already have the
+ organisms loaded in the database. See the
+ <a href="'.url('admin/tripal/tripal_organism').'">Tripal Organism Admin page</a> for
+ instructions for adding and Syncing organisms.</p></li>
+
+ <li><p><b>Create Analysis</b>: Tripal requires that feature data loaded using the Tripal loaders
+ be associated with an analyis. This provides a grouping for the feature data and can be used
+ later to visualize data pipelines. Before loading feature data through the FASTA or GFF loaders
+ you will need to <a href="'.url('node/add').'">create an analysis</a> for the data.</p></li>
+
+ <li><p><b>Create Referring Database Entries</b>: If you would like to associate your feature data with an
+ external reference database, check to ensure that the <a href="'.url('admin/tripal/tripal_db/edit_db').'">
+ database record already exists</a>. If not you should <a href="'.url('admin/tripal/tripal_db/add_db').'">add a new database record</a> before importing
+ feature data.</p></li>
+
+ <li><p><b>Data Import</b>: if you do not already have an existing Chado database with preloaded data
+ then you will want
+ to import data. You can do so using the Chado perl scripts that come with the normal
+ <a href="http://gmod.org/wiki/Chado">distribution of Chado</a> or you can use the <a href="'.url('admin/tripal/tripal_feature/fasta_loader').'">FASTA loader</a> and
+ <a href="'.url('admin/tripal/tripal_feature/gff3_load').'">GFF loader</a> provided here. If you
+ created the Chado database using Tripal then you\'ll most likely want to use the Tripal loaders. If your data
+ is not condusive for loading with these loaders you may have to write your own loaders.
+ </p></li>
+
+ <li><p><b>Sync Features</b>: After data is loaded you need to sync features. This process is what
+ creates the pages for viewing online. Not all features need be synced. For instance, if you
+ have loaded whole genome sequence with fully defined gene models with several features to define
+ a gene and its products (e.g. gene, mRNA, CDS, 5\'UTR, 3\'UTR, etc) you probably only want to create
+ pages for genes or genes and mRNA. You probably do not want a page for a 5\'UTR.
+ Using the <a href="'.url('admin/tripal/tripal_feature/configuration/sync').'">Feature Sync page</a>
+ you can sync (or create pages) for the desired feature types. </p></li>
+
+ <li><p><b>Set Feature URL</b>: It is often convenient to have a simple URL for each feature page.
+ For example, http://www.mygenomesite.org/[feature], where [feature] is a unique identifier for a feature page.
+ With this, people can easily include links to feature pages of interest. Use the
+ <li><p><b>Integration with Drupal Views</b>: <a href="http://drupal.org/project/views">Drupal Views</a> is
+ a powerful tool that allows the site administrator to create lists or basic searching forms of Chado content.
+ It provides a graphical interface within Drupal to allow the site admin to directly query the Chado database
+ and create custom lists without PHP programming or customization of Tripal source code. Views can also
+ be created to filter content that has not yet been synced with Druapl in order to protect access to non
+ published data (only works if Chado was installed using Tripal). You can see a list of available pre-existing
+ Views <a href="'.url('admin/build/views/').'">here</a>, as well as create your own. </p></li>
+
+ <li><p><b>Basic Feature Lookup View</b>: This module provides a basic <a href="'.url('features').'">feature search
+ tool</a> for finding or listing features in Chado. It does not require indexing for Drupal searching but relies
+ on Drupal Views. <a href="http://drupal.org/project/views">Drupal Views</a> must be installed. </p></li>
+
+ <li><p><b>Delete Features</b>: This module provides a <a href="'.url('admin/tripal/tripal_feature/delete').'">Delete Feature page</a>
+ for bulk deltions of features. You may delete features using a list of feature names, or for a specific organism
+ or for a specific feature type.</p></li>
+
+ </ul>
+ </p>';
+
+ $text .= '<h3>Page Customizations</h3>';
+ $text .= '<p>There are several ways to customize the look-and-feel for the way Chado data is presented through Tripal.
+ Below is a description of several methods. These methods may be used in conjunction with one another to
+ provide fine-grained control.
+ <ul>
+
+ <li><p><b>Integration with Drupal Panels</b>: <a href="http://drupal.org/project/views">Drupal Panels</a>
+ allows for customization of a page layout if you don\'t want to do PHP/Javascript/CSS programming. Tripal comes with pre-set layouts for feature pages. However,
+ Panels become useful if you prefer a layout that is different from the pre-set layouts. Chado content
+ is provided to Panels in the form of Drupal "blocks" which you can then place anywhere on a page using the
+ Panel\'s GUI.</p></li>
+
+ <li><p><b>Drupal\'s Content Construction Kit (CCK)</b>: the
+ <a href="http://drupal.org/project/cck">Content Construction Kit (CCK) </a> is a powerful way to add non-Chado content
+ to any page without need to edit template files or knowing PHP. You must first download and install CCK.
+ With CCK, the site administartor can create a new field to appear on the page. For example, currently,
+ the Chado publication module is not yet supported by Tripal. Therefore, the site administrator can add a text
+ field to the feature pages. This content is not stored in Chado, but will appear on the feature page. A field
+ added by CCK will also appear in the form when editing a feature to allow users to manually enter the appropriate
+ text. If the default pre-set layout and themeing for Tripal is used, it is better to create the CCK element,
+ indicate that it is not to be shown (using the CCK interface), then manually add the new content type
+ where desired by editing the templates (as described below). If using Panels, the CCK field can be added to the
+ location desired using the Panels interface.</p></li>
+
+ <li><p><b>Drupal Node Templates</b>: The Tripal packages comes with a "theme_tripal" directory that contains the
+ themeing for Chado content. The feature module has a template file for feature "nodes" (Tripal feature pages). This file
+ is named "node-chado_feature.tpl.php", and provides javascript, HTML and PHP code for display of the feature
+ pages. You can edit this file to control which types of information (or which feature "blocks") are displayed for features. Be sure to
+ copy these template to your primary theme directory for editing. Do not edit them in the "theme_tripal" directory as
+ future Tripal updates may overwrite your customizations. See the <a href="http://tripal.sourceforge.net/">Tripal website </a>
+ for instructions on how to access variables and other Chado content within the template file.</p></li>
+
+ <li><p><b>Feature "Block" Templates</b>: In the "theme_tripal" directory is a subdirectory named "tripal_feature".
+ Inside this directory is a set of templates that control distinct types of information for features. For example,
+ there is a "base" template for displaying of data directly from the Chado feature table, and a "references"
+ template for showing external site references for a feature (data from the feature_dbxref table). These templates are used both by Drupal blocks
+ for use in Drupal Panels (as described above) or for use in the default pre-set layout that the node template
+ provides (also desribed above). You can customize this template as you desire. Be sure to copy the
+ template to your primary theme directory for editing. Do not edit them in the "theme_tripal" directory as
+ future Tripal updates may overwrite your customizations. See the <a href="http://tripal.sourceforge.net/">Tripal website </a>
+ for instructions on how to access variables and other Chado content within the template files.</p></li>
+ </li>
+
+ <li><p><b>Adding Links to the "Resources" Sidebar</b>: If you use the pre-set default Tripal layout for theming, you
+ will see a "Resources" sidebar on each page. The links that appear on the sidebar are automatically generated
+ using Javascript for all of the feature "Blocks" that appear on the page. If you want to add additional links
+ (e.g. a dynamic link to GBrowse for the feature) and you want that link to appear in the
+ "Resources" sidebar, simply edit the Drupal Node Template (as described above) and add the link to the
+ section at the bottom of the template file where the resources section is found.</p></li>
+
+ </ul>
+ </p>';
+
+ return $text;
+}
+
+/**
+ *
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_feature_admin () {
+
+ // before proceeding check to see if we have any
+ // currently processing jobs. If so, we don't want
+ 'show_feature_browser' => "Show the feature browser on the organism page. The browser loads when page loads. This may be slow for large sites.",
+ 'hide_feature_browser' => "Hide the feature browser on the organism page. Disables the feature browser completely.",
+ );
+// $allowedoptions ['allow_feature_browser'] = "Allow loading of the feature browsing through AJAX. For large sites the initial page load will be quick with the feature browser loading afterwards.";
+
+ $form['browser']['browser_desc'] = array(
+ '#type' => 'markup',
+ '#value' => 'A feature browser can be added to an organism page to allow users to quickly '.
+ 'access a feature. This will most likely not be the ideal mechanism for accessing feature '.
+ 'information, especially for large sites, but it will alow users exploring the site (such '.
+ 'as students) to better understand the data types available on the site.',
+
+ );
+ $form['browser']['feature_types'] = array(
+ '#title' => t('Feature Types'),
+ '#type' => 'textarea',
+ '#description' => t("Enter the Sequence Ontology (SO) terms for the feature types that ".
+ '#description' => t('Please enter the Sequence Ontology (SO) term for the base feature type for this aggregator.'),
+ '#default_value' => $default_base,
+ '#required' => TRUE,
+ '#weight' => 1
+ );
+ }
+
+ $form['others']= array(
+ '#type' => 'textarea',
+ '#title' => t('Aggregate these types if a relationship exists'),
+ '#description' => t('Please enter the Sequence Ontology (SO) terms that should be aggregated with the base feature type listed above. Separate each by a space or newline'),
+ 'description' => t('Features have relationships with other features and it may be desirable to aggregate the content from one ore more child or parent feature.'),
+ foreach($feature_synonyms as $index => $synonym){
+ $synonyms .= $synonym->synonym_id->name ."\n";
+ }
+ }
+ }
+
+ $analyses = $node->analyses;
+ $references = $node->references;
+
+ // We need to pass above variables for preview to show
+ $form['feature'] = array(
+ '#type' => 'value',
+ '#value' => $feature
+ );
+ // This field is read when previewing a node
+ $form['synonyms'] = array(
+ '#type' => 'value',
+ '#value' => $synonyms
+ );
+ // This field is read when previewing a node
+ $form['analyses'] = array(
+ '#type' => 'value',
+ '#value' => $analyses
+ );
+ // This field is read when previewing a node
+ $form['references'] = array(
+ '#type' => 'value',
+ '#value' => $references
+ );
+
+ // keep track of the feature id if we have one. If we do have one then
+ // this would indicate an update as opposed to an insert.
+ $form['feature_id'] = array(
+ '#type' => 'value',
+ '#value' => $feature->feature_id,
+ );
+
+ $form['title']= array(
+ '#type' => 'textfield',
+ '#title' => t('Title'),
+ '#required' => TRUE,
+ '#default_value' => $node->title,
+ '#description' => t('The title must be a unique identifier for this feature. It is recommended to use a combination of uniquename, organism and feature type in the title as this is guranteed to be unique.'),
+ '#weight' => 1,
+ '#maxlength' => 255
+ );
+
+ $form['uniquename']= array(
+ '#type' => 'textfield',
+ '#title' => t('Unique Feature Name'),
+ '#required' => TRUE,
+ '#default_value' => $feature->uniquename,
+ '#description' => t('Enter a unique name for this feature. This name must be unique for the organism and feature type.'),
+ '#weight' => 1,
+ '#maxlength' => 255
+ );
+
+ $form['fname']= array(
+ '#type' => 'textfield',
+ '#title' => t('Feature Name'),
+ '#required' => TRUE,
+ '#default_value' => $feature->name,
+ '#description' => t('Enter the name used by humans to refer to this feature.'),
+ '#weight' => 1,
+ '#maxlength' => 255
+ );
+
+ // get the list of supported feature types
+ $ftypes = array();
+ $ftypes[''] = '';
+ $supported_ftypes = split("[ \n]",variable_get('tripal_feature_type_setting','gene mRNA EST contig'));
+ foreach($supported_ftypes as $ftype){
+ $ftypes["$ftype"] = $ftype;
+ }
+
+ $form['feature_type'] = array (
+ '#title' => t('Feature Type'),
+ '#type' => t('select'),
+ '#description' => t("Choose the feature type."),
+ '#required' => TRUE,
+ '#default_value' => $feature->type_id->name,
+ '#options' => $ftypes,
+ '#weight' => 2
+ );
+ // get the list of organisms
+ $sql = "SELECT * FROM {Organism} ORDER BY genus, species";
+ $previous_db = tripal_db_set_active('chado'); // use chado database
+ $org_rset = db_query($sql);
+ tripal_db_set_active($previous_db); // now use drupal database
+ '#description' => t('Enter alternate names (synonmys) for this feature to help in searching and identification. You may enter as many alternate names as needed separated by spaces or on different lines.'),
+ '#weight' => 5,
+ );
+
+ $form['residues']= array(
+ '#type' => 'textarea',
+ '#title' => t('Residues'),
+ '#required' => FALSE,
+ '#default_value' => $feature->residues,
+ '#description' => t('Enter the nucelotide sequences for this feature'),
+ '#weight' => 6
+ );
+
+ $checked = '';
+ if($feature->is_obsolete == 't'){
+ $checked = '1';
+ }
+ $form['is_obsolete']= array(
+ '#type' => 'checkbox',
+ '#title' => t('Is Obsolete'),
+ '#required' => FALSE,
+ '#default_value' => $checked,
+ '#description' => t('Check this box if this sequence should be retired and no longer included in further analysis.'),
+ '#weight' => 8
+ );
+ return $form;
+}
+/**
+ *
+ *
+ * @ingroup tripal_feature
+ */
+function chado_feature_validate($node){
+ $result = 0;
+
+ // if this is an update, we want to make sure that a different feature for
+ // the organism doesn't already have this uniquename. We don't want to give
+ // two sequences the same uniquename
+ if($node->feature_id){
+ $sql = "SELECT *
+ FROM {Feature} F
+ INNER JOIN {cvterm} CVT ON F.type_id = CVT.cvterm_id
+ WHERE uniquename = '%s'
+ AND organism_id = %d AND CVT.name = '%s' AND NOT feature_id = %d";
+ form_set_error('uniquename',t("Feature update cannot proceed. The feature name '$node->uniquename' is not unique for this organism. Please provide a unique name for this feature. "));
+ }
+ }
+
+ // if this is an insert then we just need to make sure this name doesn't
+ // already exist for this organism if it does then we need to throw an error
+ else {
+ $sql = "SELECT *
+ FROM {Feature} F
+ INNER JOIN {cvterm} CVT ON F.type_id = CVT.cvterm_id
+ form_set_error('uniquename',t("Feature insert cannot proceed. The feature name '$node->uniquename' already exists for this organism. Please provide a unique name for this feature. "));
+ }
+ }
+
+ // we want to remove all characters except IUPAC nucleotide characters from the
+ // the residues. however, residues are not required so if blank then we'll skip
+ form_set_error('residues',t("The residues in feature $node->name contains more than the nucleotide IUPAC characters. Only the following characters are allowed: A,C,T,G,U,R,Y,M,K,S,W,B,D,H,V,N: '" . $residues ."'"));
+ }
+ }
+
+ // we don't allow a genbank accession number for a contig
+ if($node->feature_type == 'contig' and $node->gbaccession){
+ form_set_error('gbaccession',t("Contigs cannot have a genbank accession number. Please change the feature type or remove the accession number"));
+ }
+
+}
+/**
+ * When a node is requested by the user this function is called to allow us