Parcourir la source

TripalTerm & TripalVocab entities are now working.

Stephen Ficklin il y a 9 ans
Parent
commit
facf5d663e

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

@@ -60,69 +60,6 @@ function tripal_chado_entity_load($entities, $type) {
 
 }
 
-/**
- *
- * Implements hook_tripal_bundle_data_alter().
- */
-function tripal_chado_tripal_bundle_data_alter(&$bundle_data, $bundle_id, $cvterm) {
-
-  // Get the cvterm for this entity type.
-  $bundle_id = $entity->bundle;
-  $cvterm_id = preg_replace('/bio-data_/', $bundle_id);
-  $cvterm = tripal_get_cv(array('cvterm_id' => $cvterm_id));
-
-  // The organism table does not have a type_id so we won't ever find
-  // a record for it in the tripal_cv_defaults table.
-  if ($cvterm->name == 'organism') {
-    $bundle_data = array(
-      'cv_id' => $cvterm->cv_id->cv_id,
-      'cvterm_id' => $cvterm->cvterm_id,
-      'data_table' => 'organism',
-      'type_table' => 'organism',
-      'field' =>  '',
-    );
-  }
-  // The analysis table does not have a type_id so we won't ever find
-  // a record for it in the tripalcv_defaults table.
-  else if ($cvterm->name == 'analysis') {
-    $bundle_data = array(
-      'cv_id' => $cvterm->cv_id->cv_id,
-      'cvterm_id' => $cvterm->cvterm_id,
-      'data_table' => 'analysis',
-      'type_table' => 'analysis',
-      'field' =>  '',
-    );
-  }
-  else if ($cvterm->name == 'project') {
-    $bundle_data = array(
-      'cv_id' => $cvterm->cv_id->cv_id,
-      'cvterm_id' => $cvterm->cvterm_id,
-      'data_table' => 'project',
-      'type_table' => 'project',
-      'field' =>  '',
-    );
-  }
-  else {
-    // TODO: WHAT TO DO IF A VOCABULARY IS USED AS A DEFAULT FOR MULTIPLE
-    // TABLES.
-    // Look to see if this vocabulary is used as a default for any table.
-    $default = db_select('tripal_cv_defaults', 't')
-      ->fields('t')
-      ->condition('cv_id', $cvterm->cv_id->cv_id)
-      ->execute()
-      ->fetchObject();
-    if ($default) {
-      $bundle_data = array(
-        'cv_id' => $cvterm->cv_id->cv_id,
-        'cvterm_id' => $cvterm->cvterm_id,
-        'data_table' => $default->table_name,
-        'type_table' => $default->table_name,
-        'field' =>  $default->field_name,
-      );
-    }
-  }
-}
-
 /**
  *
  * Implements hook_entity_update().

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

@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Implements hook_field_storage_info().
  */

+ 3 - 3
tripal_chado/tripal_chado.install

