Przeglądaj źródła

Fixed merge conflict

Stephen Ficklin 8 lat temu
rodzic
commit
1308771d3e

+ 41 - 11
tripal/api/tripal.entities.api.inc

@@ -325,17 +325,6 @@ function tripal_create_bundle($args, &$error = '') {
       $function = $module . '_bundle_postcreate';
       $function($bundle);
     }
-
-    // Finally set admin perimssions for the content type:
-//     $roles = user_roles();
-//     $admin_rid = variable_get('user_admin_role');
-//     $perms = user_role_permissions(array($admin_rid));
-//     dpm($perms);
-//     foreach ($perms[$admin_rid] as $perm => $value) {
-//       $perms[$admin_rid][$perm] = TRUE;
-//     }
-//     user_role_change_permissions($admin_rid, $perms[$admin_rid]);
-
   }
   catch (Exception $e) {
     $transaction->rollback();
@@ -348,6 +337,47 @@ function tripal_create_bundle($args, &$error = '') {
   return $bundle;
 }
 
+/*
+ * Checks access permissions for a given entity.
+ *
+ * This function is set for TripalEntity access checking in the
+ * tripal_entity_info() under the 'access callback' element.
+ *
+ *
+ * @param $entity
+ *   The entity to check access for.
+
+function tripal_entity_permissions($entity) {
+
+  if ($entity) {
+    $bundle_name = $entity->bundle;
+  }
+  else {
+    return FALSE;
+  }
+
+  // Get the bundle object.
+  $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
+
+  // Identify the administrative user roles.
+  $admin_role = user_role_load_by_name('administrator');
+  $roles = array($admin_role->rid => $admin_role->name);
+  // Define the permissions.
+  $permission_for_role = array(
+    'create ' . $bundle->label => TRUE,
+    'view ' . $bundle->label => TRUE,
+    'edit ' . $bundle->label => TRUE,
+    'delete ' . $bundle->label => TRUE,
+  );
+  // Assign the permissions
+  foreach($roles as $role => $value){
+    user_role_grant_permissions($role, $permission_for_role);
+    watchdog('debug', '<pre>tripal_entity_permissions  $role: '. print_r($role, TRUE) .'</pre>');
+  }
+
+  return TRUE;
+}
+ */
 /**
  * Retrieves a list of the content types.
  *

+ 34 - 1
tripal/includes/TripalBundleUIController.inc

@@ -942,6 +942,7 @@ function tripal_admin_add_type_form_submit($form, &$form_state) {
       }
       else {
         drupal_set_message('New data type created.');
+        tripal_admin_access($bundle);
         $form_state['redirect'] = "admin/structure/bio_data";
       }
 
@@ -953,4 +954,36 @@ function tripal_admin_add_type_form_submit($form, &$form_state) {
       drupal_set_message("The term '$accession' already exists as a content type.", 'warning');
     }
   }
-}
+}
+
+/**
+ * Checks access permissions for a given entity.
+ */
+function tripal_admin_access($entity) {
+  if ($entity) {
+    $bundle_name = $entity->name;
+  }
+  else {
+    return FALSE;
+  }
+
+  // Get the bundle object.
+  $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
+
+  // Identify the administrative user roles.
+  $admin_role = user_role_load_by_name('administrator');
+  $roles = array($admin_role->rid => $admin_role->name);
+  // Define the permissions.
+  $permission_for_role = array(
+    'create ' . $bundle->name => TRUE,
+    'view ' . $bundle->name => TRUE,
+    'edit ' . $bundle->name => TRUE,
+    'delete ' . $bundle->name => TRUE,
+  );
+
+  // Assign the permissions
+  foreach($roles as $role => $value){
+    user_role_change_permissions($role, $permission_for_role);
+  }
+  return TRUE;
+}

+ 12 - 1
tripal/theme/css/tripal.css

@@ -66,4 +66,15 @@ div.messages.tripal-site-admin-only{
   float: left;
 }
 .tripal-dl dd {
-}
+}
+
+
+ /******************************************************************************
+  * Spinner for paginated elements
+  *****************************************************************************/
+ #spinner {
+   position: absolute;
+   display: none;
+   left: 24%;
+   bottom: 7%;
+ }

+ 20 - 2
tripal/theme/js/tripal.js

@@ -1,7 +1,7 @@
 // Using the closure to map jQuery to $. 
 (function ($) {
   // Store our function as a property of Drupal.behaviors.
-  Drupal.behaviors.myModuleSecureLink = {
+  Drupal.behaviors.tripal = {
     attach: function (context, settings) {
 
       $(".tripal-entity-unattached .field-items").replaceWith('<div class="field-items">Loading... <img src="' + tripal_path + '/theme/images/ajax-loader.gif"></div>');
@@ -20,4 +20,22 @@
       });
     }
   }
-})(jQuery);
+
+})(jQuery);
+
+function tripal_navigate_field_pager(id, page) {
+    jQuery(document).ajaxStart(function () {
+        jQuery('#spinner').show();
+    }).ajaxComplete(function () {
+        jQuery('#spinner').hide();
+    });
+
+    jQuery.ajax({
+    type: "GET",
+    url: Drupal.settings["basePath"] + "bio_data/ajax/field_attach/" + id,
+    data: { 'page' : page },
+    success: function(response) {
+      jQuery("#" + id + ' .field-items').replaceWith(response['content']);
+    }
+  });
+}

+ 14 - 1
tripal/tripal.install

