Pārlūkot izejas kodu

Added interface for configuring Link-outs. Still doesn't actually link out in BLAST results.

Lacey Sanderson 10 gadi atpakaļ
vecāks
revīzija
30d3911339
3 mainītis faili ar 237 papildinājumiem un 18 dzēšanām
  1. 38 0
      api/blast_ui.api.inc
  2. 39 13
      blast_ui.install
  3. 160 5
      includes/blast_ui.node.inc

+ 38 - 0
api/blast_ui.api.inc

@@ -196,4 +196,42 @@ function validate_fasta_sequence($type, $sequence) {
     }
   }
   return FALSE;
+}
+
+/**
+ * Retrieve the regex to capture the Link-out Accession from the Hit Def.
+ *
+ * @param $nid
+ *   The node ID of the BLAST database the hit is from.
+ * @param $options
+ *   An array of options that can be passed to this function. Supported
+ *   options include:
+ *    -
+ *
+ * @return
+ *   A PHP regex for use with preg_match to cature the Link-out Accession.
+ */
+function get_blastdb_linkout_regex($node, $options = array()) {
+
+  if (empty($node->linkout->regex)) {
+    switch ($node->linkout->regex_type) {
+      case 'default':
+        $regex = '/^(\s+) .*/';
+        break;
+      case 'genbank':
+        $regex = '/^gb\|([^\|])*\|.*/';
+        break;
+      case 'embl':
+        $regex = '/^embl\|([^\|])*\|.*/';
+        break;
+      case 'swissprot':
+        $regex = '/^sp\|([^\|])*\|.*/';
+        break;
+    }
+  }
+  else {
+    $regex = $node->linkout->regex;
+  }
+
+  return $regex;
 }

+ 39 - 13
blast_ui.install

