Browse Source

Added necessary code to support the biomaterial table

Stephen Ficklin 7 years ago
parent
commit
ccde805a45

+ 6 - 0
tripal_chado/api/tripal_chado.schema.api.inc

@@ -586,6 +586,12 @@ function chado_get_base_tables() {
   // whose foreign key constraints link to two or more base table.
   $final_list = array();
   foreach ($base_tables as $i => $tablename) {
+    // The biomaterial table breaks our rule and seems to look like a linking
+    // table, but we want to keep it as a base table.
+    if ($tablename == 'biomaterial') {
+      $final_list[] = $tablename;
+      continue;
+    }
     $num_links = 0;
     $schema = chado_get_schema($tablename);
     $fkeys = $schema['foreign keys'];

+ 221 - 0
tripal_chado/includes/TripalFields/local__contact/local__contact.inc

@@ -0,0 +1,221 @@
+<?php
+
+class local__contact extends ChadoField {
+
+
+  // --------------------------------------------------------------------------
+  //                     EDITABLE STATIC CONSTANTS
+  //
+  // The following constants SHOULD be set for each descendent class.  They are
+  // used by the static functions to provide information to Drupal about
+  // the field and it's default widget and formatter.
+  // --------------------------------------------------------------------------
+
+  // The default lable for this field.
+  public static $default_label = 'Contact';
+
+  // The default description for this field.
+  public static $description = 'An indviddual or organization that serves as a contact for this record.';
+
+  // Provide a list of instance specific settings. These can be access within
+  // the instanceSettingsForm.  When the instanceSettingsForm is submitted
+  // then Drupal with automatically change these settings for the instnace.
+  // It is recommended to put settings at the instance level whenever possible.
+  // If you override this variable in a child class be sure to replicate the
+  // term_name, term_vocab, term_accession and term_fixed keys as these are
+  // required for all TripalFields.
+  public static $default_instance_settings  = array(
+    // The short name for the vocabulary (e.g. shcema, SO, GO, PATO, etc.).
+    'term_vocabulary' => 'local',
+    // The name of the term.
+    'term_name' => 'contact',
+    // The unique ID (i.e. accession) of the term.
+    'term_accession' => 'contact',
+    // Set to TRUE if the site admin is allowed to change the term
+    // type. This will create form elements when editing the field instance
+    // to allow the site admin to change the term settings above.
+    'term_fixed' => FALSE,
+  );
+
+
+  // The default widget for this field.
+  public static $default_widget = 'local__contact_widget';
+
+  // The default formatter for this field.
+  public static $default_formatter = 'local__contact_formatter';
+
+  // --------------------------------------------------------------------------
+  //              PROTECTED CLASS MEMBERS -- DO NOT OVERRIDE
+  // --------------------------------------------------------------------------
+  // An array containing details about the field. The format of this array
+  // is the same as that returned by field_info_fields()
+  protected $field;
+  // An array containing details about an instance of the field. A field does
+  // not have to have an instance.  But if dealing with an instance (such as
+  // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
+  protected $instance;
+
+
+  /**
+   * @see TripalField::elements()
+   */
+  public function elementInfo() {
+    $field_term = $this->getFieldTermID();
+    $type_term = tripal_get_chado_semweb_term('contact', 'type_id');
+    $name_term = tripal_get_chado_semweb_term('contact', 'name');
+    $description_term = tripal_get_chado_semweb_term('contact', 'description');
+
+    return array(
+      $field_term => array(
+        'operations' => array('eq', 'contains', 'starts'),
+        'sortable' => TRUE,
+        'searchable' => TRUE,
+        'type' => 'string',
+        'elements' => array(
+          $type_term => array(
+            'searchable' => TRUE,
+            'label' => 'Contact Type',
+            'help' => 'The type of contact',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          $name_term => array(
+            'searchable' => TRUE,
+            'label' => 'Contact Name',
+            'help' => 'The name of the contact.',
+            'operations' => array('eq', 'ne', 'contains', 'starts'),
+            'sortable' => TRUE,
+          ),
+          $description_term => array(
+            'searchable' => TRUE,
+            'label' => 'Contact Description',
+            'help' => 'A descriptoin of the contact.',
+            'operations' => array('contains'),
+            'sortable' => TRUE,
+          ),
+          'entity' => array(
+            'searchable' => FALSE,
+          ),
+        ),
+      )
+    );
+  }
+  /**
+   *
+   * @see TripalField::load()
+   */
+  public function load($entity) {
+    $record = $entity->chado_record;
+
+    $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
+    $field_table = $this->instance['settings']['chado_table'];
+    $field_column = $this->instance['settings']['chado_column'];
+    $base_table = $this->instance['settings']['base_table'];
+
+    $type_term = tripal_get_chado_semweb_term('contact', 'type_id');
+    $name_term = tripal_get_chado_semweb_term('contact', 'name');
+    $description_term = tripal_get_chado_semweb_term('contact', 'description');
+
+
+    // Set some defaults for the empty record.
+    $entity->{$field_name}['und'][0] = array(
+      'value' => array(),
+    );
+
+    // Handle the biomaterial table.
+    if ($field_table == 'biomaterial') {
+      if ($record) {
+        $contact = $record->biosourceprovider_id;
+        $entity->{$field_name}['und'][0] = array(
+          'value' => array(
+            $type_term => $contact->type_id ? $contact->type_id->name : '',
+            $name_term => $contact->name,
+            $description_term => $contact->description,
+          ),
+          $entity->{$field_name}['und'][0]['chado-biomaterial__biosourceprovider_id'] = $contact->contact_id,
+        );
+        if (property_exists($contact, 'entity_id')) {
+          $entity->{$field_name}['und'][0]['value']['entity'] = 'TripalEntity:' . $contact->entity_id;
+        }
+      }
+    };
+    // Here place other non-linker tables that have a FK to the contact table.
+  }
+
+  /**
+   * @see ChadoField::query()
+   */
+  public function query($query, $condition) {
+    $alias = $this->field['field_name'];
+    $operator = $condition['operator'];
+
+    $field_term_id = $this->getFieldTermID();
+    $type_term = tripal_get_chado_semweb_term('contact', 'type_id');
+    $name_term = tripal_get_chado_semweb_term('contact', 'name');
+    $description_term = tripal_get_chado_semweb_term('contact', 'description');
+
+    if ($field_table == 'biomaterial') {
+      if ($record) {
+        $contact = $record->biosourceprovider_id;
+
+        // Join the contact table
+        $calias = $alias . '_provider_id';
+        $this->queryJoinOnce($query, 'contact', $calias, "base.biosourceprovider_id = $calias.contact_id");
+
+        // Search by the contact name
+        if ($condition['column'] == $field_term_id or
+            $condition['column'] == $field_term_id . ',' . $name_term) {
+          $query->condition("$calias.name", $condition['value'], $operator);
+        }
+        // Search on the contact description.
+        if ($condition['column'] == $field_term_id . ',' . $description_term) {
+          $query->condition("$calias.description", $condition['value'], $operator);
+        }
+        // Search on the contact type.
+        if ($condition['column'] == $field_term_id . ',' . $type_term) {
+          $talias = $alias . 'provider_contact_type';
+          $this->queryJoinOnce($query, 'cvterm', $talias, "$calias.type_id = $talias.cvterm_id");
+          $query->condition("$talias.name", $condition['value'], $operator);
+        }
+      }
+    }
+  }
+
+  /**
+   * @see ChadoField::queryOrder()
+   */
+  public function queryOrder($query, $order) {
+    $alias = $this->field['field_name'];
+    $field_term_id = $this->getFieldTermID();
+    $type_term = tripal_get_chado_semweb_term('contact', 'type_id');
+    $name_term = tripal_get_chado_semweb_term('contact', 'name');
+    $description_term = tripal_get_chado_semweb_term('contact', 'description');
+
+    if ($field_table == 'biomaterial') {
+      if ($record) {
+        $contact = $record->biosourceprovider_id;
+
+        // Join the contact linker table and then join the contact table.
+        $calias = $alias . '_provider_id';
+        $this->queryJoinOnce($query, 'contact', $calias, "base.biosourceprovider_id = $calias.contact_id");
+
+        // Search by the contact name
+        if ($order['column'] == $field_term_id or
+            $order['column'] == $field_term_id . ',' . $name_term) {
+          $query->orderBy("$calias.name", $order['direction']);
+        }
+        // Search on the contact description.
+        if ($order['column'] == $field_term_id . ',' . $description_term) {
+          $query->orderBy("$calias.description", $order['direction']);
+        }
+        // Search on the contact type.
+        if ($order['column'] == $field_term_id . ',' . $type_term) {
+          $talias = $alias . 'provider_contact_type';
+          $this->queryJoinOnce($query, 'cvterm', $talias, "$calias.type_id = $talias.cvterm_id", "LEFT OUTER");
+          $query->orderBy("$talias.name", $order['direction']);
+        }
+      }
+    }
+  }
+}

+ 75 - 0
tripal_chado/includes/TripalFields/local__contact/local__contact_formatter.inc

@@ -0,0 +1,75 @@
+<?php
+
+class local__contact_formatter extends ChadoFieldFormatter {
+  // The default lable for this field.
+  public static $default_label = 'Contact';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = array('local_contact');
+
+
+  /**
+   *
+   * @see TripalFieldFormatter::settingsForm()
+  */
+  public function settingsForm($view_mode, $form, &$form_state) {
+
+  }
+
+  /**
+   *
+   * @see TripalFieldFormatter::view()
+   */
+  public function view(&$element, $entity_type, $entity, $langcode, $items, $display) {
+    // Get the settings
+    $settings = $display['settings'];
+
+    $type_term = tripal_get_chado_semweb_term('contact', 'type_id');
+    $name_term = tripal_get_chado_semweb_term('contact', 'name');
+    $description_term = tripal_get_chado_semweb_term('contact', 'description');
+
+    $headers = array('Name', 'Description', 'Type');
+    $rows = array();
+
+    foreach ($items as $delta => $item) {
+      $contact = $item['value'];
+      if (!$contact) {
+        continue;
+      }
+
+      // Get the field values
+      $contact_name = $contact[$name_term];
+      $description = $contact[$description_term];
+      $type = $contact[$type_term];
+
+      // Add a link i there is an entity.
+      if (array_key_exists('entity', $item['value']) and $item['value']['entity']) {
+        list($entity_type, $entity_id) = explode(':', $item['value']['entity']);
+        $contact_name = l($contact_name, "bio_data/" . $entity_id, array('attributes' => array('target' => "_blank")));
+      }
+      $rows[] = array($contact_name, $description, $type);
+    }
+    $table = array(
+      'header' => $headers,
+      'rows' => $rows,
+      'attributes' => array(
+        'id' => 'tripal_linker-table-contact-object',
+        'class' => 'tripal-data-table'
+      ),
+      'sticky' => FALSE,
+      'caption' => "",
+      'colgroups' => array(),
+      'empty' => 'There are no contacts available.',
+    );
+    $content = theme_table($table);
+
+    if (count($items) > 0) {
+      // once we have our table array structure defined, we call Drupal's theme_table()
+      // function to generate the table.
+      $element[0] = array(
+        '#type' => 'markup',
+        '#markup' => $content,
+      );
+    }
+  }
+}

+ 126 - 0
tripal_chado/includes/TripalFields/local__contact/local__contact_widget.inc

@@ -0,0 +1,126 @@
+<?php
+
+class local__contact_widget extends ChadoFieldWidget {
+  // The default lable for this field.
+  public static $default_label = 'Contact';
+
+  // The list of field types for which this formatter is appropriate.
+  public static $field_types = array('local_contact');
+
+  /**
+   *
+   * @see TripalFieldWidget::form()
+   */
+  public function form(&$widget, &$form, &$form_state, $langcode, $items, $delta, $element) {
+    parent::form($widget, $form, $form_state, $langcode, $items, $delta, $element);
+    $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
+    $base_table = $this->instance['settings']['base_table'];
+    $field_table = $this->instance['settings']['chado_table'];
+    $chado_column = $this->instance['settings']['chado_column'];
+    $instance = $this->instance;
+
+    $schema = chado_get_schema($field_table);
+    $pkey = $schema['primary key'][0];
+
+    // Get the field defaults.
+    $record_id = '';
+    $contact_id = '';
+    $name = '';
+    $value = '';
+
+    $name_term = tripal_get_chado_semweb_term('contact', 'name');
+
+    // Set the linker field appropriately.
+    if ($field_table == 'biomaterial') {
+      $linker_field = 'chado-biomaterial__biosourceprovider_id';
+    }
+    else {
+      $linker_field = 'chado-' . $field_table . '__contact_id';
+    }
+
+    // If the field already has a value then it will come through the $items
+    // array.  This happens when editing an existing record.
+    if (count($items) > 0 and array_key_exists($delta, $items)) {
+      $name = array_key_exists($name_term, $items[$delta]['value']) ? $items[$delta]['value'][$name_term] : $name;
+      $record_id = tripal_get_field_item_keyval($items, $delta, 'chado-' . $field_table . '__' . $pkey, $record_id);
+      if ($field_table == 'biomaterial') {
+        $contact_id = tripal_get_field_item_keyval($items, $delta, $linker_field, $contact_id);
+      }
+    }
+
+    // Check $form_state['values'] to see if an AJAX call set the values.
+    if (array_key_exists('values', $form_state) and
+        array_key_exists($field_name, $form_state['values'])) {
+      $name = $form_state['values'][$field_name]['und'][$delta]['name'];
+    }
+
+    $schema = chado_get_schema('contact');
+
+    $widget['value'] = array(
+      '#type' => 'value',
+      '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
+    );
+
+    $widget['chado-' . $field_table . '__' . $pkey] = array(
+      '#type' => 'value',
+      '#default_value' => $record_id,
+    );
+    $widget[$linker_field] = array(
+      '#type' => 'value',
+      '#default_value' => $contact_id,
+    );
+
+    $widget['name'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Contact'),
+      '#default_value' => $name,
+      '#autocomplete_path' => 'admin/tripal/storage/chado/auto_name/contact',
+      '#maxlength' => 100000,
+    );
+
+  }
+
+
+  /**
+   *
+   * @see TripalFieldWidget::submit()
+   */
+  public function validate($element, $form, &$form_state, $langcode, $delta) {
+    $field_name = $this->field['field_name'];
+    $field_type = $this->field['type'];
+    $base_table = $this->instance['settings']['base_table'];
+    $field_table = $this->instance['settings']['chado_table'];
+    $chado_column = $this->instance['settings']['chado_column'];
+    $instance = $this->instance;
+
+    // Get information about this contact linke rtable.
+    $schema = chado_get_schema($field_table);
+    $pkey = $schema['primary key'][0];
+
+    // Get the name from the form state.
+    $name = $form_state['values'][$field_name]['und'][$delta]['name'];
+
+    // Set the linker field appropriately.
+    if ($field_table == 'biomaterial') {
+      $linker_field = 'chado-biomaterial__biosourceprovider_id';
+    }
+    else {
+      $linker_field = 'chado-' . $field_table . '__contact_id';
+    }
+
+    // If the user provided a name then we want to set the foreign key
+    // value to be the chado_record_id
+    if ($name) {
+      $contact = chado_generate_var('contact', array('name' => $name));
+      if ($contact) {
+        $form_state['values'][$field_name]['und'][$delta][$linker_field] = $contact->contact_id;
+        $form_state['values'][$field_name]['und'][$delta]['value'] = $name;
+      }
+    }
+    // If no name is provided then we want to set the field for deletion.
+    else {
+      $form_state['values'][$field_name]['und'][$delta][$linker_field] = '';
+    }
+  }
+}

+ 25 - 3
tripal_chado/includes/TripalFields/obi__organism/obi__organism.inc

@@ -56,11 +56,19 @@ class obi__organism extends ChadoField {
     $field_table = $this->instance['settings']['chado_table'];
     $field_column = $this->instance['settings']['chado_column'];
 
+    // Set the linker field appropriately.
+    if ($field_table == 'biomaterial') {
+      $linker_field = 'chado-biomaterial__taxon_id';
+    }
+    else {
+      $linker_field = 'chado-' . $field_table . '__organism_id';
+    }
+
     // Get the field values.
     foreach ($items as $delta => $values) {
 
       // Get the field values.
-      $organism_id = $values['chado-' . $field_table . '__organism_id'];
+      $organism_id = $values[$linker_field];
       if (!$organism_id or $organism_id == 0) {
         $errors[$field_name]['und'][0][] = array(
           'message' =>  t("Please specify an organism."),
@@ -90,13 +98,27 @@ class obi__organism extends ChadoField {
     $infraspecific_name_term = tripal_get_chado_semweb_term('organism', 'infraspecific_name');
     $infraspecific_type_term = tripal_get_chado_semweb_term('organism', 'type_id');
 
+
+    // Set the linker field appropriately.
+    if ($field_table == 'biomaterial') {
+      $linker_field = 'chado-biomaterial__taxon_id';
+    }
+    else {
+      $linker_field = 'chado-' . $field_table . '__organism_id';
+    }
+
     // Set some defaults for the empty record.
     $entity->{$field_name}['und'][0] = array(
       'value' => array(),
     );
 
     if ($record) {
-      $organism = $record->organism_id;
+      if ($field_table == 'biomaterial') {
+        $organism = $record->taxon_id;
+      }
+      else {
+        $organism = $record->organism_id;
+      }
       $string = $settings['field_display_string'];
       $label = tripal_replace_chado_tokens($string, $organism);
       $entity->{$field_name}['und'][0]['value'] = array(
@@ -112,7 +134,7 @@ class obi__organism extends ChadoField {
           $entity->{$field_name}['und'][0]['value'][$infraspecific_type_term] =  $organism->type_id->name;
         }
       }
-      $entity->{$field_name}['und'][0]['chado-' . $field_table . '__organism_id'] = $organism->organism_id;
+      $entity->{$field_name}['und'][0][$linker_field] = $organism->organism_id;
 
       // Is there a published entity for this organism?
       if (property_exists($record->{$field_column}, 'entity_id')) {

+ 20 - 4
tripal_chado/includes/TripalFields/obi__organism/obi__organism_widget.inc

@@ -22,9 +22,17 @@ class obi__organism_widget extends ChadoFieldWidget {
     $field_table = $this->instance['settings']['chado_table'];
     $field_column = $this->instance['settings']['chado_column'];
 
+    // Set the linker field appropriately.
+    if ($field_table == 'biomaterial') {
+      $linker_field = 'chado-biomaterial__taxon_id';
+    }
+    else {
+      $linker_field = 'chado-' . $field_table . '__organism_id';
+    }
+
     $organism_id = 0;
-    if (count($items) > 0 and array_key_exists('chado-' . $field_table . '__organism_id', $items[0])) {
-      $organism_id = $items[0]['chado-' . $field_table . '__organism_id'];
+    if (count($items) > 0 and array_key_exists($linker_field, $items[0])) {
+      $organism_id = $items[0][$linker_field];
     }
 
     $widget['value'] = array(
@@ -32,7 +40,7 @@ class obi__organism_widget extends ChadoFieldWidget {
       '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
     );
     $options = tripal_get_organism_select_options(FALSE);
-    $widget['chado-' . $field_table . '__organism_id'] = array(
+    $widget[$linker_field] = array(
       '#type' => 'select',
       '#title' => $element['#title'],
       '#description' => $element['#description'],
@@ -52,8 +60,16 @@ class obi__organism_widget extends ChadoFieldWidget {
     $field_name = $this->field['field_name'];
     $field_table = $this->instance['settings']['chado_table'];
 
+    // Set the linker field appropriately.
+    if ($field_table == 'biomaterial') {
+      $linker_field = 'chado-biomaterial__taxon_id';
+    }
+    else {
+      $linker_field = 'chado-' . $field_table . '__organism_id';
+    }
+
     // Make sure the value is set to the organism_id
-    $organism_id = $form_state['values'][$field_name]['und'][0]['chado-' . $field_table . '__organism_id'];
+    $organism_id = $form_state['values'][$field_name]['und'][0][$linker_field];
     $form_state['values'][$field_name]['und'][0]['value'] = $organism_id;
   }
 }

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

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

+ 0 - 1
tripal_chado/includes/tripal_chado.field_storage.inc

@@ -43,7 +43,6 @@ function tripal_chado_field_storage_write($entity_type, $entity, $op, $fields) {
 
   // Convert the fields into a key/value list of fields and their values.
   $field_vals = tripal_chado_field_storage_write_merge_fields($fields, $entity_type, $entity);
-//dpm($field_vals);
 
   // First, write the record for the base table.  If we have a record id then
   // this is an update and we need to set the primary key.  If not, then this

+ 88 - 5
tripal_chado/includes/tripal_chado.fields.inc

@@ -82,6 +82,12 @@ function tripal_chado_bundle_fields_info_base(&$info, $details, $entity_type, $b
       continue;
     }
 
+    // The biosourceprovider_id and taxon_id are handled by custom fields.
+    if ($table_name == 'biomaterial' and (
+        $column_name == 'biosourceprovider_id' or $column_name == 'taxon_id')) {
+      continue;
+    }
+
     // Don't create base fields for the primary key and the type_id field.
     if ($column_name == $pkey or $column_name == $type_column) {
       continue;
@@ -165,6 +171,13 @@ function tripal_chado_bundle_fields_info_base(&$info, $details, $entity_type, $b
         break;
     }
 
+    // Set some defaults for biomaterial table
+    if ($table_name == 'biomaterial' and $column_name == 'name') {
+      $base_info['type'] = 'text';
+      $base_info['settings']['max_length'] = '2048';
+      $base_info['settings']['text_processing'] = 0;
+    }
+
     // Set some default semantic web information
     if ($column_name == 'uniquename') {
       $base_info['settings']['text_processing'] = 0;
@@ -213,7 +226,8 @@ function tripal_chado_bundle_fields_info_custom(&$info, $details, $entity_type,
 
   // BASE ORGANISM_ID
   if ($table_name != 'organism' and
-      array_key_exists('organism_id', $schema['fields'])) {
+      (array_key_exists('organism_id', $schema['fields']) or
+       array_key_exists('taxon_id', $schema['fields']))) {
     $field_name = 'obi__organism';
     $field_type = 'obi__organism';
     $info[$field_name] = array(
@@ -227,6 +241,20 @@ function tripal_chado_bundle_fields_info_custom(&$info, $details, $entity_type,
     );
   }
 
+  if ($table_name == 'biomaterial') {
+    $field_name = 'biomaterial__provider_id';
+    $field_type = 'local__contact';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'type' => $field_type,
+      'cardinality' => 1,
+      'locked' => FALSE,
+      'storage' => array(
+        'type' => 'field_chado_storage',
+      ),
+    );
+  }
+
   // BASE ORGANISM_ID
   if ($table_name == 'cvterm') {
     $field_name = 'sio__vocabulary';
@@ -751,6 +779,11 @@ function tripal_chado_bundle_instances_info_base(&$info, $entity_type, $bundle,
       continue;
     }
 
+    if ($table_name == 'biomaterial' and (
+        $column_name == 'biosourceprovider_id' or $column_name == 'taxon_id')) {
+      continue;
+    }
+
     $field_name = strtolower($cvterm->dbxref_id->db_id->name . '__' . preg_replace('/[^\w]/', '_', $cvterm->name));
     $field_name = substr($field_name, 0, 32);
 
@@ -870,6 +903,16 @@ function tripal_chado_bundle_instances_info_base(&$info, $entity_type, $bundle,
       $base_info['label'] = 'Description';
     }
     //
+    // BIOMATERIAL TABLE
+    //
+    if ($table_name == 'biomaterial' and $column_name == 'name') {
+      $base_info['widget'] = array();
+      $base_info['widget']['type'] = 'text_textfield';
+      unset($base_info['display']['default']['label']);
+      unset($base_info['settings']['text_processing']);
+      unset($base_info['settings']['format']);
+    }
+    //
     // FEATUREMAP TABLE
     //
     if ($table_name == 'featuremap' and $column_name == 'name') {
@@ -1021,11 +1064,19 @@ function tripal_chado_bundle_instances_info_custom(&$info, $entity_type, $bundle
   }
 
   // BASE ORGANISM_ID
-  if ($table_name != 'organism' and array_key_exists('organism_id', $schema['fields'])) {
+    if ($table_name != 'organism' and
+      (array_key_exists('organism_id', $schema['fields']) or
+       array_key_exists('taxon_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']) {
+    $table_column = 'organism_id';
+    if ($table_name == 'biomaterial') {
+      $is_required = FALSE;
+      $table_column = 'taxon_id';
+    }
+    elseif (array_key_exists('not null', $schema['fields']['organism_id']) and
+      $schema['fields']['organism_id']['not null']) {
       $is_required = TRUE;
     }
     $info[$field_name] =  array(
@@ -1038,7 +1089,7 @@ function tripal_chado_bundle_instances_info_custom(&$info, $entity_type, $bundle
       'settings' => array(
         'auto_attach' => TRUE,
         'chado_table' => $table_name,
-        'chado_column' => 'organism_id',
+        'chado_column' => $table_column,
         'base_table' => $table_name,
       ),
       'widget' => array(
@@ -1057,6 +1108,38 @@ function tripal_chado_bundle_instances_info_custom(&$info, $entity_type, $bundle
     );
   }
 
+  if ($table_name == 'biomaterial') {
+    $field_name = 'biomaterial__provider_id';
+    $field_type = 'local__contact';
+    $info[$field_name] = array(
+      'field_name' => $field_name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle->name,
+      'label' => 'Contact',
+      'description' => 'An indviddual or organization that serves as a contact for this record.',
+      'required' => FALSE,
+      'settings' => array(
+        'auto_attach' => FALSE,
+        'chado_table' => 'biomaterial',
+        'chado_column' => 'biosourceprovider_id',
+        'base_table' => 'biomaterial',
+      ),
+      'widget' => array(
+        'type' => 'local__contact_widget',
+        'settings' => array(
+          'display_label' => 1,
+        ),
+      ),
+      'display' => array(
+        'default' => array(
+          'label' => 'inline',
+          'type' => 'local__contact_formatter',
+          'settings' => array(),
+        ),
+      ),
+    );
+  }
+
   // BASE CVTERM
   if ($table_name == 'cvterm') {
     $field_name = 'sio__vocabulary';

+ 4 - 1
tripal_chado/includes/tripal_chado.semweb.inc

@@ -594,6 +594,7 @@ function tripal_chado_populate_vocab_OBI() {
     'definition' => 'A material entity that is an individual living system, such as animal, plant, bacteria or virus, that is capable of replicating or reproducing, growth and maintenance in the right environment. An organism may be unicellular or made up, like humans, of many billions of cells divided into specialized tissues and organs.',
   ));
   tripal_associate_chado_semweb_term(NULL, 'organism_id', $term);
+  tripal_associate_chado_semweb_term('biomaterial', 'taxon_id', $term);
 }
 
 /**
@@ -1348,7 +1349,7 @@ function tripal_chado_populate_vocab_LOCAL() {
   //--------------
   // Terms for Content Types
   //--------------
-  tripal_insert_cvterm(array(
+  $term = tripal_insert_cvterm(array(
     'id' => 'local:contact',
     'name' => 'contact',
     'definition' => 'An entity (e.g. individual or organization) through ' .
@@ -1356,6 +1357,8 @@ function tripal_chado_populate_vocab_LOCAL() {
     'influential people, and the like.',
     'cv_name' => 'local',
   ));
+  tripal_associate_chado_semweb_term('biomaterial', 'biosourceprovider_id', $term);
+
 
   tripal_insert_cvterm(array(
     'id' => 'local:relationship',

+ 28 - 0
tripal_chado/tripal_chado.install

@@ -1257,4 +1257,32 @@ function tripal_chado_update_7316() {
     $error = $e->getMessage();
     throw new DrupalUpdateException('Could not perform update: '. $error);
   }
+}
+
+/**
+ * Support for the biomaterial table.
+ */
+function tripal_chado_update_7317() {
+  try {
+    $term = tripal_insert_cvterm(array(
+      'id' => 'OBI:0100026',
+      'name' => 'organism',
+      'cv_name' => 'obi',
+      'definition' => 'A material entity that is an individual living system, such as animal, plant, bacteria or virus, that is capable of replicating or reproducing, growth and maintenance in the right environment. An organism may be unicellular or made up, like humans, of many billions of cells divided into specialized tissues and organs.',
+    ));
+    tripal_associate_chado_semweb_term('biomaterial', 'taxon_id', $term);
+    $term = tripal_insert_cvterm(array(
+      'id' => 'local:contact',
+      'name' => 'contact',
+      'definition' => 'An entity (e.g. individual or organization) through ' .
+      'whom a person can gain access to information, favors, ' .
+      'influential people, and the like.',
+      'cv_name' => 'local',
+    ));
+    tripal_associate_chado_semweb_term('biomaterial', 'biosourceprovider_id', $term);
+  }
+  catch (\PDOException $e) {
+    $error = $e->getMessage();
+    throw new DrupalUpdateException('Could not perform update: '. $error);
+  }
 }