@@ -483,7 +483,7 @@ function tripal_tripal_vocab_schema() {
       'vocabulary' => array(
         'description' => 'The short name for the vocabulary (e.g. SO, PATO, etc.).',
         'type' => 'varchar',
-        'length' => 10,
+        'length' => 128,
         'not null' => TRUE,
       ),
       'created' => array(
@@ -701,3 +701,16 @@ function tripal_tripal_bundle_variables_schema() {
 
   return $schema;
 }
+
+/**
+ * Change tripal_vocab.vocabulary to varchar(128)
+ */
+function tripal_update_7300() {
+  $spec = array(
+    'description' => 'The short name for the vocabulary (e.g. SO, PATO, etc.).',
+    'type' => 'varchar',
+    'length' => 128,
+    'not null' => TRUE
+  );
+  db_change_field('tripal_vocab', 'vocabulary', 'vocabulary',$spec);
+}

+ 205 - 0
tripal_chado/api/modules/tripal_chado.cv.api.inc

@@ -352,6 +352,7 @@ function tripal_update_cvtermpath($cv_id, $job_id = NULL) {
   $previous = chado_set_active('chado');
   try {
     $sql = "SELECT * FROM fill_cvtermpath(:name)";
+
     db_query($sql, array(':name' => $cv->name));
     chado_set_active($previous);
   }
@@ -364,6 +365,210 @@ function tripal_update_cvtermpath($cv_id, $job_id = NULL) {
   return TRUE;
 }
 
+/**
+ *
+ * @param unknown $cv_id
+ * @param string $job_id
+ */
+function tripal_update_cvtermpath_bak($cv_id, $job_id = NULL){
+  chado_set_active('chado');
+  $result = db_query('
+    SELECT DISTINCT t.*
+    FROM cvterm t
+      LEFT JOIN cvterm_relationship r ON (t.cvterm_id = r.subject_id)
+      INNER JOIN cvterm_relationship r2 ON (t.cvterm_id = r2.object_id)
+    WHERE t.cv_id = :cvid AND r.subject_id is null',
+    array(':cvid' => $cv_id)
+  );
+
+  $record = $result->fetchObject();
+  tripal_update_cvtermpath_root_loop($record->cvterm_id, $record->cv_id);
+}
+
+/**
+ *
+ * @param unknown $rootid
+ * @param unknown $cvid
+ */
+function tripal_update_cvtermpath_root_loop($rootid, $cvid){
+  chado_set_active('chado');
+  $ttype = db_select('cvterm', 'cv')
+          ->fields('cv', array('cvterm_id'));
+  $db_or = db_or();
+  $db_or->condition('cv.name', "isa", '=' );
+  $db_or->condition('cv.name', "is_a", '=' );
+  $ttype->condition($db_or);
+  $result = $ttype->execute()->fetchObject();
+
+  tripal_update_cvtermpath_loop($rootid, $rootid, $cvid, $result->cvterm_id, 0);
+
+  $cterm = db_query(
+    'SELECT *
+     FROM cvterm_relationship
+     WHERE object_id = :rootid
+    ',
+    array(':rootid' => $rootid)
+  );
+
+  while($cterm_result = $cterm->fetchAssoc()) {
+    tripal_update_cvtermpath_root_loop($cterm_result['subject_id'], $cvid);
+  };
+
+}
+
+/**
+ *
+ * @param $origin
+ * @param $subject_id
+ * @param $cv_id
+ * @param $type_id
+ * @param $depth
+ * @return multitype:
+ */
+function tripal_update_cvtermpath_loop($origin, $child_id, $cv_id, $type_id, $depth){
+  chado_set_active('chado');
+  $count =  db_query(
+    'SELECT *
+     FROM cvtermpath
+     WHERE cv_id = :cvid 
+      AND object_id = :origin
+      AND subject_id = :child_id
+      AND pathdistance = :depth
+    ',
+    array(':cvid' => $cv_id, ':origin' => $origin, ':child_id' => $child_id, ':depth' => $depth)
+  );
+  $count_total = $count->rowCount();
+
+  //Loop check
+  chado_set_active('chado');
+  $loop = db_query(
+    'SELECT *
+     FROM cvtermpath
+     WHERE cv_id = :cvid 
+      AND object_id = :origin
+      AND subject_id = :child_id 
+      AND type_id = :type_id
+    ',
+    array(':cvid' => $cv_id, ':origin' => $origin, ':child_id' => $child_id, ':type_id' => $type_id,)
+  );
+  $loop_check = $loop->rowCount();
+
+  //watchdog('debug', '<pre>tripal_ds_preprocess_TripalEntity $rows ' . print_r($rows, TRUE) . '</pre>');
+  /*if(!empty($rows)){
+    foreach($rows as $row){
+      tripal_update_cvtermpath_loop_check($origin, $child_id, $cv_id, $type_id, $depth, $row->cvtermpath_id, 0);
+    }
+  }
+  else {*/
+    //If no loop proceed.
+  try{
+    if($count_total == 0) {
+      chado_set_active('chado');
+
+      $query = db_insert('cvtermpath')
+        ->fields(array(
+          'object_id' => $origin,
+          'subject_id' => $child_id,
+          'cv_id' => $cv_id,
+          'type_id' => $type_id,
+          'pathdistance' => $depth,
+        ));
+      $rows = $query->execute();
+    }
+    if ($loop_check == 0) {
+      chado_set_active('chado');
+
+      $query = db_select('cvterm_relationship', 'cvtr')
+        ->fields('cvtr')
+        ->condition('cvtr.object_id', $child_id, '=')
+        ->execute();
+      $cterm = $query->fetchAll();
+
+      foreach ($cterm as $item) {
+        //watchdog('debug', '<pre>tripal_ds_preprocess_TripalEntity $item ' . print_r($item, TRUE) . '</pre>');
+        tripal_update_cvtermpath_loop($origin, $item->subject_id, $cv_id, $item->type_id, $depth + 1);
+      };
+      //}
+    }
+  }
+  catch(Exception $e){
+    watchdog_exception('tripal_ds', $e);
+    return FALSE;
+  }
+
+  return 1;
+
+}
+
+/**
+ *
+ * @param $origin
+ * @param $subject_id
+ * @param $cv_id
+ * @param $type_id
+ * @param $depth
+ * @return multitype:
+
+function tripal_update_cvtermpath_loop_check($origin, $child_id, $cv_id, $type_id, $depth, $cvtermpath_id, $loop_count, $loop_check, $object_id){
+  //Store the
+
+  //Check if the passed parameters match any of the items in the loop_check array.
+  if(!empty($loop_check)){
+    foreach($loop_check as $item){
+        if ($item['type_id'] = $type_id){
+          if($item['subject_id'] = $child_id){
+            if($item['object_id'] = $object_id){
+              //Loop found, roll back all rows until $cvtermpath_id-1 (last correct entry)
+              // and step into the next loop
+            }
+          }
+        }
+    }
+  }
+  $loop_count + 1;
+
+  chado_set_active('chado');
+  $count =  db_query(
+    'SELECT *
+     FROM cvtermpath
+     WHERE cv_id = :cvid AND object_id = :origin
+       AND subject_id = :child_id
+       AND pathdistance = :depth
+    ',
+    array(':cvid' => $cv_id, ':origin' => $origin, ':child_id' => $child_id, ':depth' => $depth)
+  );
+  $count_total = $count->rowCount();
+
+  if ($count_total == 0) {
+    chado_set_active('chado');
+    $query = db_insert('cvtermpath')
+      ->fields(array(
+        'object_id' => $origin,
+        'subject_id' => $child_id,
+        'cv_id' => $cv_id,
+        'type_id' => $type_id,
+        'pathdistance' => $depth,
+      ));
+    $rows = $query->execute();
+    $cterm = array();
+    $query = db_select('cvterm_relationship', 'cvtr')
+      ->fields('cvtr')
+      ->condition('cvtr.object_id', $child_id, '=' )
+      ->execute();
+    $cterm = $query->fetchAll();
+
+    foreach ($cterm as $item) {
+      $loop_check[$loop_count]= $item;
+      tripal_update_cvtermpath_loop_check($origin, $item->subject_id, $cv_id, $item->type_id, $depth + 1, $loop_count, $loop_check, $item->object_id);
+    };
+  }
+
+
+  return 1;
+
+}
+ */
+
 /**
  * Adds a controlled vocabular to the CV table of Chado.
  *

+ 39 - 0
tripal_chado/api/tripal_chado.api.inc

@@ -1,5 +1,44 @@
 <?php
 
+/**
+ * Retrieves an entity that matches the given table and record id.
+ *
+ * @param $table
+ *   The name of the Chado table.
+ * @param $record_id
+ *   The record's primary key in the table specified by $table.
+ *
+ * @return
+ *   A chado_entity object.
+ */
+function tripal_load_chado_entity($table, $record_id) {
+   $entity_id = db_select('chado_entity', 'ce')
+     ->fields('ce', array('entity_id'))
+     ->condition('ce.record_id', $record_id)
+     ->condition('ce.data_table', $table)
+     ->execute()
+     ->fetchField();
+   if ($entity_id) {
+     $entity = entity_load('TripalEntity', array($entity_id));
+     return reset($entity);
+   }
+   return NULL;
+}
+
+/**
+ * Retrieves the entity ID using a record ID.
+ *
+ * @param unknown $data_table
+ * @param unknown $record_id
+ */
+function tripal_get_chado_entity_id($data_table, $record_id) {
+   return db_select('chado_entity', 'ce')
+     ->fields('ce', array('entity_id'))
+     ->condition('data_table', $data_table)
+     ->condition('record_id', $record_id)
+     ->execute()
+     ->fetchField();
+}
 
 /**
  * Publishes content in Chado as a new TripalEntity entity.

+ 21 - 3
tripal_chado/includes/TripalFields/sbo__relationship/sbo__relationship_formatter.inc

@@ -53,7 +53,6 @@ class sbo__relationship_formatter extends ChadoFieldFormatter {
   public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
     // Get the settings
     $settings = $display['settings'];
-
     $rows = array();
     $headers = array($settings['title']);
 
@@ -92,9 +91,27 @@ class sbo__relationship_formatter extends ChadoFieldFormatter {
         }
       }
 
-      $rows[] = array($phrase);
+      $rows[][] = array('data' => $phrase, 'class' => array('tripal-entity-unattached field-items'));
     }
 
+    //$pager = $this->generate_pager(count($rows), $per_page);
+
+    $per_page = 10;
+    // Initialize the pager
+    $current_page = pager_default_initialize(count($rows), $per_page);
+    // Split your list into page sized chunks
+    $chunks = array_chunk($rows, $per_page, TRUE);
+    //format pager
+    $pager = theme('pager', array('quantity', count($rows)));
+
+
+    global $base_path;
+    $tmp_base_path = preg_replace('/\//', '\/', $base_path);
+    $field_id = 'tripal-entity-' . $entity->id . '--' . $this->field['field_name'];
+    $pager = preg_replace('/href="' . $tmp_base_path . 'bio_data\/ajax\/field_attach\/' . $field_id . '\?page=(.+?)"/', 'href="javascript:void(0)" onclick="tripal_navigate_field_pager(\'' . $field_id . '\', $1)"', $pager);
+    $pager = preg_replace('/href="' . $tmp_base_path . 'bio_data\/ajax\/field_attach\/' . $field_id . '"/', 'href="javascript:void(0)" onclick="tripal_navigate_field_pager(\'' . $field_id . '\', 0)"', $pager);
+
+    //$pager = preg_replace("/href=\"" . $tmp_base_path . "gensas\/load_job_view_panel\/" . $job_id . "\/\d\"/", 'href="javascript:void(0)" onclick="gensas.show_job_view_panel(\'' . $job_id . '\', \'' . $job->getName() . '\')"', $pager);
     // the $table array contains the headers and rows array as well as other
     // options for controlling the display of the table.  Additional
     // documentation can be found here:
@@ -102,7 +119,7 @@ class sbo__relationship_formatter extends ChadoFieldFormatter {
 
     $table = array(
       'header' => $headers,
-      'rows' => $rows,
+      'rows' => $chunks[$current_page],
       'attributes' => array(
         'id' => 'sbo--relationship-table',
       ),
@@ -118,6 +135,7 @@ class sbo__relationship_formatter extends ChadoFieldFormatter {
       $element[0] = array(
         '#type' => 'markup',
         '#markup' => theme_table($table),
+        '#suffix' => '<img src=\'/sites/all/modules/tripal-7.x-3.x/tripal/theme/images/ajax-loader.gif\' id=\'spinner\'/>' . $pager,
       );
     }
   }

+ 3 - 2
tripal_chado/includes/loaders/tripal_chado.obo_loader.inc

@@ -510,7 +510,8 @@ function tripal_chado_load_update_cvtermpath($newcvs, $jobid) {
  */
 function tripal_chado_load_obo_v1_2($file, $jobid = NULL, &$newcvs) {
 
-  #$transaction = db_transaction();
+  //$transaction = db_transaction();
+
   print "\nNOTE: Loading of this OBO file is performed using a database transaction. \n" .
       "If the load fails or is terminated prematurely then the entire set of \n" .
       "insertions/updates is rolled back and will not be found in the database\n\n";
@@ -570,7 +571,7 @@ function tripal_chado_load_obo_v1_2($file, $jobid = NULL, &$newcvs) {
     }
   }
   catch (Exception $e) {
-    $transaction->rollback();
+   //$transaction->rollback();
     print "\n"; // make sure we start errors on new line
     print "FAILED. Rolling back database changes...\n";
     watchdog_exception('T_obo_loader', $e);

+ 1684 - 0
tripal_chado/includes/tripal_chado.fields.inc.orig

@@ -0,0 +1,1684 @@
+<?php
+
+/**
+ * Implements hook_field_create_info().
+ *
+ * This is a Tripal defined hook that supports integration with the
+ * TripalEntity field.
+ */
+function tripal_chado_bundle_create_fields($entity_type, $bundle, $chado_bundle) {
+
+  // Get the details about the mapping of this bundle to the Chado table:
+  $details = array(
+    'chado_cvterm_id' => $chado_bundle['type_id'],
+    'chado_table' => $chado_bundle['data_table'],
+    'chado_type_table' => $chado_bundle['type_linker_table'],
+    'chado_type_column' => $chado_bundle['type_column'],
+  );
+
+  $info = array();
+
+  // Create the fields for each column in the table.
+  tripal_chado_bundle_create_fields_base($info, $details, $entity_type, $bundle);
+
+  // Create custom fields.
+  tripal_chado_bundle_create_fields_custom($info, $details, $entity_type, $bundle);
+
+  // Create fields for linking tables.
+  tripal_chado_bundle_create_fields_linker($info, $details, $entity_type, $bundle);
+
+  foreach ($info as $field_name => $details) {
+    $field_type = $details['type'];
+
+    // If the field already exists then skip it.
+    $field = field_info_field($details['field_name']);
+    if ($field) {
+      continue;
+    }
+
+    // Create the field.
+    $field = field_create_field($details);
+    if (!$field) {
+      tripal_set_message(t("Could not create new field: %field.",
+          array('%field' =>  $details['field_name'])), TRIPAL_ERROR);
+    }
+  }
+}
+/**
+ *
+ * @param unknown $details
+ */
+function tripal_chado_bundle_create_fields_base(&$info, $details, $entity_type, $bundle) {
+
+  $table_name = $details['chado_table'];
+  $type_table = $details['chado_type_table'];
+  $type_field = $details['chado_type_column'];
+  $cvterm_id  = $details['chado_cvterm_id'];
+
+  // Iterate through the columns of the table and see if fields have been
+  // created for each one. If not, then create them.
+  $schema = chado_get_schema($table_name);
+  if (!$schema) {
+    return;
+  }
+
+  $pkey = $schema['primary key'][0];
+
+
+  // Get the list of columns for this table and create a new field for each one.
+  $columns = $schema['fields'];
+  foreach ($columns as $column_name => $details) {
+    // Don't create base fields for the primary key and the type_id field.
+    if ($column_name == $pkey or $column_name == $type_field) {
+      continue;
+    }
+    $cvterm = tripal_get_chado_semweb_term($table_name, $column_name, array('return_object' => TRUE));
+    if (!$cvterm) {
+      tripal_report_error('tripal', TRIPAL_ERROR,
+        'Cannot create field for "%table_name.%column_name". Missing an appropriate vocabulary term',
+         array('%table_name' => $table_name, '%column_name' => $column_name));
+      drupal_set_message(t('Cannot create field for "%table_name.%column_name". Missing an appropriate vocabulary term',
+        array('%table_name' => $table_name, '%column_name' => $column_name)), 'error');
+      continue;
+    }
+    $field_name = strtolower($cvterm->dbxref_id->db_id->name . '__' . preg_replace('/ /', '_', $cvterm->name));
+
+    // Skip the primary key field.
+    if ($column_name == $schema['primary key'][0]) {
+      continue;
+    }
+
+    // Skip the type field.
+    if ($table_name == $type_table and $column_name == $type_field) {
+      continue;
+    }
+
+    // Set some defaults for the field.
+    $base_info = array(
+      'field_name' => $field_name,
+      'type' => '',
+      'cardinality' => 1,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+
+    // Alter the field info array depending on the column details.
+    switch($details['type']) {
+      case 'char':
+        $base_info['type'] = 'text';
+        $base_info['settings']['max_length'] = $details['length'];
+        break;
+      case 'varchar':
+        $base_info['type'] = 'text';
+        $base_info['settings']['max_length'] = $details['length'];
+        break;
+      case 'text':
+        $base_info['type'] = 'text';
+        $base_info['settings']['max_length'] = 17179869184;
+        $base_info['settings']['text_processing'] = 1;
+        break;
+      case 'blob':
+        // not sure how to support a blob field.
+        continue;
+        break;
+      case 'int':
+        $base_info['type'] = 'number_integer';
+        break;
+      case 'float':
+        $base_info['type'] = 'number_float';
+        $base_info['settings']['precision'] = 10;
+        $base_info['settings']['scale'] = 2;
+        $base_info['settings']['decimal_separator'] = '.';
+        break;
+      case 'numeric':
+        $base_info['type'] = 'number_decimal';
+        break;
+      case 'serial':
+        // Serial fields are most likely not needed as a field.
+        break;
+      case 'boolean':
+        $base_info['type'] = 'list_boolean';
+        $base_info['settings']['allowed_values'] = array(0 => "No", 1 => "Yes");
+        break;
+      case 'datetime':
+        // Use the Drupal Date and Date API to create the field/widget
+        $base_info['type'] = 'datetime';
+        break;
+    }
+
+    // Set some default semantic web information
+    if ($column_name == 'uniquename') {
+      $base_info['settings']['text_processing'] = 0;
+    }
+    //
+    // PUB TABLE
+    //
+    elseif ($table_name == 'pub' and $column_name == 'uniquename') {
+      $base_info['type'] = 'text';
+      $base_info['settings']['text_processing'] = 0;
+    }
+
+    //
+    // ANALYSIS TABLE
+    //
+    elseif ($table_name == 'analysis' and $column_name == 'sourceuri') {
+      $base_info['type'] = 'text';
+      $base_info['settings']['text_processing'] = 0;
+    }
+
+    $info[$field_name] = $base_info;
+  }
+}
+
+/**
+ *
+ * @param unknown $details
+ */
+function tripal_chado_bundle_create_fields_custom(&$info, $details, $entity_type, $bundle) {
+  $table_name = $details['chado_table'];
+  $type_table = $details['chado_type_table'];
+  $type_field = $details['chado_type_column'];
+  $cvterm_id  = $details['chado_cvterm_id'];
+
+  $schema = chado_get_schema($table_name);
+
+  // BASE ORGANISM_ID
+  if ($table_name != 'organism' and
+      array_key_exists('organism_id', $schema['fields'])) {
+    $field_name = 'obi__organism';
+    $field_type = 'obi__organism';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => 1,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // BASE DBXREF
+  if (array_key_exists('dbxref_id', $schema['fields'])) {
+    $field_name = 'data__accession';
+    $field_type = 'data__accession';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => 1,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // FEATURE MD5CHECKSUM
+  if ($table_name == 'feature') {
+    $field_name = 'data__sequence_checksum';
+    $field_type = 'data__sequence_checksum';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => 1,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // FEATURE RESIDUES
+  if ($table_name == 'feature') {
+    $field_name = 'data__sequence';
+    $field_type = 'data__sequence';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => 1,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // FEATURE SEQLEN
+  if ($table_name == 'feature') {
+    $field_name = 'data__sequence_length';
+    $field_type = 'data__sequence_length';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => 1,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // GENE TRANSCRIPTS
+  $rel_table = $table_name . '_relationship';
+  if (chado_table_exists($rel_table) and $bundle->label == 'gene') {
+    $field_name = 'so__transcript';
+    $field_type = 'so__transcript';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // ORGANISM TYPE_ID
+//   if ($table_name == 'organism' and array_key_exists('type_id', $schema['fields'])) {
+//     $field_name = 'taxarank__infraspecific_taxon';
+//     $field_type = 'taxarank__infraspecific_taxon';
+//     $info[$field_name] = array(
+//       'field_name' => $field_name,
+//       'type' => $field_type,
+//       'cardinality' => 1,
+//       'locked' => TRUE,
+//       'storage' => array(
+//         'type' => 'field_chado_storage',
+//       ),
+//       'settings' => array(
+//       ),
+//     );
+//   }
+}
+
+/**
+ *
+ * @param unknown $details
+ */
+function tripal_chado_bundle_create_fields_linker(&$info, $details, $entity_type, $bundle) {
+
+  $table_name = $details['chado_table'];
+  $type_table = $details['chado_type_table'];
+  $type_field = $details['chado_type_column'];
+  $cvterm_id  = $details['chado_cvterm_id'];
+
+  // CONTACTS
+  $contact_table = $table_name . '_contact';
+  if (chado_table_exists($contact_table)) {
+    $schema = chado_get_schema($contact_table);
+    $pkey = $schema['primary key'][0];
+    $field_name = $table_name . '_contact';
+    $field_type = 'chado_linker__contact';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => 1,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // DBXREF
+  $dbxref_table = $table_name . '_dbxref';
+  if (chado_table_exists($dbxref_table)) {
+    $field_name = 'sbo__database_cross_reference';
+    $field_type = 'sbo__database_cross_reference';
+    $info[$field_name] = array(
+      'field_name' =>  $field_name,
+      'type' => $field_type,
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // EXPRESSION
+  $expression_table = $table_name . '_expression';
+  if (chado_table_exists($expression_table)) {
+    $field_name = 'go__gene_expression';
+    $field_type = 'go__gene_expression';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // FEATURELOC
+  if ($table_name == 'feature') {
+    $field_name = 'data__sequence_coordinates';
+    $field_type = 'data__sequence_coordinates';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // FEATUREPOS
+  if ($table_name == 'feature') {
+    $field_name = 'ogi__location_on_map';
+    $field_type = 'ogi__location_on_map';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // GENOTYPE
+  $genotype_table = $table_name . '_genotype';
+  if (chado_table_exists($genotype_table)) {
+    $field_name = 'so__genotype';
+    $field_type = 'so__genotype';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // PHENOTYPE
+  $phenotype_table = $table_name . '_phenotype';
+  if (chado_table_exists($phenotype_table)) {
+    $field_name = 'sbo__phenotype';
+    $field_type = 'sbo__phenotype';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // PROPERTIES
+  $prop_table = $table_name . 'prop';
+  if (chado_table_exists($prop_table)) {
+    // Get the list of existing property types for this table.
+    $sql = 'SELECT DISTINCT type_id FROM {' . $prop_table . '}';
+    $props = chado_query($sql);
+    while ($prop = $props->fetchObject()) {
+      $term = chado_generate_var('cvterm', array('cvterm_id' => $prop->type_id));
+      $field_name = strtolower(preg_replace('/[^\w]/','_', $term->dbxref_id->db_id->name . '__' . $term->name));
+      $field_type = 'chado_linker__prop';
+      $info[$field_name] = array(
+        'field_name' => $field_name,
+        'type' => $field_type,
+        'cardinality' => 1,
+        'locked' => FALSE,
+        'storage' => array(
+          'type' => 'field_chado_storage',
+        ),
+      );
+    }
+  }
+
+  // PUBLICATIONS
+  $pub_table = $table_name . '_pub';
+  if (chado_table_exists($pub_table)) {
+    $field_name = 'schema__publication';
+    $field_type = 'schema__publication';
+    $info[$field_name] =  array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // RELATIONSHIPS
+  // If the linker table does not exists then we don't want to add attach.
+  $rel_table = $table_name . '_relationship';
+  if (chado_table_exists($rel_table)) {
+    $field_name = 'sbo__relationship';
+    $field_type = 'sbo__relationship';
+    $info[$field_name] =  array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
+  // SYNONYMS
+  $syn_table = $table_name . '_synonym';
+  if (chado_table_exists($syn_table)) {
+    $field_name = 'schema__alternate_name';
+    $field_type = 'schema__alternate_name';
+    $info[$field_name] =  array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'locked' => TRUE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+      'settings' => array(
+      ),
+    );
+  }
+}
+
+/**
+ * Impelments hook_create_tripalfield_instance().
+ *
+ * This is a Tripal defined hook that supports integration with the
+ * TripalEntity field.
+ */
+function tripal_chado_bundle_create_instances($entity_type, $bundle, $chado_bundle) {
+
+  $details = array(
+    'chado_cvterm_id' => $chado_bundle['type_id'],
+    'chado_table' => $chado_bundle['data_table'],
+    'chado_type_table' => $chado_bundle['type_linker_table'],
+    'chado_type_column' => $chado_bundle['type_column'],
+  );
+
+  tripal_chado_bundle_create_instances_base($info, $entity_type, $bundle, $details);
+  tripal_chado_bundle_create_instances_custom($info, $entity_type, $bundle, $details);
+  tripal_chado_bundle_create_instances_linker($info, $entity_type, $bundle, $details);
+
+  foreach ($info as $field_name => $details) {
+    // If the field is already attached to this bundle then skip it.
+    $field = field_info_field($details['field_name']);
+    if ($field and array_key_exists('bundles', $field) and
+        array_key_exists('TripalEntity', $field['bundles']) and
+        in_array($bundle->name, $field['bundles']['TripalEntity'])) {
+      continue;
+    }
+    // Create the field instance.
+    $instance = field_create_instance($details);
+  }
+
+}
+/**
+ * Helper function for the hook_create_tripalfield_instance().
+ *
+ * Add the field instances that corresond to the columns of the base table.
+ *
+ * @param $entity_type
+ * @param $bundle
+ * @param $details
+ */
+function tripal_chado_bundle_create_instances_base(&$info, $entity_type, $bundle, $details) {
+  $fields = array();
+
+  // Get Chado information
+  $table_name = $details['chado_table'];
+  $type_table = $details['chado_type_table'];
+  $type_field = $details['chado_type_column'];
+  $cvterm_id  = $details['chado_cvterm_id'];
+
+  // Iterate through the columns of the table and see if fields have been
+  // created for each one. If not, then create them.
+  $schema = chado_get_schema($table_name);
+  if (!$schema) {
+    return;
+  }
+
+  $pkey = $schema['primary key'][0];
+
+  $columns = $schema['fields'];
+  foreach ($columns as $column_name => $details) {
+    // Don't create base fields for the primary key and the type_id field.
+    if ($column_name == $pkey or $column_name == $type_field) {
+      continue;
+    }
+    $cvterm = tripal_get_chado_semweb_term($table_name, $column_name, array('return_object' => TRUE));
+    if (!$cvterm) {
+      // We already provided an error when creating the base field.  So
+      // don't create another one here.
+      continue;
+    }
+
+    $field_name = strtolower($cvterm->dbxref_id->db_id->name . '__' . preg_replace('/ /', '_', $cvterm->name));
+
+    // Skip the primary key field.
+    if ($column_name == $schema['primary key'][0]) {
+      continue;
+    }
+
+    // Skip the type field.
+    if ($table_name == $type_table and $column_name == $type_field) {
+      continue;
+    }
+
+    $base_info =  array(
+      'field_name' => $field_name,
+      'entity_type' => 'TripalEntity',
+      'bundle' => $bundle->name,
+      'label' => ucwords(preg_replace('/_/', ' ', $column_name)),
+      'description' => '',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => TRUE,
+        'term_vocabulary' => $cvterm->dbxref_id->db_id->name,
+        'term_name' => $cvterm->name,
+        'term_accession' => $cvterm->dbxref_id->accession,
+        'chado_table' => $table_name,
+        'chado_column' => $column_name,
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'inline',
+          'settings' => array(),
+        ),
+      ),
+    );
+
+    // Determine if the field is required.
+    if (array_key_exists('not null', $details) and $details['not null'] === TRUE) {
+      $base_info['required'] = TRUE;
+    }
+
+    // Alter the field info array depending on the column details.
+    switch($details['type']) {
+      case 'char':
+        $base_info['widget']['type'] = 'text_textfield';
+        break;
+      case 'varchar':
+        $base_info['widget']['type'] = 'text_textfield';
+        break;
+      case 'text':
+        $base_info['widget']['type'] = 'text_textarea';
+        $base_info['widget']['settings']['format'] = filter_default_format();
+        break;
+      case 'blob':
+        // not sure how to support a blob field.
+        continue;
+        break;
+      case 'int':
+        $base_info['widget']['type'] = 'number';
+        break;
+      case 'float':
+        $base_info['widget']['type'] = 'number';
+        break;
+      case 'numeric':
+        $base_info['widget']['type'] = 'number';
+        break;
+      case 'serial':
+        // Serial fields are most likely not needed as a field.
+        break;
+      case 'boolean':
+        $base_info['widget']['type'] = 'options_onoff';
+        $base_info['required'] = FALSE;
+        break;
+      case 'datetime':
+        $base_info['widget']['type'] = 'date_select';
+        $base_info['widget']['settings']['increment'] = 1;
+        $base_info['widget']['settings']['tz_handling'] = 'none';
+        $base_info['widget']['settings']['collapsible'] = TRUE;
+
+        // TODO: Add settings so that the minutes increment by 1.
+        // And turn off the timezone, as the Chado field doesn't support it.
+        break;
+    }
+
+    // Set some default semantic web information
+    if ($column_name == 'uniquename') {
+      $base_info['label'] = 'Identifier';
+      $base_info['widget_type'] = 'text_textfield';
+    }
+    elseif ($base_info['label'] == 'Timeaccessioned') {
+      $base_info['label'] = 'Time Accessioned';
+      $base_info['description'] = 'Please enter the time that this record was first added to the database.';
+    }
+    elseif ($base_info['label'] == 'Timelastmodified') {
+      $base_info['label'] = 'Time Last Modified';
+      $base_info['description'] = 'Please enter the time that this record was last modified. The default is the current time.';
+    }
+    //
+    // ORGANISM TABLE
+    //
+    elseif ($table_name == 'organism' and $column_name == 'comment') {
+      $base_info['label'] = 'Description';
+    }
+    //
+    // PUB TABLE
+    //
+    elseif ($table_name == 'pub' and $column_name == 'uniquename') {
+      $base_info['widget_type'] = 'text_textfield';
+    }
+
+    //
+    // ANALYSIS TABLE
+    //
+    elseif ($table_name == 'analysis' and $column_name == 'program') {
+      $base_info['description'] = 'The program name (e.g. blastx, blastp, sim4, genscan. If the analysis was not derived from a software package then provide a very brief description of the pipeline, workflow or method.';
+      $base_info['label'] = 'Program, Pipeline, Workflow or Method Name.';
+    }
+    elseif ($table_name == 'analysis' and $column_name == 'sourceuri') {
+      $base_info['widget_type'] = 'text_textfield';
+      $base_info['label'] = 'Source URL';
+      $base_info['description'] = 'The URL where the original source data was derived.  Ideally, this should link to the page where more information about the source data can be found.';
+    }
+    elseif ($table_name == 'analysis' and $column_name == 'sourcename') {
+      $base_info['label'] = 'Source Name';
+      $base_info['description'] = 'The name of the source data. This could be a file name, data set or a small description for how the data was collected. For long descriptions use the larger description field.';
+    }
+    elseif ($table_name == 'analysis' and $column_name == 'sourceversion') {
+      $base_info['label'] = 'Source Version';
+      $base_info['description'] = 'If hte source data set has a version include it here.';
+    }
+    elseif ($table_name == 'analysis' and $column_name == 'algorithm') {
+      $base_info['label'] = 'Source Version';
+      $base_info['description'] = 'The name of the algorithm used to produce the dataset if different from the program.';
+    }
+    elseif ($table_name == 'analysis' and $column_name == 'programversion') {
+      $base_info['label'] = 'Program Version';
+      $base_info['description'] = 'The version of the program used to perform this analysis. (e.g. TBLASTX 2.0MP-WashU [09-Nov-2000]. Enter "n/a" if no version is available or applicable.';
+    }
+    //
+    // PROJECT TABLE
+    //
+    elseif ($table_name == 'project' and $column_name == 'description') {
+      $base_info['label'] = 'Short Description';
+    }
+    $info[$field_name] = $base_info;
+  }
+}
+
+/**
+ * Helper function for the hook_create_tripalfield_instance().
+ *
+ * Adds custom fields for base fields.  These override the settings provided
+ * in the tripal_chado_create_tripalfield_instance_base() function.
+ *
+ * @param $entity_type
+ * @param $bundle
+ * @param $details
+ */
+function tripal_chado_bundle_create_instances_custom(&$info, $entity_type, $bundle, $details) {
+  $table_name = $details['chado_table'];
+  $type_table = $details['chado_type_table'];
+  $type_field = $details['chado_type_column'];
+  $cvterm_id  = $details['chado_cvterm_id'];
+  $schema = chado_get_schema($table_name);
+
+  // BASE ORGANISM_ID
+  if ($table_name != 'organism' and array_key_exists('organism_id', $schema['fields'])) {
+    $field_name = 'obi__organism';
+    $is_required = FALSE;
+    if (array_key_exists('not null', $schema['fields']['organism_id']) and
+        $schema['fields']['organism_id']['not null']) {
+      $is_required = TRUE;
+    }
+    $info[$field_name] =  array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Organism',
+      'description' => 'Select an organism.',
+      'required' => $is_required,
+      'settings' => array(
+        'auto_attach' => TRUE,
+        'chado_table' => $table_name,
+        'chado_column' => 'organism_id',
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'obi__organism_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'inline',
+          'type' => 'obi__organism_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // BASE DBXREF
+  if (array_key_exists('dbxref_id', $schema['fields'])) {
+    $field_name = 'data__accession';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Accession',
+      'description' => 'This field specifies the unique stable accession (ID) for
+        this record. It requires that this site have a database entry.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => TRUE,
+        'chado_table' => $table_name,
+        'chado_column' => 'dbxref_id',
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'data__accession_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'inline',
+          'type' => 'data__accession_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // FEATURE MD5CHECKSUM
+  if ($table_name == 'feature') {
+    $field_name = 'data__sequence_checksum';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Sequence Checksum',
+      'description' => 'The MD5 checksum for the sequence. The checksum here
+        will always be unique for the raw unformatted sequence. To verify that the
+        sequence has not been corrupted, download the raw sequence and use an MD5 tool
+        to calculate the value. If the value calculated is identical the one shown
+        here, then the downloaded sequence is uncorrupted.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => TRUE,
+        'chado_table' => $table_name,
+        'chado_column' => 'md5checksum',
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'data__sequence_checksum_widget',
+        'settings' => array(
+          'display_label' => 1,
+          'md5_fieldname' => 'feature__md5checksum',
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'inline',
+          'type' => 'data__sequence_checksum_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // FEATURE RESIDUES
+  if ($table_name == 'feature') {
+    $field_name = 'data__sequence';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Sequence',
+      'description' => 'All available sequences for this record.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => $table_name,
+        'chado_column' => 'residues',
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'data__sequence_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'above',
+          'type' => 'data__sequence_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // FEATURE SEQLEN
+  if ($table_name == 'feature') {
+    $field_name = 'data__sequence_length';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Sequence Length',
+      'description' => 'The number of residues in the raw sequence.  This length
+        is only for the assigned raw sequence and does not represent the length of any
+        sequences derived from alignments. If this value is zero but aligned sequences
+        are present then this record has no official assigned sequence.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => TRUE,
+        'chado_table' => $table_name,
+        'chado_column' => 'seqlen',
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'data__sequence_length_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'inline',
+          'type' => 'data__sequence_length_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // GENE TRANSCRIPTS
+  $rel_table = $table_name . '_relationship';
+  if (chado_table_exists($rel_table) and $bundle->label == 'gene') {
+    $field_name = 'so__transcript';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Transcripts',
+      'description' => 'Transcripts that are part of this gene.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => $rel_table,
+        'chado_column' => '',
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'so__transcript_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'above',
+          'type' => 'so__transcript_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // ORGANISM TYPE_ID
+//   if ($table_name == 'organism' and array_key_exists('type_id', $schema['fields'])) {
+//     $field_name = 'taxarank__infraspecific_taxon';
+//     $info[$field_name] = array(
+//       'field_name' => $field_name,
+//       'entity_type' => $entity_type,
+//       'bundle' => $bundle->name,
+//       'label' => 'Infraspecific Taxon',
+//       'description' => 'The Infraspecific Taxon.',
+//       'required' => FALSE,
+//       'settings' => array(
+//         'auto_attach' => TRUE,
+//         'chado_table' => 'organism',
+//         'chado_column' => 'type_id',
+//         'base_table' => 'organism',
+//       ),
+//       'widget' => array(
+//         'type' => 'taxarank__infraspecific_taxon_widget',
+//         'settings' => array(
+//           'display_label' => 1,
+//         ),
+//       ),
+//       'display' => array(
+//         'default' => array(
+//           'label' => 'inline',
+//           'type' => 'taxarank__infraspecific_taxon_formatter',
+//           'settings' => array(),
+//         ),
+//       ),
+//     );
+//   }
+}
+
+/**
+ *
+ * @param unknown $entity_type
+ * @param unknown $bundle
+ * @param unknown $details
+ */
+function tripal_chado_bundle_create_instances_linker(&$info, $entity_type, $bundle, $details) {
+
+  $table_name = $details['chado_table'];
+  $type_table = $details['chado_type_table'];
+  $type_field = $details['chado_type_column'];
+  $cvterm_id  = $details['chado_cvterm_id'];
+
+  // CONTACTS
+  $contact_table = $table_name . '_contact';
+  if (chado_table_exists($contact_table)) {
+    $field_name = $table_name . '_contact';
+    $info[$field_name] =     $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Contact',
+      'description' => 'Associates an indviddual or organization with this record',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => $contact_table,
+        'base_table' => $table_name,
+        'chado_column' => 'contact_id',
+      ),
+      'widget' => array(
+        'type' => 'local__contact_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'above',
+          'type' => 'local__contact_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // DBXREF
+  $dbxref_table = $table_name . '_dbxref';
+  if (chado_table_exists($dbxref_table)) {
+    $field_name = 'sbo__database_cross_reference';
+    $schema = chado_get_schema($dbxref_table);
+    $pkey = $schema['primary key'][0];
+    $info[$field_name] =  array(
+      'field_name' =>  $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Database Cross Reference',
+      'description' => 'The IDs where this record may be available in other external online databases.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => $dbxref_table,
+        'chado_column' => $pkey,
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'sbo__database_cross_reference_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'inline',
+          'type' => 'sbo__database_cross_reference_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // EXPRESSION
+  $expression_table = $table_name . '_expression';
+  if (chado_table_exists($expression_table)) {
+    $field_name = 'go__gene_expression';
+    $schema = chado_get_schema($expression_table);
+    $pkey = $schema['primary key'][0];
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Gene expression',
+      'description' => 'Information about the expression of this record.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => $expression_table,
+        'chado_column' => $pkey,
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'go__gene_expression_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'above',
+          'type' => 'go__gene_expression_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // FEATURELOC
+  if ($table_name == 'feature') {
+    $field_name = 'data__sequence_coordinates';
+    $schema = chado_get_schema('featureloc');
+    $pkey = $schema['primary key'][0];
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Sequence Coordinates',
+      'description' => 'The locations on other genomic sequences where this
+        record has been aligned.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => 'featureloc',
+        'chado_column' => $pkey,
+        'base_table' => 'feature',
+      ),
+      'widget' => array(
+        'type' => 'data__sequence_coordinates_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'above',
+          'type' => 'data__sequence_coordinates_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // FEATUREPOS
+  if ($table_name == 'feature') {
+    $field_name = 'ogi__location_on_map';
+    $schema = chado_get_schema('featurepos');
+    $pkey = $schema['primary key'][0];
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Location on Map',
+      'description' => 'The positions on a genetic map.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => 'featurepos',
+        'chado_column' => $pkey,
+        'base_table' => 'feature',
+      ),
+      'widget' => array(
+        'type' => 'ogi__location_on_map_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'above',
+          'type' => 'ogi__location_on_map_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // GENOTYPE
+  $genotype_table = $table_name . '_genotype';
+  if (chado_table_exists($genotype_table)) {
+    $field_name = 'so__genotype';
+    $schema = chado_get_schema($genotype_table);
+    $pkey = $schema['primary key'][0];
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Genotype',
+      'description' => 'The genotypes associated with this record.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => $genotype_table,
+        'chado_column' => $pkey,
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'so__genotype_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'above',
+          'type' => 'so__genotype_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // PHENOTYPE
+  $phenotype_table = $table_name . '_phenotype';
+  if (chado_table_exists($phenotype_table)) {
+    $field_name = 'sbo__phenotype';
+    $schema = chado_get_schema($phenotype_table);
+    $pkey = $schema['primary key'][0];
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Phenotype',
+      'description' => 'The phenotypes associated with this record.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => $phenotype_table,
+        'chado_column' => $pkey,
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'sbo__phenotype_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'above',
+          'type' => 'sbo__phenotype_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // PROPERTIES
+  $prop_table = $table_name . 'prop';
+  if (chado_table_exists($prop_table)) {
+     // Get the list of existing property types for this table.
+     $sql = 'SELECT DISTINCT type_id FROM {' . $prop_table . '}';
+     $props = chado_query($sql);
+     $schema = chado_get_schema($prop_table);
+     $pkey = $schema['primary key'][0];
+     while ($prop = $props->fetchObject()) {
+       $term = chado_generate_var('cvterm', array('cvterm_id' => $prop->type_id));
+       $field_name = strtolower(preg_replace('/[^\w]/','_', $term->dbxref_id->db_id->name . '__' . $term->name));
+       $info[$field_name] = array(
+         'field_name' => $field_name,
+         'entity_type' => $entity_type,
+         'bundle' => $bundle->name,
+         'label' => ucwords(preg_replace('/_/', ' ', $term->name)),
+         'description' => $term->definition,
+         'required' => FALSE,
+         'settings' => array(
+           'auto_attach' => TRUE,
+           'term_vocabulary' => $term->dbxref_id->db_id->name,
+           'term_accession' => $term->dbxref_id->accession,
+           'term_name' => $term->name,
+           'base_table' => $table_name,
+           'chado_table' => $prop_table,
+           'chado_column' => $pkey,
+         ),
+         'widget' => array(
+           'type' => 'chado_linker__prop_widget',
+           'settings' => array(
+             'display_label' => 1,
+           ),
+         ),
+         'display' => array(
+           'default' => array(
+             'label' => 'inline',
+             'type' => 'chado_linker__prop_formatter',
+             'settings' => array(),
+           ),
+         ),
+       );
+     }
+   }
+
+
+  // PUBLICATIONS
+  $pub_table = $table_name . '_pub';
+  if (chado_table_exists($pub_table)) {
+    $field_name = 'schema__publication';
+    $schema = chado_get_schema($pub_table);
+    $pkey = $schema['primary key'][0];
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Publication',
+      'description' => 'This record has been referenced or is sourced from these publications.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => $pub_table,
+        'chado_column' => $pkey,
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'schema__publication_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'above',
+          'type' => 'schema__publication_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // RELATIONSHIPS
+  // If the linker table does not exists then we don't want to add attach.
+  $rel_table = $table_name . '_relationship';
+  if (chado_table_exists($rel_table)) {
+    $field_name = 'sbo__relationship';
+    $schema = chado_get_schema($rel_table);
+    $pkey = $schema['primary key'][0];
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Relationship',
+      'description' => 'Other records with relationships to this record.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => $rel_table,
+        'chado_column' => $pkey,
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'sbo__relationship_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'above',
+          'type' => 'sbo__relationship_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
+  // SYNONYMS
+  $syn_table = $table_name . '_synonym';
+  if (chado_table_exists($syn_table)) {
+    $field_name = 'schema__alternate_name';
+    $schema = chado_get_schema($syn_table);
+    $pkey = $schema['primary key'][0];
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Synonyms',
+      'description' => 'Alternate names, aliases or synonyms for this record.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => $syn_table,
+        'chado_column' => $pkey,
+        'base_table' => $table_name,
+      ),
+      'widget' => array(
+        'type' => 'schema__alternate_name_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'inline',
+          'type' => 'schema__alternate_name_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * The field_ui_field_overview_form is used for ordering and configuring the
+ * fields attached to an entity.
+ *
+ * This function removes the property adder field as that is really not meant
+ * for users to show or manage.
+ */
+function tripal_chado_form_field_ui_field_overview_form_alter(&$form, &$form_state, $form_id) {
+
+  // Remove the kvproperty_addr field as it isn't ever displayed. It's just used
+  // on the add/edit form of an entity for adding new property fields.
+  $fields_names = element_children($form['fields']);
+  foreach ($fields_names as $field_name) {
+    $field_info = field_info_field($field_name);
+    if ($field_info['type'] == 'kvproperty_adder') {
+      unset($form['fields'][$field_name]);
+    }
+    if ($field_info['type'] == 'cvterm_class_adder') {
+      unset($form['fields'][$field_name]);
+    }
+  }
+}
+
+/**
+ * Implements hook_form_field_ui_field_overview_add_new().
+ */
+function tripal_chado_form_field_ui_field_overview_add_new($new_field, $bundle) {
+  // Get the table this bundle is mapped to.
+  $term = tripal_load_term_entity(array('term_id' => $bundle->term_id));
+  $vocab = $term->vocab;
+  $params = array(
+    'vocabulary' => $vocab->vocabulary,
+    'accession' => $term->accession,
+  );
+  $mapped_table = chado_get_cvterm_mapping($params);
+  $chado_table = $mapped_table->chado_table;
+  $chado_type_table = $mapped_table->chado_table;
+  $chado_type_column = $mapped_table->chado_field;
+
+  // We allow site admins to add new chado_linker__prop fields to an entity.
+  // This function will allow us to properly add them.  But at this point we
+  // don't know the controlled vocabulary term.  We'll have to use the
+  // defaults and let the user set it using the interface.
+  if ($new_field['type'] == 'chado_linker__prop') {
+    $table_name = $chado_table . 'prop';
+
+    if (chado_table_exists($table_name)) {
+      $schema = chado_get_schema($table_name);
+      $pkey = $schema['primary key'][0];
+      $field_name = $new_field['field_name'];
+      $field_type = 'chado_linker__prop';
+
+      // First add the field.
+      field_create_field(array(
+        'field_name' => $field_name,
+        'type' => $field_type,
+        'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+        'locked' => FALSE,
+        'storage' => array(
+          'type' => 'field_chado_storage',
+        ),
+        'settings' => array(
+          'base_table' => $chado_table,
+          'chado_table' => $table_name,
+          'chado_column' => $pkey,
+        ),
+      ));
+
+      // Now add the instance
+      field_create_instance(array(
+        'field_name' => $field_name,
+        'entity_type' => 'TripalEntity',
+        'bundle' => $bundle->name,
+        'label' => $new_field['label'],
+        'description' => '',
+        'required' => FALSE,
+        'settings' => array(
+          'auto_attach' => TRUE,
+        ),
+        'widget' => array(
+          'type' => 'chado_linker__prop_widget',
+          'settings' => array(
+            'display_label' => 1,
+          ),
+        ),
+        'display' => array(
+          'default' => array(
+            'label' => 'inline',
+            'type' => 'chado_linker__prop_formatter',
+            'settings' => array(),
+          ),
+        ),
+      ));
+    }
+    else {
+      drupal_set_message('Cannot add a property field to this entity. Chado does not support properties for this data type.', 'error');
+    }
+  }
+
+  // We allow site admins to add new chado_linker__cvterm fields to an entity.
+  // This function will allow us to properly add them.  But at this point we
+  // don't know the controlled vocabulary term.  We'll have to use the
+  // defaults and let the user set it using the interface.
+
+  if ($new_field['type'] == 'chado_linker__cvterm') {
+    $table_name = $chado_table . '_cvterm';
+
+    if (chado_table_exists($table_name)) {
+      $schema = chado_get_schema($table_name);
+      $pkey = $schema['primary key'][0];
+      $field_name = $new_field['field_name'];
+      $field_type = 'chado_linker__cvterm';
+
+      // First add the field.
+      field_create_field(array(
+        'field_name' => $field_name,
+        'type' => $field_type,
+        'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+        'locked' => FALSE,
+        'storage' => array(
+          'type' => 'field_chado_storage',
+        ),
+        'settings' => array(
+          'base_table' => $chado_table,
+          'chado_table' => $table_name,
+          'chado_column' => $pkey,
+        ),
+      ));
+
+      // Now add the instance
+      field_create_instance(array(
+        'field_name' => $field_name,
+        'entity_type' => 'TripalEntity',
+        'bundle' => $bundle->name,
+        'label' => $new_field['label'],
+        'description' => '',
+        'required' => FALSE,
+        'settings' => array(
+          'auto_attach' => TRUE,
+        ),
+        'widget' => array(
+          'type' => 'chado_linker__cvterm_widget',
+          'settings' => array(
+            'display_label' => 1,
+          ),
+        ),
+        'display' => array(
+          'default' => array(
+            'label' => 'above',
+            'type' => 'chado_linker__cvterm_formatter',
+            'settings' => array(),
+          ),
+        ),
+      ));
+    }
+    else {
+      drupal_set_message('Cannot add a property field to this entity. Chado does not support annotations for this data type.', 'error');
+    }
+  }
+}
+
+
+/**
+ * Allows for altering of a field's instance setting form.
+ *
+ * This appears to be a Drupal hook but is actually a custom function created
+ * by this module. It is called by the tripal_form_alter() function of this
+ * module.
+ *
+ * Here we put additional form elements for any field, regardless if it is
+ * a tripalField or not.
+ *
+ * @param $form
+ *   The form array.  Alterations to the form can be made within this array.
+ * @param $form_state
+ *   The form state array.
+ */
+function tripal_chado_field_instance_settings_form_alter(&$form, $form_state) {
+  global $language;
+  $field = $form['#field'];
+  $instance = $form['#instance'];
+
+  // Only show the Chado mapping information for field instances that map
+  // to Chado.
+  if (!array_key_exists('chado_table',$instance['settings'])) {
+    return;
+  }
+
+  // Construct a table for the vocabulary information.
+  $headers = array();
+  $rows = array();
+  $rows[] = array(
+    array(
+      'data' => 'Base Table',
+      'header' => TRUE,
+      'width' => '20%',
+    ),
+    $instance['settings']['base_table']
+  );
+  $rows[] = array(
+    array(
+      'data' => 'Record Table',
+      'header' => TRUE,
+      'width' => '20%',
+    ),
+    $instance['settings']['chado_table']
+  );
+  $rows[] = array(
+    array(
+      'data' => 'ID Column',
+      'header' => TRUE,
+      'width' => '20%',
+    ),
+    $instance['settings']['chado_column']
+  );
+  $table = array(
+    'header' => $headers,
+    'rows' => $rows,
+    'attributes' => array(
+    ),
+    'sticky' => FALSE,
+    'caption' => '',
+    'colgroups' => array(),
+    'empty' => '',
+  );
+
+  $form['chado_mapping'] = array(
+    '#type' => 'fieldset',
+    '#title' => 'Chado Mapping',
+    '#description' => t('This field maps to data in Chado to the following table:'),
+  );
+  $form['chado_mapping']['details'] = array(
+    '#type' => 'item',
+    '#markup' => theme_table($table),
+  );
+
+}
+<<<<<<< HEAD
+=======
+
+/**
+ * Implements hook_form_FROM_ID_alter()
+ */
+function tripal_chado_form_tripalbundle_form_alter(&$form, $form_state) {
+  global $language;
+  $bundle = $form['#bundle'];
+
+  $term = entity_load('TripalTerm', array('id' => $bundle->term_id));
+  $term = reset($term);
+  $vocab = $term->vocab;
+  $params = array(
+    'vocabulary' => $vocab->vocabulary,
+    'accession' => $term->accession,
+  );
+  $mapped_table = chado_get_cvterm_mapping($params);
+  $chado_table = $mapped_table->chado_table;
+  $chado_column = $mapped_table->chado_field;
+
+  // Construct a table for the vocabulary information.
+  $headers = array();
+  $rows = array();
+  $rows[] = array(
+    array(
+      'data' => 'Chado Table',
+      'header' => TRUE,
+      'width' => '20%',
+    ),
+    $chado_table
+  );
+  $rows[] = array(
+    array(
+      'data' => 'Type Column',
+      'header' => TRUE,
+      'width' => '20%',
+    ),
+    $chado_column
+  );
+  $table = array(
+    'header' => $headers,
+    'rows' => $rows,
+    'attributes' => array(
+    ),
+    'sticky' => FALSE,
+    'caption' => '',
+    'colgroups' => array(),
+    'empty' => '',
+  );
+
+  $form['chado_mapping'] = array(
+    '#type' => 'item',
+    '#title' => 'Chado Mapping',
+    '#markup' => theme_table($table),
+    '#description' => t('This content type maps to the table in Chado
+        listed above.  Chado allows multiple data types to be housed
+        in a single table. Therefore, the column that is used to
+        differentiate between data types is also listed above.'),
+    '#weight' => 0,
+  );
+}
+>>>>>>> a584591704c14877292a457afa4b1e793853f9f6

+ 1 - 14
tripal_chado/tripal_chado.module

@@ -839,17 +839,4 @@ 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.
-}
-
-/**
- * Implements hook_form_alter().
- */
-function tripal_chado_form_alter(&$form, $form_state, $form_id) {
-  // If this is the field_ui_field_edit_form (i.e. the form that appears
-  // when editing a field that is attached to an entity). Then we want
-  // to add term settings for any field attached to a TripalEntity
-  // content type.
-  if ($form_id == 'field_ui_field_edit_form' and $form['#instance']['entity_type'] == 'TripalEntity') {
-    tripal_chado_field_instance_settings_form_alter($form, $form_state);
-  }
-}
+}

+ 116 - 1
tripal_ds/includes/tripal_ds.ds.inc

@@ -131,7 +131,7 @@ function _ds_layout_settings_info($bundle_name, $instances) {
         $group_field_name = substr($group_field_name, 0, 27);
         $fieldset_field_name = substr($fieldset_field_name, 0, 27);
 
-        // Add randomm numbers to ensure the field name is unique within the 32
+        // Add random numbers to ensure the field name is unique within the 32
         // character limit of the field.
         $group_field_name = $group_field_name.rand(0, 99999);
         $fieldset_field_name = $fieldset_field_name.rand(0, 99999);
@@ -189,6 +189,121 @@ function _ds_layout_settings_info($bundle_name, $instances) {
 }
 
 
+/**
+ *  Implements hook_ds_layout_settings_info().
+ */
+function _ds_layout_pub_settings_info($bundle_name, $instances) {
+  $region_right = array();
+  $region_left = array();
+  $properties= array();
+  $all_fields = array();
+  $instances_for_field_groups = array();
+  $disabled_instances = array();
+
+  try {
+    // Add Abstract, Citation, DB Cross Reference, Properties.
+    $all_fields['tpub__abstract']= 'right';
+    $all_fields['tpub__citation']= 'right';
+    $all_fields['sbo__database_cross_reference']= 'right';
+    $all_fields['tpub__publication_type']= 'right';
+    $all_fields['tpub__doi']= 'right';
+    $all_fields['tpub__publication_date']= 'right';
+    $all_fields['sio__references']= 'right';
+
+    // Iterate through the fields of this bundle.
+    foreach ($instances as $key => $instance) {
+      $instance_name = $instance['field_name'];
+
+      if($instance_name == 'tpub__abstract' || $instance_name == 'tpub__citation' || $instance_name == 'sbo__database_cross_reference' || $instance_name == 'sio__references'){
+        array_push($instances_for_field_groups, $instance);
+        // Update the display settings so that the title is hidden.
+        $instance['display']['default']['label'] = 'hidden';
+        field_update_instance($instance);
+      }
+      elseif($instance_name == 'tpub__publication_type' || $instance_name == 'tpub__doi' || $instance_name == 'tpub__publication_date') {
+        array_push($properties, $instance);
+      }
+      else {
+        array_push($disabled_instances, $instance);
+      }
+
+    }
+    //Publication fields that are not going in the properties table.
+    foreach ($instances_for_field_groups as $key => $other_field) {
+      // Temporary field names.
+      $temporary_field = array();
+      $group_field_name = 'gp_'.$other_field['field_name'];
+      $fieldset_field_name = 'ft_'.$other_field['field_name'];
+
+      // Need to truncate the names because of database field size restrictions,
+      // updating fields here to ensure name consistency.
+      $group_field_name = substr($group_field_name, 0, 27);
+      $fieldset_field_name = substr($fieldset_field_name, 0, 27);
+
+      // Add randomm numbers to ensure the field name is unique within the 32
+      // character limit of the field.
+      $group_field_name = $group_field_name.rand(0, 99999);
+      $fieldset_field_name = $fieldset_field_name.rand(0, 99999);
+
+      // Build the field group.
+      _additional_fields_field_group_info($bundle_name, $other_field['label'], $group_field_name, $fieldset_field_name, $other_field['field_name']);
+
+      // Update arrays.
+      array_push($temporary_field, $group_field_name, $fieldset_field_name, $other_field['field_name']);
+      $region_right = array_merge($region_right, $temporary_field);
+      $all_fields += [ $group_field_name => 'right', $fieldset_field_name => 'right' ];
+    }
+
+    //Properties table fields.
+    if(!empty($properties)){
+      _publication_prop_field_group_info($bundle_name, $properties);
+      array_unshift($properties, 'group_prop_tripalpane', 'group_prop', 'group_prop_table');
+      $region_right = array_merge($region_right, $properties);
+      $all_fields+= [ 'group_prop_tripalpane' => 'right', 'group_prop' => 'right', 'group_prop_table' => 'right' ];
+    }
+
+    // Add blocks to $region_left and build the toc field that is placed within.
+    _ds_fields_info_write($bundle_name);
+    $region_left += [ 'toc' ];
+    $all_fields += [ 'toc' => 'left' ];
+    // Build the ds layout.
+    $record = new stdClass;
+    $record->id ='TripalEntity|' . $bundle_name . '|default';
+    $record->entity_type = 'TripalEntity';
+    $record->bundle = $bundle_name;
+    $record->view_mode = 'default';
+    $record->layout = 'tripal_ds_feature';
+    $settings = array(
+      'regions' => array(
+        'left' =>
+          $region_left,
+        'right' =>
+          $region_right,
+      ),
+      'fields' =>
+        $all_fields,
+      'classes' => array(),
+      'wrappers' => array(
+        'left' => 'div',
+        'right' => 'div',
+      ),
+      'layout_wrapper' => 'div',
+      'layout_attributes' => '',
+      'layout_attributes_merge' => 1,
+      'layout_link_attribute' => '',
+      'layout_link_custom' => '',
+      'layout_disable_css' => 0,
+    );
+    $record->settings = $settings;
+    drupal_write_record('ds_layout_settings', $record);
+  }
+  catch (Exception $e) {
+    watchdog_exception('tripal_ds', $e);
+    return FALSE;
+  }
+  return TRUE;
+}
+
 /**
  * Implements hook_ds_fields_info().
  */

+ 1 - 74
tripal_ds/includes/tripal_ds.field_formatter.inc

@@ -56,77 +56,4 @@ function tripal_ds_field_group_pre_render(&$element, $group, &$form) {
       $element['#suffix'] = '</div>';
       break;
   }
-}
-
-/*
- * Implements hook_field_group_create_field_group
- * 
- */
-function tripal_ds_field_group_create_field_group($group) {
-
-  if($group->format_type == 'tripalpane'){
-    //write to the tripal_ds table to record the new tripal pane
-    $field_for_table = new stdClass();
-    $field_for_table->tripal_ds_field_name = $group->group_name;
-    $field_for_table->tripal_ds_field_label = $group->label;
-    $field_for_table->entity_type = 'TripalEntity';
-    $field_for_table->bundle = $group->bundle;
-
-    drupal_write_record('tripal_ds', $field_for_table);
-
-  }
-}
-
-/*
- * Implements hook_field_group_delete_field_group
- * 
- */
-function tripal_ds_field_group_delete_field_group($group) {
-
-  if($group->format_type == 'tripalpane'){
-    db_delete('tripal_ds')
-      ->condition('bundle', $group->bundle, '=')
-      ->condition('tripal_ds_field_name', $group->group_name, '=')
-      ->execute();
-    }
-}
-
-/*
- * Implements hook_field_group_update_field_group
- * checks for changes from tripalpane to another type
- */
-function tripal_ds_field_group_update_field_group($group) {
-  //Change from tripal pane to another type.
-  if(!empty($group->bundle)){
-    $result = db_select('tripal_ds', 't')
-      ->fields('t')
-      ->condition('bundle', $group->bundle,'=')
-      ->condition('tripal_ds_field_name', $group->group_name,'=')
-      ->execute()
-      ->fetchAssoc();
-
-    //Change from tripal pane to another type.
-    if($group->format_type !== 'tripalpane' && !empty($result)){
-       db_delete('tripal_ds')
-      ->condition('bundle', $result['bundle'], '=')
-      ->condition('tripal_ds_field_name', $result['tripal_ds_field_name'], '=')
-      ->execute();
-    }
-
-    //Change from other type to tripalpane.
-    if($group->format_type == 'tripalpane' && empty($result)){
-
-      if(strpos($group->group_name, 'Tripal Pane')){
-        $group_name = str_replace('Tripal Pane', "", $group->group_name);
-      } 
-      $field_for_table = new stdClass();
-      $field_for_table->tripal_ds_field_name = $group_name;
-      $field_for_table->tripal_ds_field_label = $group->label;
-      $field_for_table->entity_type = 'TripalEntity';
-      $field_for_table->bundle = $group->bundle;
-
-      drupal_write_record('tripal_ds', $field_for_table);
-    }
-  }
-}
-
+}

+ 107 - 28
tripal_ds/includes/tripal_ds.field_group.inc

@@ -34,13 +34,8 @@ function _summary_field_group_info($bundle_name, $fields){
   drupal_write_record('field_group', $field_group_tripalpane);
 
   //Write to the tripal_ds table to record the new tripal pane.
-  $field_for_table = new stdClass();
-  $field_for_table->tripal_ds_field_name = 'group_summary_tripalpane';
-  $field_for_table->tripal_ds_field_label = 'Summary';
-  $field_for_table->entity_type = 'TripalEntity';
-  $field_for_table->bundle = $bundle_name;
+  tripal_ds_bundle_menu_item($bundle_name, 'Summary', 'group_summary_tripalpane', 'TripalEntity');
 
-  drupal_write_record('tripal_ds', $field_for_table);
 
   //Fieldset field to nest the table within.
   $field_group_fieldset = new stdClass();
@@ -122,7 +117,7 @@ function _prop_field_group_info($bundle_name, $fields){
   $field_group_tripalpane->mode = 'default';
   $field_group_tripalpane->parent_name = '';
   $field_group_tripalpane->data = array(
-    'label' => 'Tripal Pane Properties',
+    'label' => 'Properties Tripal Pane',
     'weight' => '2',
     'children' => array(
         0 => 'group_prop',
@@ -140,13 +135,7 @@ function _prop_field_group_info($bundle_name, $fields){
   drupal_write_record('field_group', $field_group_tripalpane);
 
   //write to the tripal_ds table to record the new tripal pane.
-  $field_for_table = new stdClass();
-  $field_for_table->tripal_ds_field_name = 'group_prop_tripalpane';
-  $field_for_table->tripal_ds_field_label = 'Properties';
-  $field_for_table->entity_type = 'TripalEntity';
-  $field_for_table->bundle = $bundle_name;
-
-  drupal_write_record('tripal_ds', $field_for_table);
+  tripal_ds_bundle_menu_item($bundle_name, 'Properties', 'group_prop_tripalpane', 'TripalEntity');
 
 
   //Fieldset field to nest the table within.
@@ -245,13 +234,7 @@ function _data_sequence_field_group_info($bundle_name, $fields){
   drupal_write_record('field_group', $field_group_tripalpane);
 
   //Write to the tripal_ds table to record the new tripal pane.
-  $field_for_table = new stdClass();
-  $field_for_table->tripal_ds_field_name = 'group_sequence_tripalpane';
-  $field_for_table->tripal_ds_field_label = 'Sequence';
-  $field_for_table->entity_type = 'TripalEntity';
-  $field_for_table->bundle = $bundle_name;
-
-  drupal_write_record('tripal_ds', $field_for_table);
+  tripal_ds_bundle_menu_item($bundle_name, 'Sequence', 'group_sequence_tripalpane', 'TripalEntity');
 
   //Fieldset field to nest the table within.
   $field_group_fieldset = new stdClass();
@@ -323,13 +306,7 @@ function _data_sequence_field_group_info($bundle_name, $fields){
 
 function _additional_fields_field_group_info($bundle_name, $field_label, $group_field_name, $fieldset_field_name, $field_name){
   //Write to the tripal_ds table to record the new tripal pane.
-  $field_for_table = new stdClass();
-  $field_for_table->tripal_ds_field_name = $group_field_name;
-  $field_for_table->tripal_ds_field_label = $field_label;
-  $field_for_table->entity_type = 'TripalEntity';
-  $field_for_table->bundle = $bundle_name;
-
-  drupal_write_record('tripal_ds', $field_for_table);
+  tripal_ds_bundle_menu_item($bundle_name, $field_label, $group_field_name, 'TripalEntity');
 
   //Tripal pane to nest the fieldset within.
   $field_group_fieldset = new stdClass();
@@ -393,4 +370,106 @@ function _additional_fields_field_group_info($bundle_name, $field_label, $group_
   drupal_write_record('field_group', $field_group);
 
 }
+/**
+ * Implements hook_field_group_info().
+ */
+
+function _publication_prop_field_group_info($bundle_name, $fields){
+
+  //Tripal pane  to nest the fieldset within.
+  $field_group_tripalpane = new stdClass();
+  $field_group_tripalpane->disabled = FALSE; /* Edit this to true to make a default field_group disabled initially*/
+  $field_group_tripalpane->api_version = 1;
+  $field_group_tripalpane->identifier = 'group_prop_tripalpane|TripalEntity|'.$bundle_name.'|default';
+  $field_group_tripalpane->group_name = 'group_prop_tripalpane';
+  $field_group_tripalpane->entity_type = 'TripalEntity';
+  $field_group_tripalpane->bundle = $bundle_name;
+  $field_group_tripalpane->mode = 'default';
+  $field_group_tripalpane->parent_name = '';
+  $field_group_tripalpane->data = array(
+    'label' => 'Properties Tripal Pane',
+    'weight' => '2',
+    'children' => array(
+      0 => 'group_prop',
+    ),
+    'format_type' => 'tripalpane',
+    'format_settings' => array(
+      'label' => 'Tripal Pane Properties',
+      'instance_settings' => array(
+        'id' => 'tripal_ds-fieldset-group_prop_tripalpane',
+        'classes' => 'group-prop-tripalpane field-group-tripalpane',
+        'description' => '',
+      ),
+    ),
+  );
+  drupal_write_record('field_group', $field_group_tripalpane);
+
+  //write to the tripal_ds table to record the new tripal pane.
+  tripal_ds_bundle_menu_item($bundle_name, 'Properties', 'group_prop_tripalpane', 'TripalEntity');
+
+  //Fieldset field to nest the table within.
+  $field_group_fieldset = new stdClass();
+  $field_group_fieldset->disabled = FALSE; /* Edit this to true to make a default field_group disabled initially*/
+  $field_group_fieldset->api_version = 1;
+  $field_group_fieldset->identifier = 'group_prop|TripalEntity|'.$bundle_name.'|default';
+  $field_group_fieldset->group_name = 'group_prop';
+  $field_group_fieldset->entity_type = 'TripalEntity';
+  $field_group_fieldset->bundle = $bundle_name;
+  $field_group_fieldset->mode = 'default';
+  $field_group_fieldset->parent_name = 'group_prop_tripalpane';
+  $field_group_fieldset->data = array(
+    'label' => 'Properties',
+    'weight' => '3',
+    'children' => array(
+      0 => 'group_prop_table',
+    ),
+    'format_type' => 'fieldset',
+    'format_settings' => array(
+      'label' => 'Properties',
+      'instance_settings' => array(
+        'id' => '',
+        'classes' => 'group-prop field-group-fieldset',
+        'description' => '',
+      ),
+      'formatter' => 'collapsible',
+    ),
+  );
+
+  drupal_write_record('field_group', $field_group_fieldset);
 
+  //Table of fields.
+  $field_group = new stdClass();
+  $field_group->disabled = FALSE; /* Edit this to true to make a default field_group disabled initially*/
+  $field_group->api_version = 1;
+  $field_group->identifier = 'group_prop_table|TripalEntity|'.$bundle_name.'|default';
+  $field_group->group_name = 'group_prop_table';
+  $field_group->entity_type = 'TripalEntity';
+  $field_group->bundle = $bundle_name;
+  $field_group->mode = 'default';
+  $field_group->parent_name = 'group_prop';
+  $field_group->data = array(
+    'label' => 'Properties Table',
+    'weight' => '30',
+    'children' =>  array(
+      0 => 'tpub__doi',
+      1 => 'tpub__publication_date',
+      2 => 'tpub__publication_type',
+    ),
+    'format_type' => 'table',
+    'format_settings' => array(
+      'label' => 'Properties Table',
+      'instance_settings' => array(
+        'label_visibility' => '1',
+        'desc' => '',
+        'first_column' => '',
+        'second_column' => '',
+        'empty_label_behavior' => '1',
+        'table_row_striping' => 0,
+        'always_show_field_label' => 0,
+        'classes' => 'group-prop-table field-group-table',
+      ),
+    ),
+  );
+
+  drupal_write_record('field_group', $field_group);
+}

+ 0 - 64
tripal_ds/publication.ds.inc

@@ -1,64 +0,0 @@
-<?php
-/**
- * @file
- * publication.ds.inc
- */
-
-/**
- * Implements hook_ds_layout_settings_info().
- */
-function publication_ds_layout_settings_info() {
-  $export = array();
-
-  $ds_layout = new stdClass();
-  $ds_layout->api_version = 1;
-  $ds_layout->id = 'TripalEntity|bio_data_45|default';
-  $ds_layout->entity_type = 'TripalEntity';
-  $ds_layout->bundle = 'bio_data_45';
-  $ds_layout->view_mode = 'default';
-  $ds_layout->layout = 'ds_2col';
-  $ds_layout->settings = array(
-    'regions' => array(
-      'left' => array(
-        0 => 'tpub__abstract',
-      ),
-      'right' => array(
-        1 => 'group_citation',
-        2 => 'tpub__citation',
-        3 => 'group_properties',
-        4 => 'group_references',
-        5 => 'sio__references',
-        6 => 'group_property_table',
-        7 => 'tpub__publication_type',
-        8 => 'tpub__doi',
-        9 => 'sbo__database_cross_reference',
-      ),
-    ),
-    'fields' => array(
-      'tpub__abstract' => 'left',
-      'group_citation' => 'right',
-      'tpub__citation' => 'right',
-      'group_properties' => 'right',
-      'group_references' => 'right',
-      'sio__references' => 'right',
-      'group_property_table' => 'right',
-      'tpub__publication_type' => 'right',
-      'tpub__doi' => 'right',
-      'sbo__database_cross_reference' => 'right',
-    ),
-    'classes' => array(),
-    'wrappers' => array(
-      'left' => 'div',
-      'right' => 'div',
-    ),
-    'layout_wrapper' => 'div',
-    'layout_attributes' => '',
-    'layout_attributes_merge' => 1,
-    'layout_link_attribute' => '',
-    'layout_link_custom' => '',
-    'layout_disable_css' => 0,
-  );
-  $export['TripalEntity|bio_data_45|default'] = $ds_layout;
-
-  return $export;
-}

+ 0 - 17
tripal_ds/publication.features.inc

@@ -1,17 +0,0 @@
-<?php
-/**
- * @file
- * publication.features.inc
- */
-
-/**
- * Implements hook_ctools_plugin_api().
- */
-function publication_ctools_plugin_api($module = NULL, $api = NULL) {
-  if ($module == "ds" && $api == "ds") {
-    return array("version" => "1");
-  }
-  if ($module == "field_group" && $api == "field_group") {
-    return array("version" => "1");
-  }
-}

+ 0 - 138
tripal_ds/publication.field_group.inc

@@ -1,138 +0,0 @@
-<?php
-/**
- * @file
- * publication.field_group.inc
- */
-
-/**
- * Implements hook_field_group_info().
- */
-function publication_field_group_info() {
-  $field_groups = array();
-
-  $field_group = new stdClass();
-  $field_group->disabled = FALSE; /* Edit this to true to make a default field_group disabled initially */
-  $field_group->api_version = 1;
-  $field_group->identifier = 'group_citation|TripalEntity|bio_data_45|default';
-  $field_group->group_name = 'group_citation';
-  $field_group->entity_type = 'TripalEntity';
-  $field_group->bundle = 'bio_data_45';
-  $field_group->mode = 'default';
-  $field_group->parent_name = '';
-  $field_group->data = array(
-    'label' => 'Citation',
-    'weight' => '1',
-    'children' => array(
-      0 => 'tpub__citation',
-    ),
-    'format_type' => 'fieldset',
-    'format_settings' => array(
-      'label' => 'Citation',
-      'instance_settings' => array(
-        'id' => '',
-        'classes' => 'group-citation field-group-fieldset',
-        'description' => '',
-      ),
-      'formatter' => 'open',
-    ),
-  );
-  $field_groups[''] = $field_group;
-
-  $field_group = new stdClass();
-  $field_group->disabled = FALSE; /* Edit this to true to make a default field_group disabled initially */
-  $field_group->api_version = 1;
-  $field_group->identifier = 'group_properties|TripalEntity|bio_data_45|default';
-  $field_group->group_name = 'group_properties';
-  $field_group->entity_type = 'TripalEntity';
-  $field_group->bundle = 'bio_data_45';
-  $field_group->mode = 'default';
-  $field_group->parent_name = '';
-  $field_group->data = array(
-    'label' => 'Properties',
-    'weight' => '2',
-    'children' => array(
-      0 => 'group_property_table',
-    ),
-    'format_type' => 'fieldset',
-    'format_settings' => array(
-      'label' => 'Properties',
-      'instance_settings' => array(
-        'id' => '',
-        'classes' => 'group-properties field-group-fieldset',
-        'description' => '',
-      ),
-      'formatter' => 'open',
-    ),
-  );
-  $field_groups[''] = $field_group;
-
-  $field_group = new stdClass();
-  $field_group->disabled = FALSE; /* Edit this to true to make a default field_group disabled initially */
-  $field_group->api_version = 1;
-  $field_group->identifier = 'group_property_table|TripalEntity|bio_data_45|default';
-  $field_group->group_name = 'group_property_table';
-  $field_group->entity_type = 'TripalEntity';
-  $field_group->bundle = 'bio_data_45';
-  $field_group->mode = 'default';
-  $field_group->parent_name = 'group_properties';
-  $field_group->data = array(
-    'label' => '',
-    'weight' => '30',
-    'children' => array(
-      0 => 'sbo__database_cross_reference',
-      1 => 'tpub__doi',
-      2 => 'tpub__publication_type',
-    ),
-    'format_type' => 'table',
-    'format_settings' => array(
-      'label' => '',
-      'instance_settings' => array(
-        'label_visibility' => '3',
-        'desc' => '',
-        'first_column' => '',
-        'second_column' => '',
-        'empty_label_behavior' => '1',
-        'table_row_striping' => 0,
-        'always_show_field_label' => 0,
-        'classes' => 'group-property-table field-group-table',
-      ),
-    ),
-  );
-  $field_groups[''] = $field_group;
-
-  $field_group = new stdClass();
-  $field_group->disabled = FALSE; /* Edit this to true to make a default field_group disabled initially */
-  $field_group->api_version = 1;
-  $field_group->identifier = 'group_references|TripalEntity|bio_data_45|default';
-  $field_group->group_name = 'group_references';
-  $field_group->entity_type = 'TripalEntity';
-  $field_group->bundle = 'bio_data_45';
-  $field_group->mode = 'default';
-  $field_group->parent_name = '';
-  $field_group->data = array(
-    'label' => 'References',
-    'weight' => '3',
-    'children' => array(
-      0 => 'sio__references',
-    ),
-    'format_type' => 'fieldset',
-    'format_settings' => array(
-      'label' => 'References',
-      'instance_settings' => array(
-        'id' => '',
-        'classes' => 'group-references field-group-fieldset',
-        'description' => 'The following data housed by this site is referred  to by this publication.',
-      ),
-      'formatter' => 'open',
-    ),
-  );
-  $field_groups[''] = $field_group;
-
-  // Translatables
-  // Included for use with string extractors like potx.
-  t('Citation');
-  t('Properties');
-  t('References');
-
-  return $field_groups;
-}

+ 0 - 14
tripal_ds/publication.info

@@ -1,14 +0,0 @@
-name = Publication
-core = 7.x
-package = Features
-dependencies[] = ctools
-dependencies[] = ds
-dependencies[] = field_group
-features[ctools][] = ds:ds:1
-features[ctools][] = field_group:field_group:1
-features[ds_layout_settings][] = TripalEntity|bio_data_45|default
-features[features_api][] = api:2
-features[field_group][] = group_citation|TripalEntity|bio_data_45|default
-features[field_group][] = group_properties|TripalEntity|bio_data_45|default
-features[field_group][] = group_property_table|TripalEntity|bio_data_45|default
-features[field_group][] = group_references|TripalEntity|bio_data_45|default

+ 0 - 7
tripal_ds/publication.module

@@ -1,7 +0,0 @@
-<?php
-/**
- * @file
- * Code for the Publication feature.
- */
-
-include_once 'publication.features.inc';

+ 121 - 6
tripal_ds/tripal_ds.module

@@ -34,9 +34,9 @@ function tripal_ds_menu() {
   $items['admin/structure/bio_data/manage/%/display/apply'] = array(
     'title' => 'Apply Default Tripal Layout (will reset current layout)',
     'description' => t('Apply the Tripal Display Suite settings to this content type.'),
-    'page callback' => 'tripal_ds_apply',
+    'page callback' => 'drupal_get_form',
     'access arguments' => array('administer tripal'),
-    'page arguments' => array(4),
+    'page arguments' => array('tripal_ds_update_layout_form', 4),
     'type' => MENU_LOCAL_ACTION,
   );
   return $items;
@@ -49,20 +49,106 @@ function tripal_ds_menu() {
  */
 function tripal_ds_bundle_postcreate($bundle) {
   $bundle_name = $bundle->name;
+  $bundle_data_table = $bundle->data_table;
   $instances = field_info_instances('TripalEntity', $bundle_name);
-  _ds_layout_settings_info($bundle_name, $instances);
+  if($bundle_data_table == 'pub'){
+    _ds_layout_pub_settings_info($bundle_name, $instances);
+  }
+  else {
+    _ds_layout_settings_info($bundle_name, $instances);
+  }
+
 }
 
+/**
+ * Update the tripal_ds table when a tripal pane is deleted.
+ */
 function tripal_ds_table_column_delete($bundle){
     $bundle_name = $bundle->name;
     db_delete('tripal_ds')
       ->condition('bundle', $bundle_name, '=')
       ->execute();
 }
-
+/**
+ * Trigger the update to the tripal_ds table when a tripal pane is deleted.
+ */
 function tripal_ds_bundle_delete($bundle){
   tripal_ds_table_column_delete($bundle);
 }
+
+/*
+ * Implements hook_ds_field_settings_alter()
+ */
+function tripal_ds_ds_field_settings_alter(&$field_settings, $form, $form_state){
+  // Get the form info from the bundle about to be saved.
+  $tripal_entity_object = $form_state['build_info']['args']['1'];
+  // Grab the bundle.
+  $bundle_id = $tripal_entity_object->name;
+  // Grab the field groups from the bundle.
+  $updated_field_groups = $form_state['field_group'];
+  // Grab the fields from the bundle.
+  $fields = $form_state['values']['fields'];
+
+  // Delete the menu items associated with the bundle id.
+  db_delete('tripal_ds')
+    ->condition('bundle', $bundle_id, '=')
+    ->execute();
+
+  // Traverse the updated field_groups grabbing the tripal pane items.
+  $tripal_pane_field_groups = array();
+  $i = 0;
+  foreach($updated_field_groups as $updated_field_group){
+    if($updated_field_group->format_type == 'tripalpane'){
+      $tripal_pane_field_groups += [ $i => $updated_field_group->group_name];
+      $i++;
+    }
+  }
+
+  // Now grab the labels of the field_groups whose parent is a tripalpane.
+  foreach($updated_field_groups as $updated_field_group){
+    foreach($tripal_pane_field_groups as $tripal_pane_field_group){
+      if($updated_field_group->parent_name == $tripal_pane_field_group){
+        if($fields[$tripal_pane_field_group]['region'] !== 'hidden'){
+          tripal_ds_bundle_menu_item($bundle_id, $updated_field_group->label, $tripal_pane_field_group, 'tripalentity');
+        }
+      }
+    }
+  }
+}
+
+/**
+ * Trigger the update to the tripal_ds table when a tripal pane is deleted.
+ */
+function tripal_ds_bundle_menu_item($bundle_name, $field_label, $field_name, $entity_type){
+
+  //Check the record does not already exist
+  $tripal_ds_rows = db_select('tripal_ds', 'ds')
+    ->fields('ds', array('tripal_ds_field_name', 'tripal_ds_field_label'))
+    ->condition('bundle', $bundle_name, '=')
+    ->condition('tripal_ds_field_label', $field_label, '=')
+    ->condition('tripal_ds_field_name', $field_name, '=')
+    ->execute()->fetchAll();
+
+  if(!empty($tripal_ds_rows)){
+    foreach ($tripal_ds_rows as $tripal_ds_row){
+      if(($field_label == $tripal_ds_row->tripal_ds_field_label) && ($field_name == $tripal_ds_row->tripal_ds_field_name) && ($bundle_name == $tripal_ds_rows->bundle)) {
+        // Do not write the field to the table
+        drupal_set_message("Could not update the bundle menu because that field already exists.", 'error');
+      }
+    }
+  }
+  else {
+    //Write to the tripal_ds table to record the new tripal pane.
+    $field_for_table = new stdClass();
+    $field_for_table->tripal_ds_field_name = $field_name;
+    $field_for_table->tripal_ds_field_label = $field_label;
+    $field_for_table->entity_type = $entity_type;
+    $field_for_table->bundle = $bundle_name;
+    drupal_write_record('tripal_ds', $field_for_table);
+
+  }
+}
+
 /*
  * Implements hook_ds_layout_info() to define layouts from code in a module for
  * display suite
@@ -85,11 +171,33 @@ function tripal_ds_ds_layout_info() {
   return $layouts;
 }
 
+function tripal_ds_update_layout_form($form, &$form_state, $bundle_name) {
+  $form = array();
+  $form['bundle_name'] = array(
+    '#type' => 'value',
+    '#value' => $bundle_name,
+  );
+
+  $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
+  $bundle_label = $bundle->label;
+
+  return confirm_form($form,
+    t('Please confirm you would like to apply this layout: ' . $bundle_label),
+    'admin/structure/bio_data/manage/' . $bundle_name . '/display',
+    t('This action cannot be undone.'),
+    t('Yes, apply layout'),
+    t('No, cancel')
+  );
+}
+
 /**
  *
  * @param $bundle_name
  */
-function tripal_ds_apply($bundle_name) {
+function tripal_ds_update_layout_form_submit($form, &$form_state) {
+  $bundle_name = $form_state['build_info']['args'][0];
+  $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
+
   //Build the identifier to check against ds_layout_settings.
   $ds_identifier = 'TripalEntity|'.$bundle_name.'|default';
 
@@ -144,7 +252,14 @@ function tripal_ds_apply($bundle_name) {
 
   //Now you can build the layout fresh.
   $instances = field_info_instances('TripalEntity', $bundle_name);
-  $success = _ds_layout_settings_info($bundle_name, $instances);
+  $bundle_data_table = $bundle->data_table;
+  if($bundle_data_table == 'pub'){
+    $success = _ds_layout_pub_settings_info($bundle_name, $instances);
+  }
+  else {
+    $success = _ds_layout_settings_info($bundle_name, $instances);
+  }
+
   if ($success) {
     drupal_set_message("Layout applied successfully and saved.");
   }