@@ -29,22 +29,22 @@ function blast_ui_schema(){
   $schema['blastdb'] = array(
     'description' => t('The base table for blastdb node'),
     'fields' => array(
-     'nid' => array(
-      'description' => t('The primary identifier for a node.'),
-      'type' => 'serial',
-      'unsigned' => true,
-      'not null' => true,
+      'nid' => array(
+        'description' => t('The primary identifier for a node.'),
+        'type' => 'serial',
+        'unsigned' => true,
+        'not null' => true,
       ),
-     'name' => array(
-       'description' => t('The human-readable name of the blast database.'),
-       'type' => 'varchar',
-       'length' => 255,
-       'not null' => true,
+      'name' => array(
+        'description' => t('The human-readable name of the blast database.'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => true,
       ),
       'path' => array(
         'description' => t('The full path and filename prefix of the blast database.'),
         'type' => 'varchar',
-         'length' => 1023,
+        'length' => 1023,
         'not null' => true,
       ),
       'dbtype' => array(
@@ -52,7 +52,15 @@ function blast_ui_schema(){
         'type' => 'varchar',
         'length' => 15,
         'not null' => true,
-       ),
+      ),
+      'dbxref_id_regex' => array(
+        'description' => t('The Regular Expression to use to extract the id from the FASTA header of the BLAST database hit.'),
+        'type' => 'text',
+      ),
+      'dbxref_db' => array(
+        'description' => t('The Database records from this BLAST Database reference.'),
+        'type' => 'int',
+      ),
     ),
     'indexes' => array(
       'name' => array('name'),
@@ -68,7 +76,7 @@ function blast_ui_schema(){
 }
 
 /**
- * Changing the length of the type field to allow it to be more readable.
+ * Make BlastDB type more readable & support Link-outs for BLAST Hits.
  */
 function blast_ui_update_7101() {
 
@@ -82,4 +90,22 @@ function blast_ui_update_7101() {
     )
   );
 
+  // Add fields related to Link-outs
+  db_add_field(
+    'blastdb',
+    'dbxref_id_regex',
+    array(
+      'description' => t('The Regular Expression to use to extract the id from the FASTA header of the BLAST database hit.'),
+      'type' => 'text',
+    )
+  );
+  db_add_field(
+    'blastdb',
+    'dbxref_db_id',
+    array(
+      'description' => t('The Database records from this BLAST Database reference.'),
+      'type' => 'int',
+    )
+  );
+
 }

+ 160 - 5
includes/blast_ui.node.inc

@@ -66,14 +66,21 @@ function blastdb_node_access($node, $op, $account) {
 function blastdb_form($node, &$form_state) {
   $form = array();
 
-  $form['db_name']= array(
+  $form['#validate'] = array('blastdb_form_validate');
+
+  $form['core'] = array(
+    '#type' => 'fieldset',
+    '#title' => 'General'
+  );
+
+  $form['core']['db_name']= array(
     '#type' => 'textfield',
     '#title' => t('Human-readable Name for Blast database'),
     '#required' => TRUE,
     '#default_value' => isset($node->db_name) ? $node->db_name : '',
   );
 
-  $form['db_path']= array(
+  $form['core']['db_path']= array(
     '#type' => 'textfield',
     '#title' => t('File Prefix including Full Path'),
     '#description' => t('The full path to your blast database including the file name but not the file type suffix. For example, /var/www/website/sites/default/files/myblastdb'),
@@ -81,7 +88,7 @@ function blastdb_form($node, &$form_state) {
     '#default_value' => isset($node->db_path) ? $node->db_path : '',
   );
 
-  $form['db_dbtype'] = array(
+  $form['core']['db_dbtype'] = array(
     '#type' => 'radios',
     '#title' => t('Type of the blast database'),
     '#options' => array(
@@ -92,19 +99,124 @@ function blastdb_form($node, &$form_state) {
     '#default_value' => isset($node->db_dbtype) ? $node->db_dbtype : 'n',
   );
 
+  $form['dbxref'] = array(
+    '#type' => 'fieldset',
+    '#title' => 'Database References',
+    '#description' => 'These settings can be used to tell the BLAST UI that '
+      . 'information about the records in this BLAST database can be found '
+      . 'either in the current website or an external website.'
+  );
+
+  $description = array(
+    'default' => 'A single word followed by a free-text definition. '
+      . 'The first word contains only alphanumeric characters and optionally '
+      . 'underscores and will be used as the ID of the sequence.',
+    'genbank' => 'Follows the same format as the first option '
+      . 'except that the first "word" is of the following form: '
+      . 'gb|accession|locus. The accession will be used as the ID of the sequence.',
+    'embl' => 'Follows the same format as the first option '
+      . 'except that the first "word" is of the following form: '
+      . 'emb|accession|locus. The accession will be used as the ID of the sequence.',
+    'swissprot' => 'Follows the same format as the first option '
+      . 'except that the first "word" is of the following form: '
+      . 'sp|accession|entry name. The accession will be used as the ID of the sequence.',
+    'custom' => 'Allows you to use a regular expression (define one below) to '
+      . 'extract a specifc portion of the FASTA header to be used as the ID.'
+  );
+  $form['dbxref']['dbxref_id_type'] = array(
+    '#type' => 'radios',
+    '#title' => 'FASTA header format',
+    '#description' => 'Choose the format that matches the format of the FASTA '
+      . 'headers in this BLAST database or choose custom to define your own '
+      . 'using regular expressions. This ID will be appended to the URL Prefix '
+      . ' of the database selected below.',
+    '#options' => array(
+      'default' => '<span title="' . $description['default'] . '">Generic</span>',
+      'genbank' => '<span title="' . $description['genbank'] . '">NCBI GenBank</span>',
+      'embl' => '<span title="' . $description['embl'] . '">EMBL Data Library</span>',
+      'swissprot' => '<span title="' . $description['swissprot'] . '">SWISS-PROT</span>',
+      'custom' => '<span title="' . $description['custom'] . '">Custom Format</span>',
+    ),
+    '#default_value' => ($node->linkout->regex_type) ? $node->linkout->regex_type : 'default',
+    '#ajax' => array(
+      'callback' => 'ajax_blast_ui_node_linkout_custom_callback',
+      'wrapper' => 'link-regex',
+    )
+  );
+
+  $hide_regex = TRUE;
+  if (isset($form_state['values']['dbxref_id_type'])) {
+    if ($form_state['values']['dbxref_id_type'] == 'custom') {
+      $hide_regex = FALSE;
+    }
+  }
+  $form['dbxref']['regex'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Regular Expression',
+    '#description' => t('A PHP Regular expression with curved brackets '
+      . 'surrounding the ID that should be used in the URL to provide a link-'
+      . 'out to additional information. See <a href="@url" target="_blank">PHP.net Regular '
+      . 'Expression Documentation</a> for more information. <strong>Be sure '
+      . 'to include the opening and closing slashes</strong>. This is only '
+      . 'available if custom was choosen for the FASTA header format above.',
+      array('@url' => 'http://php.net/manual/en/reference.pcre.pattern.syntax.php')),
+    '#disabled' => $hide_regex,
+    '#prefix' => '<div id="link-regex">',
+    '#suffix' => '</div>',
+    '#default_value' => $node->linkout->regex
+  );
+
+  $db_options = tripal_get_db_select_options();
+  $db_options[0] = '';
+  $form['dbxref']['db_id'] = array(
+    '#type' => 'select',
+    '#title' => 'External Database',
+    '#description' => 'The external database you would like to link-out to. '
+      . 'Note that this list includes all Tripal Databases and if the database '
+      . 'you would like to link-out to is not included you can add it '
+      . '<a href="" target="_blank">Here</a>.',
+    '#options' => $db_options,
+    '#default_value' => $node->linkout->db_id
+  );
+
   return $form;
 }
 
+function blastdb_form_validate($form, $form_state) {
+
+  // Check that any supplied regex includes //.
+  if (!preg_match('/\/.*\//', $form_state['values']['regex'])) {
+    form_set_error('regex', 'Regular Expressions require opening and closing slashes to delinate them. For example, <em>/^(\s+) .*/</em>');
+  }
+  // Check that the supplied regex is valid.
+  elseif (@preg_match($form_state['values']['regex'], NULL) === FALSE) {
+    form_set_error('regex', 'Regular Expression not valid. See '
+      . '<a href="http://php.net/manual/en/reference.pcre.pattern.syntax.php" target="_blank">PHP.net Regular '
+      . 'Expression Documentation</a> for more information.');
+  }
+}
+
 /**
  * Implements hook_insert().
  */
 function blastdb_insert($node) {
 
+  // Hangle Link-out Rules.
+  if ($node->dbxref_id_type == 'custom') {
+    $regex = $node->regex;
+  }
+  else {
+    $regex = $node->dbxref_id_type;
+  }
+
+  // Actually insert the record.
   db_insert('blastdb')->fields(array(
     'nid' => $node->nid,
     'name' => $node->db_name,
     'path' => $node->db_path,
     'dbtype' => $node->db_dbtype,
+    'dbxref_id_regex' => $regex,
+    'dbxref_db_id' => $node->db_id,
   ))->execute();
 
 }
@@ -123,10 +235,22 @@ function blast_ui_node_insert($node) {
  * Implements hook_update().
  */
 function blastdb_update($node) {
-    db_update('blastdb')->fields(array(
+
+  // Hangle Link-out Rules.
+  if ($node->dbxref_id_type == 'custom') {
+    $regex = $node->regex;
+  }
+  else {
+    $regex = $node->dbxref_id_type;
+  }
+
+  // Actually insert the record.
+  db_update('blastdb')->fields(array(
     'name' => $node->db_name,
     'path' => $node->db_path,
     'dbtype' => $node->db_dbtype,
+    'dbxref_id_regex' => $regex,
+    'dbxref_db_id' => $node->db_id,
   ))->condition('nid', $node->nid)->execute();
 }
 
@@ -152,14 +276,45 @@ function blastdb_delete($node) {
  */
 function blastdb_load($nodes) {
 
-  $result = db_query('SELECT nid, name, path, dbtype FROM {blastdb} WHERE nid IN (:nids)', array(':nids' => array_keys($nodes)));
+  $result = db_query('SELECT nid, name, path, dbtype, dbxref_id_regex, dbxref_db_id FROM {blastdb} WHERE nid IN (:nids)', array(':nids' => array_keys($nodes)));
 
   foreach ($result as $record) {
     $nodes[$record->nid]->db_name = $record->name;
     $nodes[$record->nid]->db_path = $record->path;
     $nodes[$record->nid]->title = $record->name;
     $nodes[$record->nid]->db_dbtype = $record->dbtype;
+
+    if ($record->dbxref_id_regex) {
+      $nodes[$record->nid]->linkout = new stdClass();
+
+      if (preg_match('/\/.*\//', $record->dbxref_id_regex)) {
+        $node->linkout->regex_type = 'custom';
+        $nodes[$record->nid]->linkout->regex = $record->dbxref_id_regex;
+      }
+      else {
+        $nodes[$record->nid]->linkout->regex_type = $record->dbxref_id_regex;
+        $nodes[$record->nid]->linkout->regex = get_blastdb_linkout_regex($nodes[$record->nid]);
+      }
+      $nodes[$record->nid]->linkout->db_id = $record->dbxref_db_id;
+    }
+    else {
+      $nodes[$record->nid]->linkout = new stdClass();
+      $nodes[$record->nid]->linkout->regex = '';
+      $nodes[$record->nid]->linkout->db_id = 0;
+      $nodes[$record->nid]->linkout->none = TRUE;
+    }
   }
 
 }
 
+/**
+ * AJAX Callback: Update Node Link-out Regex Textfield.
+ *
+ * On BlastDB node form the Link-out (dbxref) options allow for settings of a
+ * custom regex which should only be enabled when "Custom" is selected. This
+ * callback refreshes the regex textfield so it can change (ie: become enabled)
+ * when someone selects custom.
+ */
+function ajax_blast_ui_node_linkout_custom_callback($form, $form_state) {
+  return $form['dbxref']['regex'];
+}