@@ -50,7 +50,7 @@ function tripal_chado_install() {
   $error = '';
   $term = array('name' => 'organism', 'cv_id' => array('name' => 'local'));
   $cvterm = chado_generate_var('cvterm', $term);
-  if (!tripal_create_entity_type($cvterm, $error)) {
+  if (!tripal_create_bundle('local', 'organism', 'organism', $error)) {
     throw new Exception($error);
   }
 
@@ -58,7 +58,7 @@ function tripal_chado_install() {
   $error = '';
   $term = array('name' => 'analysis', 'cv_id' => array('name' => 'local'));
   $cvterm = chado_generate_var('cvterm', $term);
-  if (!tripal_create_entity_type($cvterm, $error)) {
+  if (!tripal_create_bundle('local', 'analysis', 'analysis', $error)) {
     throw new Exception($error);
   }
 
@@ -66,7 +66,7 @@ function tripal_chado_install() {
   $error = '';
   $term = array('name' => 'project', 'cv_id' => array('name' => 'local'));
   $cvterm = chado_generate_var('cvterm', $term);
-  if (!tripal_create_entity_type($cvterm, $error)) {
+  if (!tripal_create_bundle('local', 'project', 'project', $error)) {
     throw new Exception($error);
   }
 }

+ 80 - 16
tripal_chado/tripal_chado.module

@@ -1,6 +1,7 @@
 <?php
 
 require_once "api/tripal_chado.api.inc";
+require_once "includes/tripal_chado.term_storage.inc";
 require_once "includes/tripal_chado.field_storage.inc";
 
 /**
@@ -520,21 +521,93 @@ function tripal_chado_theme($existing, $type, $theme, $path) {
   );
 }
 
-
 /**
  * Implements hook_add_bundle_fields().
  *
- * @param $entity_type_name
+ * @param $entity_type
+ *   The entity type (e.g. TripalEntity).
  * @param $bundle_id
- * @param $cvterm
+ *   The bundle ID.
+ * @param $term
+ *   An instance of a TripalTerm object.
+ * @return
+ *   TRUE on success, FALSE on failure.
  */
-function tripal_chado_add_bundle_fields($entity_type_name, $bundle_id, $cvterm) {
+function tripal_chado_add_bundle_fields($entity_type, $bundle_id, $term) {
+
+  // This array will hold details that map the bundle to tables in Chado.
+  $bundle_data = array();
+
+  // Get the cvterm that corresponds to this TripalTerm object.
+  $vocab = entity_load('TripalVocab', array($term->vocab_id));
+  $vocab = reset($vocab);
+  $match = array(
+    'dbxref_id' => array(
+      'db_id' => array(
+        'name' => $vocab->namespace,
+      ),
+      'accession' => $term->term_id
+    ),
+  );
+  $cvterm = chado_generate_var('cvterm', $match);
+
+  // The organism table does not have a type_id so we won't ever find
+  // a record for it in the tripal_cv_defaults table.
+  if ($cvterm->name == 'organism') {
+    $bundle_data = array(
+      'cv_id' => $cvterm->cv_id->cv_id,
+      'cvterm_id' => $cvterm->cvterm_id,
+      'data_table' => 'organism',
+      'type_table' => 'organism',
+      'field' =>  '',
+    );
+  }
+  // The analysis table does not have a type_id so we won't ever find
+  // a record for it in the tripalcv_defaults table.
+  else if ($cvterm->name == 'analysis') {
+    $bundle_data = array(
+      'cv_id' => $cvterm->cv_id->cv_id,
+      'cvterm_id' => $cvterm->cvterm_id,
+      'data_table' => 'analysis',
+      'type_table' => 'analysis',
+      'field' =>  '',
+    );
+  }
+  else if ($cvterm->name == 'project') {
+    $bundle_data = array(
+      'cv_id' => $cvterm->cv_id->cv_id,
+      'cvterm_id' => $cvterm->cvterm_id,
+      'data_table' => 'project',
+      'type_table' => 'project',
+      'field' =>  '',
+    );
+  }
+  else {
+    // TODO: WHAT TO DO IF A VOCABULARY IS USED AS A DEFAULT FOR MULTIPLE
+    // TABLES.
+    // Look to see if this vocabulary is used as a default for any table.
+    $default = db_select('tripal_cv_defaults', 't')
+      ->fields('t')
+      ->condition('cv_id', $cvterm->cv_id->cv_id)
+      ->execute()
+      ->fetchObject();
+    if ($default) {
+      $bundle_data = array(
+        'cv_id' => $cvterm->cv_id->cv_id,
+        'cvterm_id' => $cvterm->cvterm_id,
+        'data_table' => $default->table_name,
+        'type_table' => $default->table_name,
+        'field' =>  $default->field_name,
+      );
+    }
+  }
+
   // Adds the fields for the base table to the entity.
-  tripal_chado_add_bundle_base_fields($entity_type_name, $bundle_id, $cvterm);
+  tripal_chado_add_bundle_base_fields($entity_type, $bundle_id, $bundle_data);
 
   // Check to see if there are any kv-property tables associated to this
   // base table. If so, add the fields for that type of table.
-  tripal_chado_add_bundle_kvproperty_adder_field($entity_type_name, $bundle_id, 'featureprop');
+  tripal_chado_add_bundle_kvproperty_adder_field($entity_type, $bundle_id, 'featureprop');
 }
 
 /**
@@ -564,16 +637,7 @@ function tripal_chado_add_bundle_kvproperty_adder_field($entity_type_name, $bund
 /**
  * Adds the fields for the base table to the entity.
  */
-function tripal_chado_add_bundle_base_fields($entity_type_name, $bundle_id, $cvterm) {
-
-  // Get the details for this bundle
-  $bundle = db_select('tripal_bundle', 't')
-    ->fields('t')
-    ->condition('type', 'TripalEntity')
-    ->condition('bundle', $bundle_id)
-    ->execute()
-    ->fetchObject();
-  $bundle_data = unserialize($bundle->data);
+function tripal_chado_add_bundle_base_fields($entity_type_name, $bundle_id, $bundle_data) {
 
   $table_name = $bundle_data['data_table'];
   $type_table = $bundle_data['type_table'];

+ 142 - 17
tripal_entities/api/tripal_entities.api.inc

@@ -1,11 +1,65 @@
 <?php
 
+/**
+ * Retrieves a TripalTerm entity that matches the given arguments.
+ *
+ * @param $namespace
+ *   The namespace for the vocabulary
+ * @param $term_id
+ *   The ID (accession) of the term in the vocabulary.
+ *
+ * @return
+ *   A TripalTerm entity object or NULL if not found.
+ */
+function tripal_load_term_entity($namespace, $term_id) {
+  $query = db_select('tripal_term', 'tt');
+  $query->join('tripal_vocab' ,'tv', 'tv.id = tt.vocab_id');
+  $query->fields('tt', array('id', 'term_id'))
+    ->fields('tv', array('namespace'))
+    ->condition('tv.namespace', $namespace)
+    ->condition('tt.term_id', $term_id);
+  $term = $query->execute()->fetchObject();
+
+  if ($term) {
+    $entity = entity_load('TripalTerm', array($term->id));
+    return reset($entity);
+  }
+  return NULL;
+}
+
+/**
+ * Retrieves a TripalVocab entity that maches the given arguments.
+ *
+ * @param $namespace
+ *
+ * @return
+ * A TripalVocab entity object or NULL if not found.
+ */
+function tripal_load_vocab_entity($namespace) {
+  $vocab = db_select('tripal_vocab', 'tv')
+    ->fields('tv')
+    ->condition('tv.namespace', $namespace)
+    ->execute()
+    ->fetchObject();
+
+  if ($vocab) {
+    $entity = entity_load('TripalVocab', array($vocab->id));
+    return reset($entity);
+  }
+  return NULL;
+}
 
 /**
  * Creates a new Tripal Entity type (i.e. bundle).
  *
- * @param $cvterm
- *  A cvterm object created using the tripal_get_cvterm() function.
+ * @param $namespace
+ *   The abbreviated namespace for the vocabulary (e.g. RO, SO, PATO).
+ * @param $term_id
+ *   The unique term ID in the vocabulary $namespace (i.e. an accession).
+ * @param $term_name
+ *   A human-readable name for this term.  This will became the name that
+ *   appears for the content type.  In practice, this should be the name
+ *   of the term. (E.g. the name for SO:0000704 is gene).
  * @param $error
  *  A string, passed by reference, that is filled with the error message
  *  if the function fails.
@@ -13,27 +67,34 @@
  * @return
  *  TRUE if the entity type (bundle) was succesfully created.  FALSE otherwise.
  */
-function tripal_create_entity_type($cvterm, &$error = '') {
+function tripal_create_bundle($namespace, $term_id, $term_name, &$error = '') {
 
-  $bundle_id = 'bio-data_' . $cvterm->cvterm_id;
+  // First create the TripalVocab if it doesn't already exist.
+  $vocab = tripal_load_vocab_entity($namespace);
+  if (!$vocab) {
+    $vocab = entity_get_controller('TripalVocab')->create(array('namespace' => $namespace));
+    $vocab->save();
+  }
+
+  // Next create the TripalTerm if it doesn't already exist.
+  $term = tripal_load_term_entity($namespace, $term_id);
+  if (!$term) {
+    $args = array('vocab_id' => $vocab->id, 'term_id' => $term_id, 'name' => $term_name);
+    $term = entity_get_controller('TripalTerm')->create($args);
+    $term = $term->save();
+  }
 
-  // Check to see if this bundle exists. If not then create it
-  $bundle = db_select('tripal_bundle', 't')
-    ->fields('t')
-    ->condition('type', 'TripalEntity')
-    ->condition('bundle', $bundle_id)
-    ->execute()
-    ->fetchObject();
 
-  if (!$bundle) {
+  // If the bundle doesn't already exist, then add it.
+  $bundle_id = 'bio-data_' . $term->id;
+  $einfo = entity_get_info('TripalEntity');
+  if (!in_array($bundle_id, array_keys($einfo['bundles']))) {
     // Inser the bundle.
     db_insert('tripal_bundle')
       ->fields(array(
-        'label' => $cvterm->name,
+        'label' => $term_name,
         'type' => 'TripalEntity',
         'bundle' => $bundle_id,
-        'data' => serialize($bundle_data),
-        'module' => 'tripal_entities'
       ))
       ->execute();
   }
@@ -47,7 +108,7 @@ function tripal_create_entity_type($cvterm, &$error = '') {
 
 
   // Allow modules to now add fields to the bundle
-  module_invoke_all('add_bundle_fields', 'TripalEntity', $bundle_id, $cvterm);
+  module_invoke_all('add_bundle_fields', 'TripalEntity', $bundle_id, $term);
 
   return TRUE;
 }
@@ -74,4 +135,68 @@ function hook_tripal_bundle_data_alter(&$bundle_data, $bundle_id, $cvterm) {
   $cvterm = tripal_get_cv(array('cvterm_id' => $cvterm_id));
 
   // Add any key/value pairs to the $bundle_data array as desired.
-}
+}
+
+/**
+ * A hook for specifying information about the data store for vocabularies.
+ *
+ * The storage backend for controlled vocabularies has traditionally been
+ * the Chado CV term tables. However, Tripal v3.0 introduces APIs for supporting
+ * other backends.  Therefore, this function indicates to Tripal which
+ * data stores are capable of providing support for terms.
+ *
+ * @return
+ *   An array describing the storage backends implemented by the module. The
+ *   keys are storage backend names. To avoid name clashes, storage
+ *   backend names should be prefixed with the name of the module that
+ *   exposes them. The values are arrays describing the storage backend,
+ *   with the following key/value pairs:
+ *
+ *   label: The human-readable name of the storage backend.
+ *   module:  The name of the module providing the support for this backend.
+ *   description: A short description for the storage backend.
+ *   settings: An array whose keys are the names of the settings available for
+ *     the storage backend, and whose values are the default values for
+ *     those settings.
+ */
+function hook_vocab_storage_info() {
+  return array(
+    'term_chado_storage' => array(
+      'label' => t('Chado storage'),
+      'description' => t('Integrates terms stored in the local Chado database with Tripal entities.'),
+      'settings' => array(),
+    ),
+  );
+}
+
+/**
+ * Creates a form for specifying a term for TripalEntity creation.
+ *
+ * This hook allows the module that implements a vocabulary storage backend
+ * to provide the form necessary to select a term that will then be used for
+ * creating a new TripalEntity type.  Tripal will expect that a 'namespace' and
+ * 'term_id' are in the $form_state['storage'] array. The 'namespace' and
+ * must be the abbreviated uppercase namespace for the vocabulary (e.g. 'RO',
+ * 'SO', 'PATO', etc.).  The 'term_id' must be the unique term ID (or
+ * accession) for the term in the vocabulary.
+ *
+ * @param $form
+ * @param $form_state
+ *
+ * @return
+ *   A form object.
+ */
+function hook_vocab_select_term_form(&$form, &$form_state) {
+
+  return $form;
+}
+/**
+ * Validates the hook_vocab_select_term_form().
+ *
+ * @param $name
+ */
+function hook_vocab_select_term_form_validate($form, &$form_state) {
+
+}
+
+

+ 1 - 1
tripal_entities/includes/TripalTerm.inc

@@ -4,7 +4,7 @@
  */
 class TripalTerm extends Entity {
   public function __construct($values = array()) {
-    parent::__construct($values, $entity_type);
+    parent::__construct($values, 'TripalTerm');
 
   }
 

+ 5 - 4
tripal_entities/includes/TripalTermController.inc

@@ -24,7 +24,7 @@ class TripalTermController extends EntityAPIController {
     $transaction = db_transaction();
     try {
       // Invoke hook_entity_delete().
-      module_invoke_all('entity_delete', $entity, $entity->type);
+      module_invoke_all('entity_delete', $entity, 'TripalTerm');
       field_attach_delete('TripalTerm', $entity);
 
       db_delete('tripal_term')
@@ -61,12 +61,13 @@ class TripalTermController extends EntityAPIController {
       }
 
       // Invoke hook_entity_presave().
-      module_invoke_all('entity_presave', $entity, $entity->type);
+      module_invoke_all('entity_presave', $entity, 'TripalTerm');
 
       // Write out the entity record.
       $record = array(
         'vocab_id' => $entity->vocab_id,
         'term_id' => $entity->term_id,
+        'name' => $entity->name,
         'created' => $entity->created,
         'changed' => time(),
       );
@@ -90,8 +91,8 @@ class TripalTermController extends EntityAPIController {
       }
 
       // Invoke either hook_entity_update() or hook_entity_insert().
-      module_invoke_all('entity_postsave', $entity, $entity->type);
-      module_invoke_all($invocation, $entity, $entity->type);
+      module_invoke_all('entity_postsave', $entity, 'TripalTerm');
+      module_invoke_all($invocation, $entity, 'TripalTerm');
 
       return $entity;
     }

+ 2 - 2
tripal_entities/includes/TripalVocab.inc

@@ -3,8 +3,8 @@
  * A class the controller will use for instantiating the TripalTerm entity.
  */
 class TripalVocab extends Entity {
-  public function __construct($values = array()) {
-    parent::__construct($values);
+  public function __construct($values = array(), $entity_type) {
+    parent::__construct($values, $entity_type);
 
   }
 

+ 9 - 8
tripal_entities/includes/TripalVocabController.inc

@@ -7,11 +7,12 @@
  */
 class TripalVocabController extends EntityAPIController {
 
-  public function __construct($entityType) {
-    parent::__construct($entityType);
+  public function __construct($entity_type) {
+    parent::__construct($entity_type);
   }
 
   public function create(array $values = array()) {
+    $this->namespace = array_key_exists('namespace', $values) ? $values['namespace'] : '';
     return parent::create($values);
   }
 
@@ -24,11 +25,11 @@ class TripalVocabController extends EntityAPIController {
     $transaction = db_transaction();
     try {
       // Invoke hook_entity_delete().
-      module_invoke_all('entity_delete', $entity, $entity->type);
+      module_invoke_all('entity_delete', $entity, 'TripalTerm');
       field_attach_delete('TripalVocab', $entity);
 
       db_delete('tripal_term')
-        ->condition('term_id', $entity->term_id)
+        ->condition('id', $entity->id)
         ->execute();
     }
     catch (Exception $e) {
@@ -61,7 +62,7 @@ class TripalVocabController extends EntityAPIController {
       }
 
       // Invoke hook_entity_presave().
-      module_invoke_all('entity_presave', $entity, $entity->type);
+      module_invoke_all('entity_presave', $entity, 'TripalTerm');
 
       // Write out the entity record.
       $record = array(
@@ -89,10 +90,10 @@ class TripalVocabController extends EntityAPIController {
       }
 
       // Invoke either hook_entity_update() or hook_entity_insert().
-      module_invoke_all('entity_postsave', $entity, $entity->type);
-      module_invoke_all($invocation, $entity, $entity->type);
+      module_invoke_all('entity_postsave', $entity, 'TripalTerm');
+      module_invoke_all($invocation, $entity, 'TripalTerm');
 
-      return $entity;
+      return $record;
     }
     catch (Exception $e) {
       $transaction->rollback();

+ 42 - 130
tripal_entities/includes/tripal_entities.admin.inc

@@ -41,7 +41,7 @@ function tripal_entities_content_overview_form($form, &$form_state) {
   // This will return the 25 most recently created entities.
   $entities = db_select('tripal_entity', 'td')
     ->fields('td')
-    ->orderBy('created', 'DESC')//ORDER BY created
+    ->orderBy('created', 'DESC')
     ->range(0,25)
     ->execute();
 
@@ -103,160 +103,72 @@ function tripal_entities_content_overview_form($form, &$form_state) {
  * Form for creating tripal data types.
  *
  * This form is available on the menu at Admin >> Structure >> Biological Data
- * Types
+ * Types. It requires that a module implmennt the vocabulary storage.  Tripal
+ * knows which vocabulary storage methods are available when a module
+ * implements the hook_vocab_storage_info() hook.
  *
- * @param array $form
- * @param array $form_state
- *
- * @return
- *    An array describing this form to the Form API.
  */
 function tripal_entities_admin_add_type_form($form, &$form_state) {
-  $term_name = '';
-  $num_terms = 0;
-  $cv_id = '';
 
-  // Set defaults using the form state.
-  if (array_key_exists('input', $form_state)) {
-    if (array_key_exists('term_name', $form_state['input'])) {
-      $term_name = $form_state['input']['term_name'];
-    }
-    if (array_key_exists('cv_id', $form_state['input'])) {
-      $cv_id = $form_state['input']['cv_id'];
-    }
-
-    // If a term and cv_id are provided then we can look for the term using
-    // both and we should find a unique term. If only ther term is provided
-    // we can still look for a unique term but there must only be one.
-    if ($term_name and !$cv_id) {
-      $match = array(
-        'name' => $term_name,
-      );
-    }
-    else {
-      $match = array(
-        'name' => $term_name,
-        'cv_id' => $cv_id,
-      );
+  // TODO: we need some sort of administrative interface that lets the user
+  // switch to the desired vocabulary type. For now, we'll just use the
+  // first one in the list.
+  $stores = module_invoke_all('vocab_storage_info');
+  if (is_array($stores) and count($stores) > 0) {
+    $keys = array_keys($stores);
+    $module = $stores[$keys[0]]['module'];
+    $function = $module . '_vocab_select_term_form';
+    if (function_exists($function)) {
+      $form = $function($form, $form_state);
     }
-
-    $terms = tripal_get_cvterm($match, array('return_array' => TRUE));
-    $num_terms = count($terms);
-  }
-
-  // If no term has been selected yet then provide the auto complete field.
-  if ($num_terms == 0) {
-    $form['term_name'] = array(
-      '#title'       => t('Content Type'),
-      '#type'        => 'textfield',
-      '#description' => t("The content type must be the name of a term in
-          a controlled vocabulary and the controlled vocabulary should
-          already be loaded into Tripal.  For example, to create a content
-          type for storing 'genes', use the 'gene' term from the
-          Sequence Ontology (SO)."),
-      '#required'    => TRUE,
-      '#default_value' => $term_name,
-      '#autocomplete_path' => "admin/tripal/vocab/cvterm/auto_name/$cv_id",
-    );
   }
   else {
-    $form['term_name'] = array(
-      '#type' => 'hidden',
-      '#value' => $term_name,
-    );
-  }
-
-  // If the term belongs to more than one vocabulary then add additional fields
-  // to let the user select the vocabulary.
-  if ($num_terms > 1) {
-    $cvs = array();
-    foreach ($terms as $term) {
-      $cvs[$term->cv_id->cv_id] = 'Vocabulary: <b>' . $term->cv_id->name . '</b> (' . $term->cv_id->definition . ')<br>' . $term->name . ': ' . $term->definition;
-    }
-    $form['cv_id'] = array(
-      '#type' => 'radios',
-      '#title' => t('Select the appropriate vocabulary'),
-      '#options' => $cvs,
-    );
+    tripal_set_message('A storage backend is not enabled for managing
+          the vocabulary terms used to create content.  Please enable
+          a module that supports storage of vocabualary terms (e.g. tripal_chado)
+          and return to create new Tripal content types.', TRIPAL_NOTICE);
   }
-
-  // Add in the button for the cases of no terms or too many.
-  $form['select_button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Use this term'),
-    '#name' => 'select_cvterm'
-  );
-
   return $form;
 }
-
 /**
- * Implements hook_validate() for the tripal_entities_admin_publish_form.
+ * Implements hook_validate() for the tripal_entities_admin_add_type_form.
  *
  */
 function tripal_entities_admin_add_type_form_validate($form, &$form_state) {
-
-  if (array_key_exists('clicked_button', $form_state) and
-      $form_state['clicked_button']['#name'] =='select_cvterm') {
-
-    // First, make sure the term is unique. If not then we can't check it.
-    $term_name = NULL;
-    $cv_id = NULL;
-    $cvterm = NULL;
-    if (array_key_exists('term_name', $form_state['values'])) {
-      $term_name = $form_state['input']['term_name'];
-    }
-    if (array_key_exists('cv_id', $form_state['input'])) {
-      $cv_id = $form_state['input']['cv_id'];
-    }
-
-    // If a term and cv_id are provided then we can look for the term using
-    // both and we should find a unique term. If only ther term is provided
-    // we can still look for a unique term but there must only be one.
-    if ($term_name and !$cv_id) {
-      $match = array(
-        'name' => $term_name,
-      );
-    }
-    else {
-      $match = array(
-        'name' => $term_name,
-        'cv_id' => $cv_id,
-      );
-    }
-    $terms = tripal_get_cvterm($match, array('return_array' => TRUE));
-    $form_state['storage']['terms'] = $terms;
-
-    // If we do not have any terms then the term provided by the user does not
-    // exists and we need to provide an error message.
-    if (count($terms) == 0) {
-      form_set_error('term_name', t('The term does not exist in this database.'));
-    }
-    // If we have more than one term then we need to set an error so that the
-    // form can provide a list of vocabularies to select from.
-    if (count($terms) > 1) {
-      form_set_error('term_name', t('The term is not unique. A list of vocabularies
-          that contain this term. Please select the most appropriate vocabulary.'));
+  // TODO: we need some sort of administrative interface that lets the user
+  // switch to the desired vocabulary type. For now, we'll just use the
+  // first one in the list.
+  $stores = module_invoke_all('vocab_storage_info');
+  if (is_array($stores) and count($stores) > 0) {
+    $keys = array_keys($stores);
+    $module = $stores[$keys[0]]['module'];
+    $function = $module . '_vocab_select_term_form_validate';
+    if (function_exists($function)) {
+      $function($form, $form_state);
     }
   }
 }
 /**
- * Implements hook_submit() for the tripal_entities_admin_publish_form.
+ * Implements hook_submit() for the tripal_entities_admin_add_type_form.
+ *
+ * The storage backend must set the
  *
  */
 function tripal_entities_admin_add_type_form_submit($form, &$form_state) {
-
-  if ($form_state['clicked_button']['#name'] =='select_cvterm') {
-    $cvterm = $form_state['storage']['terms'][0];
-
-    $bundle_id = 'bio-data_' . $cvterm->cvterm_id;
+  $namespace = '';
+  $term_id = '';
+  if (array_key_exists('storage', $form_state)) {
+    $storage = $form_state['storage'];
+    $namespace = array_key_exists('namespace', $storage) ? $storage['namespace'] : '';
+    $term_id = array_key_exists('term_id', $storage) ? $storage['term_id'] : '';
+    $term_name = array_key_exists('term_name', $storage) ? $storage['term_name'] : '';
 
     // Before we try to add this type, check to see if it already exists
     // as a bundle.
-    $einfo = entity_get_info('TripalEntity');
-    if (!in_array($bundle_id, array_keys($einfo['bundles']))) {
+    $term = tripal_load_term_entity($namespace, $term_id);
+    if (!$term) {
       $error = '';
-      $success = tripal_create_entity_type($cvterm, $error);
+      $success = tripal_create_bundle($namespace, $term_id, $term_name, $error);
       if (!$success) {
         drupal_set_message($error, 'error');
         $form_state['redirect'] = "admin/structure/bio-data";

+ 7 - 0
tripal_entities/tripal_entities.install

@@ -186,6 +186,13 @@ function tripal_entities_tripal_term_schema() {
         'not null' => TRUE,
         'default' => '',
       ),
+      'name' => array(
+        'description' => 'The human readable name for this term.',
+        'type' => 'varchar',
+        'length' => 1024,
+        'not null' => TRUE,
+        'default' => '',
+      ),
       'created' => array(
         'description' => 'The Unix timestamp when the entity was created.',
         'type' => 'int',

+ 10 - 1
tripal_entities/tripal_entities.module

@@ -31,9 +31,18 @@ function tripal_entities_menu() {
   // Entity's UI Controller class.
 
   $items = array();
+
+  $items['admin/structure/bio-data/term/%'] = array(
+    'page callback' => 'tripal_autocomplete_term',
+    'page arguments' => array(6, 7),
+    'access arguments' => array('administer content'),
+    'type' => MENU_CALLBACK,
+  );
+
   return $items;
 }
 
+
 /**
  * Implements hook_admin_paths().
  * Define administrative paths.
@@ -220,7 +229,7 @@ function tripal_entities_entity_info() {
     'controller class' => 'TripalVocabController',
 
     // The table for this entity defined in hook_schema()
-    'base table' => 'tripal_vocabulary',
+    'base table' => 'tripal_vocab',
 
     // If fieldable == FALSE, we can't attach fields.
     'fieldable' => TRUE,