Ver código fonte

Fixed problem with contact field as well as mistake with public tables in chado_query() statements

Stephen Ficklin 7 anos atrás
pai
commit
542f607357

+ 2 - 2
legacy/tripal_core/api/tripal_core.chado_nodes.api.inc

@@ -552,7 +552,7 @@ function chado_node_sync_form($form, &$form_state) {
       // yet been synced.
       $query = "SELECT " . implode(', ', $select) . ' ' .
                'FROM {' . $base_table . '} ' . $base_table . ' ' . implode(' ', $joins) . ' '.
-               "  LEFT JOIN {" . $linking_table . "} CT ON CT.$base_table_id = $base_table.$base_table_id " .
+               "  LEFT JOIN [" . $linking_table . "] CT ON CT.$base_table_id = $base_table.$base_table_id " .
                "WHERE CT.$base_table_id IS NULL";
 
       // extend the where clause if needed
@@ -862,7 +862,7 @@ function chado_node_sync_records($base_table, $max_sync = FALSE,
   $query = "
     SELECT " . implode(', ', $select) . ' ' .
     'FROM {' . $base_table . '} ' . $base_table . ' ' . implode(' ', $joins) . ' '.
-    "  LEFT JOIN {" . $linking_table . "} CT ON CT.$base_table_id = $base_table.$base_table_id " .
+    "  LEFT JOIN [" . $linking_table . "] CT ON CT.$base_table_id = $base_table.$base_table_id " .
     "WHERE CT.$base_table_id IS NULL ";
 
   // extend the where clause if needed

+ 0 - 114
legacy/tripal_feature/tripal_feature.module

@@ -108,34 +108,6 @@ function tripal_feature_permission() {
 function tripal_feature_menu() {
   $items = array();
 
-  // the administative settings menu
-  $items['find/sequences'] = array(
-    'title' => 'Sequence Retrieval',
-    'description' => 'Download a file of sequences',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('tripal_feature_seq_extract_form'),
-    'access arguments' => array('access chado_feature content'),
-    'file' =>  'includes/tripal_feature.seq_extract.inc',
-    'file path' => drupal_get_path('module', 'tripal_feature'),
-    'type' => MENU_CALLBACK,
-  );
-
-  $items['find/sequences/download'] = array(
-    'page callback' => 'tripal_feature_seq_extract_download',
-    'access arguments' => array('access chado_feature content'),
-    'file' =>  'includes/tripal_feature.seq_extract.inc',
-    'file path' => drupal_get_path('module', 'tripal_feature'),
-    'type' => MENU_CALLBACK,
-  );
-
-  // the menu link for addressing any feature (by name, uniquename, synonym)
-  $items['feature/%'] = array(
-    'page callback' => 'tripal_feature_match_features_page',
-    'page arguments' => array(1),
-    'access arguments' => array('access chado_feature content'),
-    'type' => MENU_LOCAL_TASK,
-  );
-
   // the administative settings menu
   $items['admin/tripal/legacy/tripal_feature'] = array(
     'title' => 'Features',
@@ -324,11 +296,6 @@ function tripal_feature_theme($existing, $type, $theme, $path) {
     'path' => "$path/theme/templates"
   );
 
-  // Themed Forms
-  $items['tripal_feature_seq_extract_form'] = array(
-     'render element' => 'form',
-  );
-
   // D3 Charts.
   // Feature Type/Organism Stacked Bar Chart.
   $items['tripal_feature_bar_chart_type_organism_summary'] = array(
@@ -441,87 +408,6 @@ function tripal_feature_coder_ignore() {
   );
 }
 
-/*
- * Uses the value provided in the $id argument to find all features that match
- * that ID by name, featurename or synonym.  If it matches uniquenly to a single
- * feature it will redirect to that feature page, otherwise, a list of matching
- * features is shown.
- *
- * @ingroup tripal_feature
- */
-function tripal_feature_match_features_page($id) {
-
-  // first check to see if the URL (e.g. /feature/$id) is already
-  // assigned to a node. If so, then just go there.  Otherwise,
-  // try to find the feature.
-  $sql = "
-    SELECT source
-    FROM {url_alias}
-    WHERE alias = :alias
-  ";
-  $match = db_query($sql, array(':alias' => "feature/$id"))->fetchObject();
-  if ($match) {
-    drupal_goto($match->source);
-    return;
-  }
-  $sql = "
-    SELECT
-      F.name, F.uniquename, F.feature_id,
-      O.genus, O.species, O.organism_id,
-      CVT.cvterm_id, CVT.name as type_name,
-      CF.nid,
-      array_agg(S.name) as synonyms
-    FROM {feature} F
-      INNER JOIN {organism} O on F.organism_id = O.organism_id
-      INNER JOIN {cvterm} CVT on CVT.cvterm_id = F.type_id
-      LEFT JOIN {feature_synonym} FS on FS.feature_id = F.feature_id
-      LEFT JOIN {synonym} S on S.synonym_id = FS.synonym_id
-      INNER JOIN {chado_feature} CF on CF.feature_id = F.feature_id
-    WHERE
-      F.uniquename = :uname or
-      F.name = :fname or
-      S.name = :sname
-    GROUP BY F.name, F.uniquename, F.feature_id, O.genus, O.species,
-      O.organism_id, CVT.cvterm_id, CVT.name, CF.nid
-  ";
-
-  $args = array(':uname' => $id, ':fname' => $id, ':sname' => $id);
-  $results = chado_query($sql, $args);
-
-  $num_matches = 0;
-
-  // iterate through the matches and build the table for showing matches
-  $header = array('Uniquename', 'Name', 'Type', 'Species', 'Synonyms');
-  $rows = array();
-  $curr_match;
-  while ($match = $results->fetchObject()) {
-    $curr_match = $match;
-    $synonyms = $match->synonyms;
-    $synonyms = preg_replace('/[\"\{\}]/', '', $synonyms);
-    $rows[] = array(
-       $match->uniquename,
-       "<a href=\"" . url("node/" . $match->nid) . "\">" . $match->name . "</a>",
-       $match->type_name,
-       '<i>' . $match->genus . ' ' . $match->species . '</i>',
-       $synonyms,
-    );
-    $num_matches++;
-  }
-
-  // if we have more than one match then generate the table, otherwise, redirect
-  // to the matched feature
-  if ($num_matches == 1) {
-    drupal_goto("node/" . $curr_match->nid);
-  }
-  if ($num_matches == 0) {
-    return "<p>No features matched the given name '$id'</p>";
-  }
-
-  $table_attrs = array('class' => 'tripal-data-table');
-  $output = "<p>The following features match the name '$id'.</p>";
-  $output .= theme_table($header, $rows, $table_attrs, $caption);
-  return $output;
-}
 
 /**
  * Implementation of hook_form_alter()

+ 1 - 1
legacy/tripal_pub/includes/tripal_pub.pub_search.inc

@@ -575,7 +575,7 @@ function tripal_search_publications($search_array, $offset, $limit, &$total_reco
   // build the SQL based on the criteria provided by the user
   $select = "SELECT DISTINCT P.*, CP.nid ";
   $from   = "FROM {pub} P
-               LEFT JOIN {chado_pub} CP on P.pub_id = CP.pub_id
+               LEFT JOIN [chado_pub] CP on P.pub_id = CP.pub_id
                INNER JOIN {cvterm} CVT on CVT.cvterm_id = P.type_id
             ";
   $where  = "WHERE (NOT P.title = 'null') "; // always exclude the dummy pub

+ 1 - 1
legacy/tripal_stock/tripal_stock.module

@@ -392,7 +392,7 @@ function tripal_stock_match_stocks_page($id) {
     FROM {stock} S
       INNER JOIN {organism} O on S.organism_id = O.organism_id
       INNER JOIN {cvterm} CVT on CVT.cvterm_id = S.type_id
-      INNER JOIN {chado_stock} CS on CS.stock_id = S.stock_id
+      INNER JOIN [chado_stock] CS on CS.stock_id = S.stock_id
     WHERE
       S.uniquename = :uname or S.name = :name
   ";

+ 2 - 2
tripal_chado/api/tripal_chado.api.inc

@@ -70,14 +70,14 @@ function tripal_chado_publish_records($values, $job_id = NULL) {
   $select = "SELECT T.$pkey_field as record_id ";
   $from = "
     FROM {" . $table . "} T
-      LEFT JOIN {" . $chado_entity_table . "} CE on CE.record_id = T.$pkey_field
+      LEFT JOIN [" . $chado_entity_table . "] CE on CE.record_id = T.$pkey_field
   ";
 
   // For migration of Tripal v2 nodes to entities we want to include the
   // coresponding chado linker table.
   if ($sync_node && db_table_exists('chado_' . $table)) {
     $select = "SELECT T.$pkey_field as record_id, CT.nid ";
-    $from .= " INNER JOIN {chado_" . $table . "} CT ON CT.$pkey_field = T.$pkey_field";
+    $from .= " INNER JOIN [chado_" . $table . "] CT ON CT.$pkey_field = T.$pkey_field";
   }
   $where = " WHERE CE.record_id IS NULL ";
 

+ 3 - 3
tripal_chado/includes/TripalFields/chado_linker__contact/chado_linker__contact.inc

@@ -117,7 +117,7 @@ class chado_linker__contact extends ChadoField {
     $field_table = $this->instance['settings']['chado_table'];
     $field_column = $this->instance['settings']['chado_column'];
 
-    $type_term = tripal_get_chado_semweb_term('contact', 'type');
+    $type_term = tripal_get_chado_semweb_term('contact', 'type_id');
     $name_term = tripal_get_chado_semweb_term('contact', 'name');
     $description_term = tripal_get_chado_semweb_term('contact', 'description');
 
@@ -136,7 +136,7 @@ class chado_linker__contact extends ChadoField {
     $entity->{$field_name}['und'][0] = array(
       'value' => array(),
       'chado-' . $field_table . '__' . $pkey => '',
-      'chado-' . $field_table . '__' . $fkey_lcolumn => '',
+      'chado-' . $field_table . '__' . $fkey_lcolumn => $record->$fkey_lcolumn,
       'chado-' . $field_table . '__' . 'contact_id' => '',
       // Ignore the synonym_sgml column for now.
     );
@@ -169,7 +169,7 @@ class chado_linker__contact extends ChadoField {
           // Add elements that are not part of the values but used by
           // the chado storage back-end for saving values.
           'chado-' . $field_table . '__' . $pkey => $contact_linker->$pkey,
-          'chado-' . $field_table . '__' . $fkey_lcolumn => $contact_linker->$fkey_lcolumn->$fkey_lcolumn,
+          'chado-' . $field_table . '__' . $fkey_lcolumn => $record->$fkey_lcolumn,
           'chado-' . $field_table . '__' . 'contact_id' => $contact->contact_id
         );
 

+ 7 - 3
tripal_chado/includes/TripalFields/chado_linker__contact/chado_linker__contact_formatter.inc

@@ -24,6 +24,10 @@ class chado_linker__contact_formatter extends ChadoFieldFormatter {
     // Get the settings
     $settings = $display['settings'];
 
+    $type_term = tripal_get_chado_semweb_term('contact', 'type_id');
+    $name_term = tripal_get_chado_semweb_term('contact', 'name');
+    $description_term = tripal_get_chado_semweb_term('contact', 'description');
+
     $headers = array('Name', 'Description', 'Type');
     $rows = array();
 
@@ -34,9 +38,9 @@ class chado_linker__contact_formatter extends ChadoFieldFormatter {
       }
 
       // Get the field values
-      $contact_name = $contact['name'];
-      $description = $contact['description'];
-      $type = $contact['type'];
+      $contact_name = $contact[$name_term];
+      $description = $contact[$description_term];
+      $type = $contact[$type_term];
 
       // Add a link i there is an entity.
       if (array_key_exists('entity', $item['value']) and $item['value']['entity']) {

+ 45 - 49
tripal_chado/includes/TripalFields/chado_linker__contact/chado_linker__contact_widget.inc

@@ -15,53 +15,60 @@ class chado_linker__contact_widget extends ChadoFieldWidget {
     parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
 
     $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
+    $base_table = $this->instance['settings']['base_table'];
+    $chado_table = $this->instance['settings']['chado_table'];
+    $chado_column = $this->instance['settings']['chado_column'];
+    $instance = $this->instance;
 
     // Get the FK column that links to the base table.
-    $table_name = $this->instance['settings']['chado_table'];
-    $base_table = $this->instance['settings']['base_table'];
-    $schema = chado_get_schema($table_name);
+    $schema = chado_get_schema($chado_table);
     $pkey = $schema['primary key'][0];
-    $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
-    $fkey = $fkeys[0];
+    $lfkey_field = key($schema['foreign keys'][$base_table]['columns']);
 
     // Get the field defaults.
     $record_id = '';
-    $fkey_value = array_key_exists('#entity', $element) and $element['#entity'] ? $element['#entity']->chado_record_id : NULL;
+    $fk_value = array_key_exists('#entity', $element) and $element['#entity'] ? $element['#entity']->chado_record_id : NULL;
     $contact_id = '';
     $name = '';
+    $value = '';
+
 
     // If the field already has a value then it will come through the $items
     // array.  This happens when editing an existing record.
-    if (count($items) > 0 and array_key_exists($delta, $items)) {
-      $record_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $table_name . '__' . $pkey, $record_id);
-      $contact_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $table_name . '__contact_id', $contact_id);
-      if ($contact_id) {
-        $contact = chado_generate_var('contact', array('contact_id' => $contact_id));
-        $name = $contact->name;
+    if (count($items) > 0) {
+      // Check for element values that correspond to fields in the Chado table.
+      $fk_value = tripal_get_field_item_keyval($items, 0, 'chado-' . $chado_table . '__' . $lfkey_field, $fk_value);
+      if (array_key_exists($delta, $items)) {
+        $record_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $chado_table . '__' . $pkey, $record_id);
+        $contact_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $chado_table . '__contact_id', $contact_id);
       }
     }
 
-    $schema = chado_get_schema('contact');
+    // Check $form_state['values'] to see if an AJAX call set the values.
+    if (array_key_exists('values', $form_state) and array_key_exists($delta, $form_state['values'])) {
+      $record_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__' . $pkey];
+      $fk_value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__' . $lfkey_field];
+      $contact_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__contact_id'];
+    }
+
 
-    $widget['#table_name'] = $table_name;
-    $widget['#fkey_field'] = $fkey;
-    $widget['#prefix'] =  "<span id='$table_name-$delta'>";
-    $widget['#suffix'] =  "</span>";
+    $schema = chado_get_schema('contact');
 
     $widget['value'] = array(
       '#type' => 'value',
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
 
-    $widget['chado-' . $table_name . '__' . $pkey] = array(
+    $widget['chado-' . $chado_table . '__' . $pkey] = array(
       '#type' => 'value',
       '#default_value' => $record_id,
     );
-    $widget['chado-' . $table_name . '__' . $fkey] = array(
+    $widget['chado-' . $chado_table . '__' . $lfkey_field] = array(
       '#type' => 'value',
-      '#default_value' => $fkey_value,
+      '#default_value' => $fk_value,
     );
-    $widget['chado-' . $table_name . '__contact_id'] = array(
+    $widget['chado-' . $chado_table . '__contact_id'] = array(
       '#type' => 'value',
       '#default_value' => $contact_id,
     );
@@ -73,7 +80,7 @@ class chado_linker__contact_widget extends ChadoFieldWidget {
       '#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/contact',
       '#ajax' => array(
         'callback' => "chado_linker__contact_widget_form_ajax_callback",
-        'wrapper' => "$table_name-$delta",
+        'wrapper' => "$chado_table-$delta",
         'effect' => 'fade',
         'method' => 'replace'
       ),
@@ -87,41 +94,30 @@ class chado_linker__contact_widget extends ChadoFieldWidget {
    * @see TripalFieldWidget::submit()
    */
   public function submit($form, &$form_state, $entity_type, $entity, $langcode, $delta) {
-    // Get the FK column that links to the base table.
-    $table_name = $this->instance['settings']['chado_table'];
+    $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
     $base_table = $this->instance['settings']['base_table'];
-    $schema = chado_get_schema($table_name);
+    $chado_table = $this->instance['settings']['chado_table'];
+    $chado_column = $this->instance['settings']['chado_column'];
+    $instance = $this->instance;
+    $schema = chado_get_schema($chado_table);
+
     $pkey = $schema['primary key'][0];
-    $fkeys = array_values($schema['foreign keys'][$base_table]['columns']);
-    $fkey = $fkeys[0];
-    $field_name = $this->field['field_name'];
+    $lfkey_field = key($schema['foreign keys'][$base_table]['columns']);
 
     // Get the field values.
-    $fkey_value = isset($form_state['values'][$field_name][$langcode][$delta]['value']) ? $form_state['values'][$field_name][$langcode][$delta]['value'] : '';
-    $contact_id = isset($form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__contact_id']) ? $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__contact_id'] : '';
-    $name = isset($form_state['values'][$field_name][$langcode][$delta]['name']) ? $form_state['values'][$field_name][$langcode][$delta]['name'] : '';
+    $record_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__' . $pkey];
+    $fk_value = $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__' . $lfkey_field];
+    $contact_id = $form_state['values'][$field_name]['und'][$delta]['chado-' . $chado_table . '__contact_id'];
+    $name = $form_state['values'][$field_name]['und'][$delta]['name'];
 
     // If the user provided a name then we want to set the foreign key
     // value to be the chado_record_id
-    if ($name and !$contact_id) {
+    if ($name) {
       $contact = chado_generate_var('contact', array('name' => $name));
-      $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__contact_id'] = $contact->contact_id;
-    }
-
-    // In the widgetForm function we automatically add the foreign key
-    // record.  But if the user did not provide a contact we want to take
-    // it out so that the Chado field_storage infrastructure won't try to
-    // write a record.
-    if (!$name and !$contact_id) {
-      $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $fkey] = '';
-    }
-
-    // If the user removed the contact from the contact_name field
-    // then we want to clear out the rest of the hidden values.
-    // Leave the primary key so the record can be deleted.
-    if (!$name and $contact_id) {
-      $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__' . $fkey] = '';
-      $form_state['values'][$field_name][$langcode][$delta]['chado-' . $table_name . '__contact_id'] = '';
+      $form_state['values'][$field_name][$langcode][$delta]['chado-' . $chado_table . '__contact_id'] = $contact->contact_id;
+      $form_state['values'][$field_name][$langcode][$delta]['value'] = $name;
     }
+    dpm($form_state['values']);
   }
 }

+ 6 - 0
tripal_chado/includes/tripal_chado.entity.inc

@@ -199,6 +199,12 @@ function tripal_chado_tripal_default_title_format($bundle, $available_tokens) {
       'weight' => -5,
     );
   }
+  if ($table == 'contact') {
+    $format[] = array(
+      'format' => '[schema__name]',
+      'weight' => -5,
+    );
+  }
   return $format;
 }
 

+ 9 - 8
tripal_chado/includes/tripal_chado.field_storage.inc

@@ -43,7 +43,7 @@ function tripal_chado_field_storage_write($entity_type, $entity, $op, $fields) {
 
   // Convert the fields into a key/value list of fields and their values.
   $field_vals = tripal_chado_field_storage_write_merge_fields($fields, $entity_type, $entity);
-
+dpm($field_vals);
   // First, write the record for the base table.  If we have a record id then
   // this is an update and we need to set the primary key.  If not, then this
   // is an insert and we need to set the type_id if the table supports it.
@@ -60,13 +60,14 @@ function tripal_chado_field_storage_write($entity_type, $entity, $op, $fields) {
   if ($op == FIELD_STORAGE_INSERT) {
     // Add the record to the proper chado entity table
     $chado_entity_table = chado_get_bundle_entity_table($bundle);
-    $record = array(
-      'entity_id' => $entity->id,
-      'record_id' => $base_record_id,
-    );
-    $success = drupal_write_record($chado_entity_table, $record);
-    if (!$success) {
-      drupal_set_message('Unable to insert new Chado entity.', 'error');
+    $record_id = db_insert($chado_entity_table)
+      ->fields(array(
+        'entity_id' => $entity->id,
+        'record_id' => $base_record_id
+      ))
+      ->execute();
+    if (!$record_id) {
+      throw new Exception('Unable to insert new Chado entity.');
     }
   }
 

+ 7 - 7
tripal_chado/includes/tripal_chado.migrate.inc

@@ -131,7 +131,7 @@ function tripal_chado_migrate_form($form, &$form_state) {
         $sql =
            "SELECT count(*)
             FROM {organism} O
-            INNER JOIN {chado_organism} CO ON O.organism_id = CO.organism_id
+            INNER JOIN [chado_organism] CO ON O.organism_id = CO.organism_id
           ";
         $org_count = chado_query($sql)->fetchField();
         if ($org_count > 0) {
@@ -147,7 +147,7 @@ function tripal_chado_migrate_form($form, &$form_state) {
         $sql =
         "SELECT count(*)
           FROM {analysis} A
-          INNER JOIN {chado_analysis} CA ON A.analysis_id = CA.analysis_id
+          INNER JOIN [chado_analysis] CA ON A.analysis_id = CA.analysis_id
          ";
         $ana_count = chado_query($sql)->fetchField();
         if ($ana_count > 0) {
@@ -163,7 +163,7 @@ function tripal_chado_migrate_form($form, &$form_state) {
         $sql =
           "SELECT count(*)
            FROM {project} P
-           INNER JOIN {chado_project} CP ON P.project_id = CP.project_id
+           INNER JOIN [chado_project] CP ON P.project_id = CP.project_id
           ";
         $proj_count = chado_query($sql)->fetchField();
         if ($proj_count > 0) {
@@ -179,7 +179,7 @@ function tripal_chado_migrate_form($form, &$form_state) {
         $sql =
           "SELECT count(*)
             FROM {featuremap} M
-            INNER JOIN {chado_featuremap} CM ON M.featuremap_id = CM.featuremap_id
+            INNER JOIN [chado_featuremap] CM ON M.featuremap_id = CM.featuremap_id
           ";
         $map_count = chado_query($sql)->fetchField();
         if ($map_count > 0) {
@@ -195,7 +195,7 @@ function tripal_chado_migrate_form($form, &$form_state) {
         $sql =
           "SELECT count(*)
            FROM {pub} P
-           INNER JOIN {chado_pub} CP ON P.pub_id = CP.pub_id
+           INNER JOIN [chado_pub] CP ON P.pub_id = CP.pub_id
          ";
         $proj_count = chado_query($sql)->fetchField();
         if ($proj_count > 0) {
@@ -212,7 +212,7 @@ function tripal_chado_migrate_form($form, &$form_state) {
         $sql =
             "SELECT V.name AS type, X.accession, db.name AS vocabulary , count(*) AS num
               FROM {" . $table . "} T
-              INNER JOIN {" . $tv2_content_type . "} CT ON T.$pkey = CT.$pkey
+              INNER JOIN [" . $tv2_content_type . "] CT ON T.$pkey = CT.$pkey
               INNER JOIN {cvterm} V ON V.cvterm_id = T.type_id
               INNER JOIN {dbxref} X ON X.dbxref_id = V.dbxref_id
               INNER JOIN {db} ON db.db_id = X.db_id
@@ -671,7 +671,7 @@ function tripal_chado_migrate_map_types($tv2_content_types) {
       $sql = "
         SELECT V.name AS type, X.accession, db.name AS vocabulary
         FROM {" . $table . "} T
-          INNER JOIN {" . $tv2_content_type . "} CT ON T.$pkey = CT.$pkey
+          INNER JOIN [" . $tv2_content_type . "] CT ON T.$pkey = CT.$pkey
           INNER JOIN {cvterm} V ON V.cvterm_id = T.type_id
           INNER JOIN {dbxref} X ON X.dbxref_id = V.dbxref_id
           INNER JOIN {db} ON db.db_id = X.db_id

+ 13 - 13
legacy/tripal_feature/includes/tripal_feature.seq_extract.inc → tripal_chado/includes/tripal_chado.seq_extract.inc

@@ -7,9 +7,9 @@
 /**
  * The page allowing users to download feature sequences
  *
- * @ingroup tripal_feature
+ * @ingroup tripal_chado_feature
  */
-function tripal_feature_seq_extract_download() {
+function tripal_chado_feature_seq_extract_download() {
 
   if (!array_key_exists('tripal_feature_seq_extract', $_SESSION)) {
     drupal_goto('find/sequences');
@@ -73,9 +73,9 @@ function tripal_feature_seq_extract_download() {
 /**
  * Form to choose which features to extract sequence for
  *
- * @ingroup tripal_feature
+ * @ingroup tripal_chado_feature
  */
-function tripal_feature_seq_extract_form($form, &$form_state) {
+function tripal_chado_feature_seq_extract_form($form, &$form_state) {
 
   $form['#true'] = TRUE;
 
@@ -180,7 +180,7 @@ function tripal_feature_seq_extract_form($form, &$form_state) {
     '#multiple'      => FALSE,
     '#description'   => t('The organism\'s genus. If specified, features for all organism with this genus will be retrieved.'),
     '#ajax' => array(
-      'callback'    => 'tripal_feature_seq_extract_form_ajax_callback',
+      'callback'    => 'tripal_chado_feature_seq_extract_form_ajax_callback',
       'wrapper' => 'tripal-feature-seq-extract-form',
       'event'   => 'change',
       'method'  => 'replace',
@@ -209,7 +209,7 @@ function tripal_feature_seq_extract_form($form, &$form_state) {
     '#multiple'      => FALSE,
     '#description'   => t('The organism\'s species name. If specified, features for all organisms with this species will be retrieved.  Please first select a genus'),
     '#ajax' => array(
-      'callback'    => 'tripal_feature_seq_extract_form_ajax_callback',
+      'callback'    => 'tripal_chado_feature_seq_extract_form_ajax_callback',
       'wrapper' => 'tripal-feature-seq-extract-form',
       'event'   => 'change',
       'method'  => 'replace',
@@ -363,9 +363,9 @@ function tripal_feature_seq_extract_form($form, &$form_state) {
 /**
  * Theme the Form to choose which features to extract sequence for
  *
- * @ingroup tripal_feature
+ * @ingroup tripal_chado_feature
  */
-function theme_tripal_feature_seq_extract_form(&$variables) {
+function theme_tripal_chado_feature_seq_extract_form(&$variables) {
   $form = $variables['form'];
 
   $headers = array();
@@ -423,16 +423,16 @@ function theme_tripal_feature_seq_extract_form(&$variables) {
 /**
  * Ajax function which returns the form via ajax
  */
-function tripal_feature_seq_extract_form_ajax_callback($form, &$form_state) {
+function tripal_chado_feature_seq_extract_form_ajax_callback($form, &$form_state) {
   return $form;
 }
 
 /**
  * Validate the extract sequence form
  *
- * @ingroup tripal_feature
+ * @ingroup tripal_chado_feature
  */
-function tripal_feature_seq_extract_form_validate($form, &$form_state) {
+function tripal_chado_feature_seq_extract_form_validate($form, &$form_state) {
   $genus      = $form_state['values']['genus'];
   $species    = $form_state['values']['species'];
   $analysis   = $form_state['values']['analysis'];
@@ -467,9 +467,9 @@ function tripal_feature_seq_extract_form_validate($form, &$form_state) {
 /**
  * Submit the extract sequence form
  *
- * @ingroup tripal_feature
+ * @ingroup tripal_chado_feature
  */
-function tripal_feature_seq_extract_form_submit($form, &$form_state) {
+function tripal_chado_feature_seq_extract_form_submit($form, &$form_state) {
   $genus      = $form_state['values']['genus'];
   $species    = $form_state['values']['species'];
   $analysis   = $form_state['values']['analysis'];

+ 153 - 0
tripal_chado/tripal_chado.module

@@ -684,6 +684,37 @@ function tripal_chado_menu() {
     'type' => MENU_CALLBACK,
   );
 
+  //////////////////////////////////////////////////////////////////////////////
+  //                           FEATURES
+  //////////////////////////////////////////////////////////////////////////////
+  // the menu link for addressing any feature (by name, uniquename, synonym)
+  $items['feature/%'] = array(
+    'page callback' => 'tripal_feature_match_features_page',
+    'page arguments' => array(1),
+    'access arguments' => array('access chado_feature content'),
+    'type' => MENU_LOCAL_TASK,
+  );
+
+  // the administative settings menu
+  $items['find/sequences'] = array(
+    'title' => 'Sequence Retrieval',
+    'description' => 'Download a file of sequences',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_chado_feature_seq_extract_form'),
+    'access arguments' => array('access chado_feature content'),
+    'file' =>  'includes/tripal_chado.seq_extract.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+    'type' => MENU_CALLBACK,
+  );
+
+  $items['find/sequences/download'] = array(
+    'page callback' => 'tripal_chado_feature_seq_extract_download',
+    'access arguments' => array('access chado_feature content'),
+    'file' =>  'includes/tripal_chado.seq_extract.inc',
+    'file path' => drupal_get_path('module', 'tripal_chado'),
+    'type' => MENU_CALLBACK,
+  );
+
   return $items;
 }
 
@@ -721,6 +752,10 @@ function tripal_chado_permission() {
  */
 function tripal_chado_theme($existing, $type, $theme, $path) {
   $themes = array(
+    // Themed Forms
+    'tripal_chado_feature_seq_extract_form' => array(
+      'render element' => 'form',
+    ),
 
     'tripal_chado_date_combo' => array(
       'render element' => 'element',
@@ -901,4 +936,122 @@ function tripal_chado_form_field_ui_field_edit_form_alter(&$form, &$form_state,
   }
 
   // TODO: don't the the maximum length be larger than the field size.
+}
+
+
+/**
+ * Uses the value provided in the $id argument to find all features that match
+ * that ID by name, featurename or synonym.  If it matches uniquenly to a single
+ * feature it will redirect to that feature page, otherwise, a list of matching
+ * features is shown.
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_feature_match_features_page($id) {
+
+  // first check to see if the URL (e.g. /feature/$id) is already
+  // assigned to a node. If so, then just go there.  Otherwise,
+  // try to find the feature.
+  $sql = "
+    SELECT source
+    FROM {url_alias}
+    WHERE alias = :alias
+  ";
+  $match = db_query($sql, array(':alias' => "feature/$id"))->fetchObject();
+  if ($match) {
+    drupal_goto($match->source);
+    return;
+  }
+  $sql = "
+    SELECT
+      F.name, F.uniquename, F.feature_id,
+      O.genus, O.species, O.organism_id,
+      CVT.cvterm_id, CVT.name as type_name,
+      array_agg(S.name) as synonyms
+    FROM {feature} F
+      INNER JOIN {organism} O on F.organism_id = O.organism_id
+      INNER JOIN {cvterm} CVT on CVT.cvterm_id = F.type_id
+      LEFT JOIN {feature_synonym} FS on FS.feature_id = F.feature_id
+      LEFT JOIN {synonym} S on S.synonym_id = FS.synonym_id
+    WHERE
+      F.uniquename = :uname or
+      F.name = :fname or
+      S.name = :sname
+    GROUP BY F.name, F.uniquename, F.feature_id, O.genus, O.species,
+      O.organism_id, CVT.cvterm_id, CVT.name
+  ";
+
+  $args = array(':uname' => $id, ':fname' => $id, ':sname' => $id);
+  $results = chado_query($sql, $args);
+
+  $num_matches = $results->rowCount();
+
+  // If there are no matches then just return a friendly message.
+  if ($num_matches == 0) {
+    drupal_set_message("No features matched the given name '$id'", 'warning');
+    return "No matches found";
+  }
+  // if we have more than one match then generate the table, otherwise, redirect
+  // to the matched feature
+  elseif ($num_matches == 1) {
+    $curr_match = $results->fetchObject();
+    $entity_id = chado_get_record_entity_by_table('feature', $curr_match->feature_id);
+    if ($entity_id) {
+      drupal_goto("bio_data/" . $entity_id);
+      return;
+    }
+    // If we are here it's because we couldn't find the entity. Check if a node
+    // exists (Tv2 backwards compatibility).
+    if (module_exists(tripal_feature)) {
+      $nid = chado_get_nid_from_id('feature', $curr_match->feature_id);
+      drupal_goto("node/" . $nid);
+      return;
+    }
+    // If we are here it's because we couldn't find an entity_id or an nid
+    drupal_set_message("No published features matched the given name '$id'", 'warning');
+    return "No matches found";
+
+  }
+  elseif ($num_matches > 1) {
+    // iterate through the matches and build the table for showing matches
+    $header = array('Uniquename', 'Name', 'Type', 'Species', 'Synonyms');
+    $rows = array();
+    $curr_match;
+    while ($match = $results->fetchObject()) {
+      $curr_match = $match;
+      $synonyms = $match->synonyms;
+      $synonyms = preg_replace('/[\"\{\}]/', '', $synonyms);
+
+      // Build the link to this page.
+      $entity_id = chado_get_record_entity_by_table('feature', $curr_match->feature_id);
+      $link = '';
+      if ($entity_id) {
+        $link = "bio_data/" . $entity_id;
+      }
+      // If we didn't find an entity ID we need to check nodes for
+      // backwards compatibility with Tv2.
+      if (!$entity_id and module_exists(tripal_feature)) {
+        $nid = chado_get_nid_from_id('feature', $curr_match->feature_id);
+        $link = "node/" . $nid;
+      }
+      if (!$link) {
+        continue;
+      }
+
+      $rows[] = array(
+        $match->uniquename,
+        l($match->name, $link),
+        $match->type_name,
+        '<i>' . $match->genus . ' ' . $match->species . '</i>',
+        $synonyms,
+      );
+      $num_matches++;
+    }
+    $table_attrs = array('class' => 'tripal-data-table');
+    $output = "<p>The following features match the name '$id'.</p>";
+    $output .= theme_table($header, $rows, $table_attrs, $caption);
+    return $output;
+  }
+
+
 }