Browse Source

Tripal Views: Polished the API doc including moving some functions into a new tripal_views_integration.inc include file.

Lacey Sanderson 11 years ago
parent
commit
a1f414b6ad

+ 311 - 295
tripal_views/api/tripal_views.api.inc

@@ -8,12 +8,280 @@
  * @defgroup tripal_views_api Tripal Views Module API
  * @ingroup tripal_api
  * @{
- * Provides functions for Tripal Views Integrations
+ * Provides functions to help extension modules add their own tripal views integrations
+ * as well as functions for managing default views.
+ *
+ * Managing Default Views:
+ *
+ * When you create administrative default views (or really any default view) you really
+ * have no way to ensure that the site administrator keeps these views enabled. In some
+ * cases this is a good thing and provides the site administrator the ability to disable
+ * views that don't apply to their particular installation or to replace your default view
+ * with a custom view of their own. But in other cases, particularily for administration
+ * views, you want to gaurd against accidental disabling of your views.
+ *
+ * One way to do this is to add a landing page using a heook_menu() definition to a custom
+ * callback returning HTML. You can use this page to render the view if it is enabled but
+ * provide logic to display a message if the view is disabled. Furthermore, it's often
+ * helpful to provide a link allowing site administrators to enable the view from your
+ * page rather than expecting them to go to the views administration UI. This is done for
+ * all the administration views provided by Tripal. The following is an example of how to
+ * achomplish this functionality for your own module:
+ * @code
+function mymodule_menu() {
+  $items = array();
+
+  // Create the landing page
+  $items['admin/tripal/<PATH-TO-YOUR-LANDING-PAGE>'] = array(
+    'title' => 'MyModule Administration',
+    'description' => 'Administration of my module.',
+    'page callback' => 'mymodule_admin_landing_page',
+    'access arguments' => array('<YOUR-PERMISSION-KEY>'),
+    'type' => MENU_NORMAL_ITEM,
+  );
+
+  // Create one of these for each of your default views
+  $items['admin/tripal/<PATH-TO-YOUR-ADMIN-SECTION>/views/<VIEW-MACHINE-NAME>/enable'] = array(
+    'title' => 'Enable <VIEW-HUMAN-READABLE-NAME>',
+    'page callback' => 'tripal_views_admin_enable_view',
+    'page arguments' => array('<VIEW-MACHINE-NAME>', '<PATH-TO-REDIRECT-TO-AFTERWARDS>'),
+    'access arguments' => array('<YOUR-PERMISSION-KEY>'),
+    'type' => MENU_CALLBACK,
+  );
+
+  return $items;
+}
+
+function mymodule_admin_landing_page() {
+
+  // Get the View Embed Code
+  // This function will return FALSE if your view is not enabled
+  $view_code = views_embed_view('<VIEW-MACHINE-NAME>', '<DISPLAY-MACHINE-NAME');
+  // If your view is enabled then embed it in this page by returning the embed code
+  if (isset($view_code)) {
+    $output .= $view_code;
+  }
+  else {
+    // Provide the landing page with links to the menu item created in hook_menu to
+    // to enable your view
+    $output .= '<p>The My Module module uses primarily views to provide an '
+      . 'administrative interface. Currently one or more views needed for this '
+      . 'administrative interface are disabled. <strong>Click each of the following links to '
+      . 'enable the pertinent views</strong>:</p>';
+    $output .= '<ul>';
+    // NOTE: <URL-FROM-MENU-TO-ENABLE-VIEW> is
+    // admin/tripal/<PATH-TO-YOUR-ADMIN-SECTION>/views/<VIEW-MACHINE-NAME>/enable
+    // from above hook_menu().
+    $output .= '<li>' . l('<VIEW-HUMAN-RADABLE-NAME>', '<URL-FROM-MENU-TO-ENABLE-VIEW>') . '</li>';
+    $output .= '</ul>';
+  }
+
+  return $output;
+}
+
+ * @endcode
+ *
+ * Adding your own Tripal Views Integrations:
+ *
+ * One of the main ways the Tripal View API is likely to be used is if your module needs
+ * to create it's own tripal views integration. You might need to do this for any number of
+ * reasons but the following examples are thought to be the most common:
+ *   1) Your module wants to add handlers with better functionality to fields it has more
+ *       knowledge of than the general integration for all tables
+ * @code
+ mymodule_views_data() {
+
+  // First check that your integration has not already been added
+  // When selecting a priority, do not choose -10 or -9 and make sure it is below 0
+  // so that individual sites still have the ability to override it, if needed
+  $table_name = 'my_chado_table';
+  $priority = -5;
+  if (!tripal_views_is_integrated($table_name, $priority)) {
+
+    // If you really only need to tweak an existing integration you can clone it
+    // If you want to clone the integration that is currently taking priority
+    // then use tripal_views_get_table_lightest_priority() as below
+    $lightest_priority = tripal_views_get_table_lightest_priority($table_name);
+    $setup_id = tripal_views_clone_integration($table_name, $priority, $lightest_priority);
+
+    // And then make a few changes
+    // First get the definition array created via the clone above
+    $defn_array = tripal_views_integration_export_entry($setup_id);
+
+    // Then make some changes to the array here
+
+    // And finally save the changes to the integration
+    tripal_views_integration_update_entry($setup_id, $defn_array);
+
+  }
+
+}
+ * @endcode
+ *   2) Your module creates a chado table that is not already integrated.
+ * @code
+mymodule_views_data() {
+
+  // First check that your integration has not already been added
+  // When selecting a priority, do not choose 10 or 9 and make sure it is below 0
+  // so that individual sites still have the ability to override it, if needed
+  $table_name = 'my_chado_table';
+  $priority = 5;
+  if (!tripal_views_is_integrated($table_name, $priority)) {
+
+    // Describe your table using a large array as specified by tripal_views_integration_add_entry().
+    $defn_array = array(
+      'table' => $table_name, //tablename or materialized view name
+      'name' => 'My Chado Table', // Human readable name
+      'type' => 'chado', //either chado or mview depending on tablename
+      'description' => 'Create a listing from my chado table.', //description seen when creating a view of this type
+      'priority' => $priority, //For Base tripal modules: 10; custom modules: 9 to 0;
+      'base_table' => TRUE //either TRUE or FALSE depending on whether the current table should show up in the add view list
+      'fields' => array(
+        'feature_id' => array(
+          'name' => 'feature_id', //field name in database
+          'title' => 'Feature ID', //human-readable name -seen in Views UI
+          'description' => 'This is the unique identifier for features', //help/description seen in Views UI
+          'type' => 'int', // the type of field
+          'handlers' => array(  //possible keys are field, filter, sort, argument, relationship
+            'field' => array(
+              'name' => 'chado_views_handler_numeric' //name of handler
+            ),
+            'filter' => array( ... ),
+            ...
+          ),
+          'join' => array( //describe a table that joins to this one via this field
+            'table' => 'featureprop', //table to join to
+            'field' => 'feature_id', //field in above table (featureprop)
+            'handler' => 'views_handler_join_chado_aggregator', //handler to use
+          ),
+        )
+      ),
+    );
+    // Actually create the entry
+    tripal_views_integration_add_entry($defn_array);
+
+  }
+
+}
+ * @endcode
  * @}
  */
 
 /**
- * Retrieve the priority of the lightest priority for a given table
+ * Programatically enable view
+ *
+ * This should be used in a hook_menu definition as the callback to provide a link
+ * to enable the view (first example). It can also be called directly if needed (second example).
+ * @code
+// Create a URL that when the user navigates there, a given view will be enabled.
+// You will still need to provide a link to this menu item somewhere appropriate (ie: an admin landing page).
+function mymodule_menu() {
+  $items = array();
+
+  // Create one of these for each of your default views
+  $items['admin/tripal/<PATH-TO-YOUR-ADMIN-SECTION>/views/<VIEW-MACHINE-NAME>/enable'] = array(
+    'title' => 'Enable <VIEW-HUMAN-READABLE-NAME>',
+    'page callback' => 'tripal_views_admin_enable_view',
+    'page arguments' => array('<VIEW-MACHINE-NAME>', '<PATH-TO-REDIRECT-TO-AFTERWARDS>'),
+    'access arguments' => array('<YOUR-PERMISSION-KEY>'),
+    'type' => MENU_CALLBACK,
+  );
+
+  return $items;
+}
+
+// Call this function directly to disable a view
+// The example shows enabling your own default view when your module is enabled.
+// This might be useful if you disable your view when your module is disabled.
+function mymodule_enable() {
+
+  $view_name = '<VIEW-MACHINE-NAME>';
+  tripal_views_admin_enable_view($view_name);
+
+}
+ * @endcode
+ *
+ * @param $view_name
+ *   The machine-name of the view to be enabled
+ * @param $redirect_link
+ *   The path to redirect to. FALSE if no redirect needed
+ *
+ * @ingroup tripal_views_api
+ */
+function tripal_views_admin_enable_view($view_name, $redirect_link = FALSE) {
+
+  $status = variable_get('views_defaults', array());
+  if (isset($status[$view_name])) {
+    $status[$view_name] = FALSE;
+    variable_set('views_defaults', $status);
+    drupal_set_message("Successfully Enabled $view_name");
+  }
+  else {
+    drupal_set_message("Unable to find a view by the name of '$view_name'. Unable to enable this view.",'error');
+  }
+  if ($redirect_link) {
+    drupal_goto($redirect_link);
+  }
+}
+
+/**
+ * Programatically disable view.
+ *
+ * This should be used in a hook_menu definition as the callback to provide a link
+ * to disable the view (first example). It can also be called directly if needed (second example).
+ * @code
+// Create a URL that when the user navigates there, a given view will be disabled.
+// You will still need to provide a link to this menu item somewhere appropriate.
+function mymodule_menu() {
+  $items = array();
+
+  // Create one of these for each of your default views
+  $items['admin/tripal/<PATH-TO-YOUR-ADMIN-SECTION>/views/<VIEW-MACHINE-NAME>/disable'] = array(
+    'title' => 'Disable <VIEW-HUMAN-READABLE-NAME>',
+    'page callback' => 'tripal_views_admin_disable_view',
+    'page arguments' => array('<VIEW-MACHINE-NAME>', '<PATH-TO-REDIRECT-TO-AFTERWARDS>'),
+    'access arguments' => array('<YOUR-PERMISSION-KEY>'),
+    'type' => MENU_CALLBACK,
+  );
+
+  return $items;
+}
+
+// Call this function directly to disable a view
+// The example shows disabling your own default view when your module is uninstalled
+function mymodule_uninstall() {
+
+  $view_name = '<VIEW-MACHINE-NAME>';
+  tripal_views_admin_disable_view($view_name);
+
+}
+ * @endcode
+ *
+ * @param $view_name
+ *   The machine-name of the view to be enabled
+ * @param $redirect_link
+ *   The path to redirect to. FALSE if no redirect needed
+ *
+ * @ingroup tripal_views_api
+ */
+function tripal_views_admin_disable_view($view_name, $redirect_link = FALSE) {
+
+  $status = variable_get('views_defaults', array());
+  if (isset($status[$view_name])) {
+    $status[$view_name] = TRUE;
+    variable_set('views_defaults', $status);
+    drupal_set_message("Disabled $view_name");
+  }
+  else {
+    drupal_set_message("Unable to find a view by the name of '$view_name'. Unable to disable this view.",'error');
+  }
+  if ($redirect_link) {
+    drupal_goto($redirect_link);
+  }
+}
+
+/**
+ * Retrieve the priority of the lightest priority for a given table.
  *
  * NOTE: Uses lightest priority (drupal-style) where the range is from -10 to 10
  * and -10 is of highest priority.
@@ -44,7 +312,7 @@ function tripal_views_get_table_lightest_priority($table_name) {
 }
 
 /**
- * Retrieve the views integration setup with the lightest priority for a given table
+ * Retrieve the views integration setup_id with the lightest priority for a given table
  *
  * NOTE: Uses lightest priority (drupal-style) where the range is from -10 to 10
  * and -10 is of highest priority.
@@ -73,7 +341,7 @@ function tripal_views_get_lightest_priority_setup($table_name) {
 }
 
 /**
- * Retrieve the views integration setup with the given priority/table combination
+ * Retrieve the views integration setup_id with the given priority/table combination.
  *
  * @param $table_name
  *   The name of the table to retrieve the setup ID for. This can be either a materialized
@@ -101,7 +369,7 @@ function tripal_views_get_setup_id($table_name, $priority) {
 }
 
 /**
- * Check to see if this table already has an integration record with the given priority
+ * Check to see if this table already has an integration record with the given priority.
  *
  * @param $table_name
  *   The name of the table to check for integration
@@ -138,7 +406,8 @@ function tripal_views_is_integrated($table_name, $priority = NULL) {
 }
 
 /**
- * Checks if you are dealing with the lightest priority setup for a given table
+ * Checks if you are dealing with the lightest priority setup for a given table. This is a
+ * good way to determine whether your modules integration is being used by views.
  *
  * @param $setup_id
  *   The ID of the setup to check (is this setup the lightest one?)
@@ -162,75 +431,13 @@ function tripal_views_is_lightest_priority_setup($setup_id, $table_name) {
 }
 
 /**
- * Programatically enable view
+ * Rebuilds all the default integrations.
  *
- * @param $view_name
- *   The machine-name of the view to be enabled
- * @param $redirect_link
- *   The path to redirect to. FALSE if no redirect needed
- *
- * @ingroup tripal_views_api
- */
-function tripal_views_admin_enable_view($view_name, $redirect_link = FALSE) {
-
-  $status = variable_get('views_defaults', array());
-  if (isset($status[$view_name])) {
-    $status[$view_name] = FALSE;
-    variable_set('views_defaults', $status);
-    drupal_set_message("Successfully Enabled $view_name");
-  }
-  else {
-    drupal_set_message("Unable to find a view by the name of '$view_name'. Unable to enable this view.",'error');
-  }
-  if ($redirect_link) {
-    drupal_goto($redirect_link);
-  }
-}
-
-/**
- * Programatically disable view
- *
- * @param $view_name
- *   The machine-name of the view to be enabled
- * @param $redirect_link
- *   The path to redirect to. FALSE if no redirect needed
- *
- * @ingroup tripal_views_api
- */
-function tripal_views_admin_disable_view($view_name, $redirect_link = FALSE) {
-
-  $status = variable_get('views_defaults', array());
-  if (isset($status[$view_name])) {
-    $status[$view_name] = TRUE;
-    variable_set('views_defaults', $status);
-    drupal_set_message("Disabled $view_name");
-  }
-  else {
-    drupal_set_message("Unable to find a view by the name of '$view_name'. Unable to disable this view.",'error');
-  }
-  if ($redirect_link) {
-    drupal_goto($redirect_link);
-  }
-}
-
-/**
- * Purpose: Deletes ALL Tripal Views Integrations.
- *
- * @ingroup tripal_views_api
- */
-function tripal_views_delete_all_integrations() {
-
-  db_query("DELETE FROM {tripal_views}");
-  db_query("DELETE FROM {tripal_views_field}");
-  db_query("DELETE FROM {tripal_views_handlers}");
-  db_query("DELETE FROM {tripal_views_join}");
-
-  drupal_set_message("Successfully deleted all views integration.");
-
-}
-
-/**
- * Rebuilds all the default integrations
+ * This essentially clears the cache in case you mess up the integrations in your site.
+ * This should not be used during module development since it really only rebuilds the
+ * integrations described by all enabled modules in the site and if $delete_first is
+ * TRUE it can delete custom integrations created by site administrators which will not
+ * make your module popular.
  *
  * @param $delete_first
  *   If TRUE then all integrations are first deleted.
@@ -248,7 +455,12 @@ function tripal_views_rebuild_views_integrations($delete_first = FALSE) {
 }
 
 /**
- * Add views integration records into the tripal_views* tables
+ * Add views integration records into the tripal_views* tables.
+ *
+ * This is the programatic way to add your own integrations to the tripal views integrations
+ * list. Keep in mind that the priority set in your $defn_array needs to be lighter than
+ * any existing integrations to be used by views and that it should still be below 0
+ * in order to allow site administrators to override it should they need to.
  *
  * @param $defn_array
  *   An array describing the structure and fields of the table
@@ -473,7 +685,12 @@ function tripal_views_integration_add_entry($defn_array) {
 }
 
 /**
- * Export Views integration records
+ * Export Views integration records.
+ *
+ * This is a great way to create your own integration since it returns an already defined
+ * integration in array form that you can modify. After modifications simply set the
+ * priority to something lighter (but still below 0) than any existing integrations
+ * and use tripal_views_integration_add_entry() to add it to the list of integrations.
  *
  * @param $setup_id
  *   The unique setup id of the tripal views integration
@@ -537,7 +754,13 @@ function tripal_views_integration_export_entry($setup_id) {
 }
 
 /**
- * Removes a View Integration Entry
+ * Removes a View Integration Entry when you only know the table the integration was
+ * created for and the priority.
+ *
+ * This should only be used to remove integrations created by your own module (possibly
+ * on uninstall of your module). To override existing integrations simply create your own
+ * integration with a lighter priority using tripal_views_clone_integration() or
+ * tripal_views_integration_export_entry() to create a template.
  *
  * @param $table_name
  *   The name of the table to remove a views integration entry for
@@ -571,7 +794,12 @@ function tripal_views_integration_remove_entry_by_table_name($table_name, $prior
 }
 
 /**
- * Removes a View Integration Entry
+ * Removes a View Integration Entry when you know the setup_id
+ *
+ * This should only be used to remove integrations created by your own module (possibly
+ * on uninstall of your module). To override existing integrations simply create your own
+ * integration with a lighter priority using tripal_views_clone_integration() or
+ * tripal_views_integration_export_entry() to create a template.
  *
  * @param $setup_id
  *   The setup ID of the views integration entry to remove
@@ -589,222 +817,9 @@ function tripal_views_integration_remove_entry_by_setup_id($setup_id) {
 }
 
 /**
- * Integrate all chado tables in the schema api.  This integration only occurs
- * once and sets all Chado tables to a priority of 10
- *
- * @ingroup tripal_views_api
- */
-function tripal_views_integrate_all_chado_tables() {
-
-  $tables = chado_get_table_names(TRUE);
-
-  $base_tables = array(
-    'acquisition', 'analysis', 'assay', 'biomaterial', 'contact', 'cv', 'cvterm',
-    'db', 'dbxref', 'environment', 'expression', 'feature', 'featuremap', 'genotype',
-    'library', 'nd_experiment', 'nd_geolocation', 'nd_protocol', 'nd_reagent',
-    'organism', 'phendesc', 'phenotype', 'phenstatement', 'phylonode', 'phylotree',
-    'project', 'protocol', 'pub', 'stock', 'study', 'synonym'
-  );
-
-  foreach ($tables as $tablename) {
-
-    $priority = 10;
-    if (!tripal_views_is_integrated($tablename, $priority)) {
-      if (in_array($tablename, $base_tables)) {
-        $table_integration_array = tripal_views_get_integration_array_for_chado_table($tablename, TRUE, $priority);
-      }
-      else {
-        $table_integration_array = tripal_views_get_integration_array_for_chado_table($tablename, FALSE, $priority);
-      }
-      if ($table_integration_array) {
-        tripal_views_integration_add_entry($table_integration_array);
-      }
-    }
-  }
-}
-
-/**
- * Returns the array needed to integrate a given chado table with views
- *
- * @param $tablename
- *   The table to generate the tripal views integration array for
- * @return
- *   The tripal views integration array which is the parameter for
- *   tripal_views_integration_add_entry($defn_array)
- *
- * @ingroup tripal_views_api
- */
-function tripal_views_get_integration_array_for_chado_table($table_name, $base_table = TRUE, $priority = 9) {
-
-  // Get the schema for this table (via the chado schema api)
-  $schema = chado_get_schema($table_name);
-
-  // Base definition array
-  $defn_array = array(
-    'table' => $table_name,
-    'type' => 'chado',
-    'name' => 'Chado ' . ucwords(str_replace('_', ' ', $table_name)),
-    'description' => (!empty($schema['description'])) ? $schema['description'] : ' ',
-    'priority' => $priority,
-    'base_table' => $base_table,
-    'fields' => array(),
-  );
-  // Add fields
-  if (!isset($schema['fields'])) {
-    tripal_report_error('tripal_views', TRIPAL_NOTICE,
-      'There are no fields defined for %table in the Chado Schema API.', array('%table' => $table_name));
-    return FALSE;
-  }
-  foreach ($schema['fields'] as $field_name => $field_schema) {
-
-    // Base field definition
-    if (!empty($field_name) && !empty($field_schema['type'])) {
-      $defn_array['fields'][$field_name] = array(
-        'name' => $field_name,
-        'title' => ucwords(str_replace('_', ' ', $field_name)),
-        'type' => $field_schema['type'],
-        'description' => (isset($field_schema['description'])) ? $field_schema['description'] : ucwords(str_replace('_', ' ', $field_name)),
-        'handlers' => array(),
-        'joins' => array()
-      );
-
-      // Add handlers based on type
-      if (preg_match('/^int/', $field_schema['type'])) {
-        $defn_array['fields'][$field_name]['handlers'] = array(
-          /** D6
-          'field' => array('name' => 'chado_views_handler_field_numeric'),
-          'filter' => array('name' => 'chado_views_handler_filter_numeric'),
-          'sort' => array('name' => 'chado_views_handler_sort'),
-          */
-          'field' => array('name' => 'views_handler_field_numeric'),
-          'filter' => array('name' => 'views_handler_filter_numeric'),
-          'sort' => array('name' => 'views_handler_sort'),
-        );
-      }
-      elseif (preg_match('/^serial/', $field_schema['type'])) {
-        $defn_array['fields'][$field_name]['handlers'] = array(
-          /** D6
-          'field' => array('name' => 'chado_views_handler_field_numeric'),
-          'filter' => array('name' => 'chado_views_handler_filter_numeric'),
-          'sort' => array('name' => 'chado_views_handler_sort'),
-          */
-          'field' => array('name' => 'views_handler_field_numeric'),
-          'filter' => array('name' => 'views_handler_filter_numeric'),
-          'sort' => array('name' => 'views_handler_sort'),
-        );
-        $defn_array['fields'][$field_name]['type'] = 'int';
-      }
-      elseif (preg_match('/^varchar/', $field_schema['type'])) {
-        $defn_array['fields'][$field_name]['handlers'] = array(
-          /** D6
-          'field' => array('name' => 'chado_views_handler_field'),
-          'filter' => array('name' => 'chado_views_handler_filter_string'),
-          'sort' => array('name' => 'chado_views_handler_sort'),
-          */
-          'field' => array('name' => 'views_handler_field'),
-          'filter' => array('name' => 'views_handler_filter_string'),
-          'sort' => array('name' => 'views_handler_sort'),
-        );
-      }
-      elseif (preg_match('/^text/', $field_schema['type'])) {
-        $defn_array['fields'][$field_name]['handlers'] = array(
-          /** D6
-          'field' => array('name' => 'chado_views_handler_field'),
-          'filter' => array('name' => 'chado_views_handler_filter_string'),
-          'sort' => array('name' => 'chado_views_handler_sort'),
-          */
-          'field' => array('name' => 'views_handler_field'),
-          'filter' => array('name' => 'views_handler_filter_string'),
-          'sort' => array('name' => 'views_handler_sort'),
-        );
-      }
-      elseif (preg_match('/^boolean/', $field_schema['type'])) {
-        $defn_array['fields'][$field_name]['handlers'] = array(
-          /**
-          'field' => array('name' => 'chado_views_handler_field_boolean'),
-          'filter' => array('name' => 'chado_views_handler_filter_boolean_operator'),
-          'sort' => array('name' => 'chado_views_handler_sort'),
-          */
-          'field' => array('name' => 'views_handler_field_boolean'),
-          'filter' => array('name' => 'views_handler_filter_boolean_operator'),
-          'sort' => array('name' => 'views_handler_sort'),
-        );
-      }
-      elseif (preg_match('/^datetime/', $field_schema['type'])) {
-        $defn_array['fields'][$field_name]['handlers'] = array(
-          /** D6
-          'field' => array('name' => 'chado_views_handler_field_date'),
-          'filter' => array('name' => 'chado_views_handler_filter_date'),
-          'sort' => array('name' => 'views_handler_sort_date'),
-          */
-          'field' => array('name' => 'views_handler_field_date'),
-          'filter' => array('name' => 'views_handler_filter_date'),
-          'sort' => array('name' => 'views_handler_sort_date'),
-        );
-      }
-      else {
-        $defn_array['fields'][$field_name]['handlers'] = array(
-          /** D6
-          'field' => array('name' => 'chado_views_handler_field'),
-          'filter' => array('name' => 'chado_views_handler_filter_string'),
-          'sort' => array('name' => 'chado_views_handler_sort'),
-          */
-          'field' => array('name' => 'views_handler_field'),
-          'filter' => array('name' => 'views_handler_filter_string'),
-          'sort' => array('name' => 'views_handler_sort'),
-        );
-      }
-
-      // Specify specialty handlers
-      if ($field_name == 'type_id' OR $field_name == 'cvterm_id') {
-        $defn_array['fields'][$field_name]['handlers']['filter']['name'] = 'tripal_views_handler_filter_select_cvterm';
-      }
-      if (preg_match('/name/',$field_name)) {
-        $defn_array['fields'][$field_name]['handlers']['filter']['name'] = 'tripal_views_handler_filter_select_string';
-      }
-    }
-  }
-
-  // Add Joins & Relationships for foreign keys to fields
-  if (!isset($schema['foreign keys'])) {
-    $schema['foreign keys'] = array();
-  }
-  foreach ($schema['foreign keys'] as $foreign_key_schema) {
-    foreach ($foreign_key_schema['columns'] as $left_field => $right_field) {
-      // Join
-      $defn_array['fields'][$left_field]['joins'][ $foreign_key_schema['table'] ] = array(
-        'table' => $foreign_key_schema['table'],
-        'field' => $right_field,
-        /**D6 'handler' => 'views_handler_join_chado_aggregator'*/
-        'handler' => 'views_handler_join',
-        'relationship_handler' => 'views_handler_relationship',
-      );
-    }
-  }
-
-  // Add in reverse relationships
-  if (isset($schema['referring_tables'])) {
-    foreach ($schema['referring_tables'] as $referring_table) {
-
-      // D7 @todo: fix referring_tables in schema to list the keys like foreign keys does
-      $referring_schema = chado_get_schema($referring_table);
-      $referring_schema_fk_columns = $referring_schema['foreign keys'][$table_name]['columns'];
-      foreach ($referring_schema_fk_columns as $left_field => $right_field) {
-        $defn_array['fields'][$right_field]['joins'][ $referring_table ] = array(
-          'table' => $referring_table,
-          'field' => $left_field,
-          'relationship_handler' => 'views_handler_relationship',
-          'relationship_only' => 1
-        );
-      }
-    }
-  }
-
-  return $defn_array;
-}
-
-/**
- * Clone an integration
+ * Clone an integration. This is often a great way to create your own module-specific
+ * integration while still benifiting from an existing (or even the lightest priority)
+ * integration.
  *
  * @param $table_name
  *   The table for which you'd like to clone an integration
@@ -1021,7 +1036,8 @@ function tripal_views_add_field_to_integration($table_name, $priority, $field) {
 }
 
 /**
- * Remove a join from an integration
+ * Remove a join from an integration. This is usually done after cloning an existing
+ * integration using tripal_views_clone_integration().
  *
  * @param $setup_id
  *   The setup_id of the integration to delete the join from

+ 180 - 1245
tripal_views/includes/tripal_views_integration.inc

@@ -1,1301 +1,236 @@
 <?php
 /**
  * @file
- * Functions related to the UI for integrating tables with views
+ * Contains functions used to manage tripal views integrations
  */
 
 /**
- * Purpose: Generates a themable table containing the list of integrated tables
- *   The look-and-feel of the table can be altered by overriding the theme for
- *   tables.
- *
- * @return
- *    a themed HTML table
+ * Purpose: Deletes ALL Tripal Views Integrations.
  *
  * @ingroup tripal_views
  */
-function tripal_views_integration_setup_list() {
-  $output = '';
-
-  $output .= '<ul class="action-links">';
-  $output .=  '<li>' . l(t('Add a New Entry'), "admin/tripal/views-integration/new") . '</li>';
-  $output .=  '<li style="float: right;">' . l(t('Delete ALL Entries'), "admin/tripal/views-integration/delete-all/confirm") . '</li>';
-  $output .= '</ul>';
-
-  $output .= '<p>' . t('The following tables are available for integration with Drupal Views. If '
-    . 'a table is integrated more than once, then the setup with the lightest '
-    . 'priority will be used. For example, if you have created a custom setup with a priority of -5 then '
-    . 'that will be used instead of the default setup with priority 10. '
-    . 'Priorities range from -10 to +10  where a setup with -10 has '
-    . 'greater precedent than any other and +10 has the least.') . '</p>';
-
-  // Start with materialized views
-  $output .= '<br /><h3>Legacy Materialized Views</h3>';
-  $header = array('', 'Drupal Views Type Name', 'Table Name', 'Is Legacy?', 'Priority', 'Comment');
-  $rows = array();
-
-  // get the list of materialized views
-  $tviews = db_query('SELECT tv.setup_id, tv.name, tv.table_name, tc.table_id, tv.priority, tv.comment '
-                     .'FROM {tripal_views} tv '
-                     .'LEFT JOIN {tripal_custom_tables} tc ON tc.table_name=tv.table_name '
-                     .'WHERE tv.mview_id IS NOT NULL '
-                     .'ORDER BY tv.table_name ASC, tv.priority ASC');
-  foreach ($tviews as $tview) {
-    $rows[] = array(
-      l(t('Edit'), "admin/tripal/views-integration/edit/" . $tview->setup_id) . "<br />"
-        . l(t('Export'), "admin/tripal/views-integration/export/" . $tview->setup_id) . "<br />"
-        . l(t('Delete'), "admin/tripal/views-integration/delete/" . $tview->setup_id),
-      $tview->name,
-      $tview->table_name,
-      ($tview->table_id) ? 'No' : 'Yes',
-      $tview->priority,
-      $tview->comment,
-    );
-  }
-
-  if ($rows) {
-    $output .= theme('table', array('header' => $header, 'rows' => $rows));
-  }
-  else {
-    $output .= '<p>There are currently no Materialized Views defined. ';
-
-  }
-
-  // Now list non-mview custom tables
-  $output .= '<br /><h3>Custom Tables & Non-Legacy Materialized Views</h3>';
-  $header = array('', 'Drupal Views Type Name', 'Table Name', 'Priority', 'Comment');
-  $rows = array();
-
-  // get the list of chado tables
-  $tviews = db_query('SELECT tv.setup_id, tv.name, tv.table_name, tv.priority, tv.comment '
-                     .'FROM {tripal_views} tv '
-                     .'LEFT JOIN {tripal_custom_tables} tc ON tc.table_name=tv.table_name '
-                     .'WHERE mview_id IS NULL AND tc.table_id IS NOT NULL '
-                     .'ORDER BY table_name ASC, priority ASC');
-  foreach ($tviews as $tview) {
-    $rows[] = array(
-      l(t('Edit'), "admin/tripal/views-integration/edit/" . $tview->setup_id) . "<br />"
-        . l(t('Export'), "admin/tripal/views-integration/export/" . $tview->setup_id) . "<br />"
-        . l(t('Delete'), "admin/tripal/views-integration/delete/" . $tview->setup_id),
-      $tview->name,
-      $tview->table_name,
-      $tview->priority,
-      $tview->comment,
-    );
-  }
-
-  if ($rows) {
-    $output .= theme('table', array('header' => $header, 'rows' => $rows));
-  }
-  else {
-    $output .= '<p>There are currently no non-Materialized View Custom Tables defined.</p>';
-  }
-
-  // Now list chado tables
-  $output .= '<br /><h3>Chado Tables</h3>';
-  $header = array('', 'Drupal Views Type Name', 'Table Name', 'Priority', 'Comment');
-  $rows = array();
+function tripal_views_delete_all_integrations() {
 
-  // get the list of chado tables
-  $tviews = db_query('SELECT tv.setup_id, tv.name, tv.table_name, tv.priority, tv.comment '
-                     .'FROM {tripal_views} tv '
-                     .'LEFT JOIN {tripal_custom_tables} tc ON tc.table_name=tv.table_name '
-                     .'WHERE mview_id IS NULL AND tc.table_id IS NULL '
-                     .'ORDER BY table_name ASC, priority ASC');
-  foreach ($tviews as $tview) {
-    $rows[] = array(
-      l(t('Edit'), "admin/tripal/views-integration/edit/" . $tview->setup_id) . "<br />"
-        . l(t('Export'), "admin/tripal/views-integration/export/" . $tview->setup_id) . "<br />"
-        . l(t('Delete'), "admin/tripal/views-integration/delete/" . $tview->setup_id),
-      $tview->name,
-      $tview->table_name,
-      $tview->priority,
-      $tview->comment,
-    );
-  }
-
-  $output .= theme('table', array('header' => $header, 'rows' => $rows));
-  return $output;
-}
-
-/**
- * Purpose: Deletes integration of a table with the Views module.  This
- *   function is meant to be called from a menu item. After completion it
- *   redirects the user to the views intergation page.
- *
- * @param $setup_id
- *    the unique setup id for the integrated table
- *
- * @ingroup tripal_views
- */
-function tripal_views_integration_delete($setup_id) {
+  db_query("DELETE FROM {tripal_views}");
+  db_query("DELETE FROM {tripal_views_field}");
+  db_query("DELETE FROM {tripal_views_handlers}");
+  db_query("DELETE FROM {tripal_views_join}");
 
-  tripal_views_integration_remove_entry_by_setup_id($setup_id);
-  drupal_set_message(t("Record Deleted"));
-  drupal_goto('admin/tripal/views-integration');
+  drupal_set_message("Successfully deleted all views integration.");
 
 }
 
 /**
- * Purpose: Deletes ALL Tripal Views Integrations.  This
- *   function is meant to be called from a menu item. After completion it
- *   redirects the user to the views intergation page.
+ * Integrate all chado tables in the schema api.  This integration only occurs
+ * once and sets all Chado tables to a priority of 10
  *
  * @ingroup tripal_views
  */
-function tripal_views_integration_delete_all_form ($form, $form_state) {
+function tripal_views_integrate_all_chado_tables() {
 
-  $form['extra'] = array(
-    '#type' => 'item',
-    '#markup' => t('This will REMOVE ALL views integrations (both custom and default) '
-      . 'from your website. This allows integrations to be rebuilt to new default '
-      . 'settings and is especially useful after an upgrade to the views integration system.'),
-  );
+  $tables = chado_get_table_names(TRUE);
 
-  $form['description'] = array(
-    '#type' => 'item',
-    '#markup' => t('Are you sure you want to REMOVE ALL Views Integrations (including custom integrations) from your system?'),
+  $base_tables = array(
+    'acquisition', 'analysis', 'assay', 'biomaterial', 'contact', 'cv', 'cvterm',
+    'db', 'dbxref', 'environment', 'expression', 'feature', 'featuremap', 'genotype',
+    'library', 'nd_experiment', 'nd_geolocation', 'nd_protocol', 'nd_reagent',
+    'organism', 'phendesc', 'phenotype', 'phenstatement', 'phylonode', 'phylotree',
+    'project', 'protocol', 'pub', 'stock', 'study', 'synonym'
   );
 
-  $form['actions'] = array('#type' => 'actions');
-
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Confirm'),
-  );
-
-  $form['actions']['cancel'] = array(
-    '#type' => 'link',
-    '#title' => t('Cancel'),
-    '#href' => 'admin/tripal/views-integration/list',
-  );
+  foreach ($tables as $tablename) {
 
-  // By default, render the form using theme_confirm_form().
-  if (!isset($form['#theme'])) {
-    $form['#theme'] = 'confirm_form';
+    $priority = 10;
+    if (!tripal_views_is_integrated($tablename, $priority)) {
+      if (in_array($tablename, $base_tables)) {
+        $table_integration_array = tripal_views_get_integration_array_for_chado_table($tablename, TRUE, $priority);
+      }
+      else {
+        $table_integration_array = tripal_views_get_integration_array_for_chado_table($tablename, FALSE, $priority);
+      }
+      if ($table_integration_array) {
+        tripal_views_integration_add_entry($table_integration_array);
+      }
+    }
   }
-
-  return $form;
-}
-
-/**
- * Purpose: Deletes ALL Tripal Views Integrations.  This
- *   function is meant to be called from a menu item. After completion it
- *   redirects the user to the views intergation page.
- *
- * @ingroup tripal_views
- */
-function tripal_views_integration_delete_all_form_submit ($form, &$form_state) {
-
-  tripal_views_rebuild_views_integrations(TRUE);
-
-  $form_state['redirect'] = 'admin/tripal/views-integration/list';
-
 }
 
 /**
- * Purpose: defines the web form used for specifing the base table, joins and
- *   handlers when integrating a table with views.  This form is used for both
- *   creating a new record and editing an existing record.
- *
- * @param $form_state
- *    The form state which is passed automatically by drupal
- *
- * @param $setup_id
- *    The unique setup for an integrated table.  This value is only set when
- *    the form is used for updating an existing record.
+ * Returns the array needed to integrate a given chado table with views
  *
+ * @param $tablename
+ *   The table to generate the tripal views integration array for
  * @return
- *    A proper Drupal form associative array.
- *
- * D7 @todo: Add ability to manage custom fields
- * D7 @todo: Update relationship handler to work with the new tripal_views_join method
+ *   The tripal views integration array which is the parameter for
+ *   tripal_views_integration_add_entry($defn_array)
  *
  * @ingroup tripal_views
  */
-function tripal_views_integration_form($form, $form_state, $arg) {
-
-  $data = array();
-  $form['#cache'] = TRUE;
-  if (isset($form_state['build_info']['args'][0])) {
-    $setup_id = $form_state['build_info']['args'][0];
-  }
-  else {
-    $setup_id = NULL;
-  }
-
-  // if Ajax is triggered to change the fields table
-  // then make some tweaks before the form is rendered
-  if (isset($form_state['triggering_element'])) {
-
-    $triggering_element = $form_state['triggering_element']['#name'];
-    if (($triggering_element == 'table_name' OR $triggering_element == 'mview_id')) {
-      $form_state['values'][$triggering_element] = $form_state['triggering_element']['#value'];
-      $setup_id = NULL;
-    }
-  }
-
-  // if a setup_id is provided then we want to get the form defaults
-  $setup_obj = array();
-  if (isset($setup_id)) {
-
-    // get the default setup values
-    $sql = "SELECT * FROM {tripal_views} WHERE setup_id = :setup";
-    $setup_obj = db_query($sql, array(':setup' => $setup_id));
-    $setup_obj = $setup_obj->fetchObject();
-    $mview_id = $setup_obj->mview_id;
-    $table_name = $setup_obj->table_name;
-    $form_state['values']['mview_id'] = $mview_id;
-    $form_state['values']['table_name'] = $table_name;
-
-    // get the default field name/description
-    $sql = "SELECT * FROM {tripal_views_field} WHERE setup_id=:setup";
-    $query = db_query($sql, array(':setup' => $setup_id));
-    $default_fields = array();
-    foreach ($query as $field) {
-      $default_fields[$field->column_name]['name'] = $field->name;
-      $default_fields[$field->column_name]['description'] = $field->description;
-    }
-
-    // get the default join settings and handlers
-    $sql = "SELECT * FROM {tripal_views_join} WHERE setup_id = :setup";
-    $query = db_query($sql, array(':setup' => $setup_id));
-    $default_joins = array();
-    foreach ($query as $join) {
-      $default_joins[$join->base_field]['left_table'] = $join->left_table;
-      $default_joins[$join->base_field]['left_field'] = $join->left_field;
-    }
-
-    // get the default handlers
-    $sql = "SELECT * FROM {tripal_views_handlers} WHERE setup_id = :setup";
-    $query = db_query($sql, array(':setup' => $setup_id));
-    $default_handlers = array();
-    foreach ($query as $handler) {
-      $default_handlers[$handler->column_name][$handler->handler_type]['handler_name'] = $handler->handler_name;
-      $default_handlers[$handler->column_name][$handler->handler_type]['arguments'] = $handler->arguments;
-    }
-
-    // get the default join handlers
-    $sql = "SELECT * FROM {tripal_views_join} WHERE setup_id = :setup";
-    $query = db_query($sql, array(':setup' => $setup_id));
-    foreach ($query as $handler) {
-      $default_handlers[$handler->base_field]['join']['handler_name'] = $handler->handler;
-      //$default_handlers[$handler->base_field]['join']['arguments'] = $handler->arguments;
-    }
-
-    // add in the setup_id for the form so we know this is an update not an insert
-    $form['setup_id'] = array(
-       '#type' => 'hidden',
-       '#value' => $setup_id,
-    );
-
-  }
-
-  // add a fieldset for the MView & Chado table selectors
-  $form['base_table_type'] = array(
-    '#type' => 'fieldset',
-    '#title' => 'Base Table',
-    '#description' => 'Please select either a materialized view or a Chado table for integration with '.
-                       'Drupal Views.  In Drupal Views terminology, the selected table becomes the "base table". '.
-                       'After you select a table from either list, the fields from that table will appear below '.
-                       'and you can specify other tables to join with and handlers.',
-  );
-
-  // build the form element for the Chado tables
-  $chado_tables = chado_get_table_names(TRUE);
-  $chado_tables = array_merge(array('Select'), $chado_tables);
-  $default = '';
-  if ($setup_id) {
-    $default = (!$setup_obj->mview_id) ? $setup_obj->table_name : '';
-  }
-  $form['base_table_type']['table_name'] = array(
-    '#title' => t('Chado/Custom Table'),
-    '#type' => 'select',
-    '#options' => $chado_tables,
-    '#description' => t('Tables from Chado, custom tables and materialized view tables (non-legacy MViews) can be selected for integration.'),
-    '#default_value' => $default,
-    '#ajax' => array(
-       //D6: 'path' => 'tripal/views-integration/ajax/view_setup_table',
-       'callback' => 'tripal_views_integration_ajax_view_setup_table',
-       'wrapper' => 'fieldset-table-rows-wrapper',
-       'effect' => 'fade',
-       'event' => 'change',
-       'method' => 'replace',
-    ),
-  );
-
-
-  // build the form element that lists the materialized views
-  // D7 TODO: Check DBTNG changes work
-  $query = db_query("SELECT mview_id, name FROM {tripal_mviews} WHERE mv_schema is NULL or mv_schema = '' ORDER BY name");
-  $mview_tables = array();
-  $mview_tables['0'] = 'Select';
-  foreach ($query as $mview) {
-    $mview_tables[$mview->mview_id] = $mview->name;
-  }
-  $default = '';
-  if ($setup_id && isset($setup_obj->mview_id)) {
-    $default = $setup_obj->mview_id;
-  }
-  $form['base_table_type']['mview_id'] = array(
-    '#title' => t('Legacy Materialized View'),
-    '#type' => 'select',
-    '#options' => $mview_tables,
-    '#description' => 'Which materialized view to use.',
-    '#default_value' => $default,
-    '#ajax' => array(
-       //D6: 'path' => 'tripal/views-integration/ajax/view_setup_table',
-       'callback' => 'tripal_views_integration_ajax_view_setup_table',
-       'wrapper' => 'fieldset-table-rows-wrapper',
-       'effect' => 'fade',
-       'event' => 'change',
-       'method' => 'replace',
-    ),
-  );
-
-  $form['views_type'] = array(
-    '#type' => 'fieldset',
-    '#title' => 'View Type',
-    '#description' => 'Here you can provide the "type" of View you want to create.',
-  );
-
-  // field for the name of the
-  $default = '';
-  if ($setup_id && isset($setup_obj->name)) {
-    $default = $setup_obj->name;
-  }
-  $form['views_type']['row_name'] = array(
-    '#title' => t('View Type Name'),
-    '#type' => 'textfield',
-    '#default_value' => $default,
-    '#size' => 60,
-    '#maxlength' => 128,
-    '#description' => 'Provide the view type name.  This is the name that will appear in '.
-                      'the Drupal Views interface when adding a new view.  The view type name '.
-                      'must be unique.',
-    '#required' => TRUE,
-  );
-
-  if (isset($setup_id)) {
-    $form['row_name']['#attributes'] = array('readonly' => 'readonly');
-  }
-
-  $priorities = array();
-  foreach (range(-10, 10) as $v) {
-    $priorities[$v] = (string) $v;
-  }
-  $default = -1;
-  if ($setup_id && isset($setup_obj->priority)) {
-    $default = $setup_obj->priority;
-    if ($setup_obj->priority >= 9) {
-      drupal_set_message('You are editing a default views integration. To ensure your changes
-        are used, change the priority to -10.', 'warning');
-    }
-  }
-  $form['views_type']['row_priority'] = array(
-    '#type' => 'select',
-    '#title' => t('Priority'),
-    '#description' => t('The level of priority your Views integration has in relation to the '
-      .'default core and module definitions. The views integration definition with the '
-      .'lightest priority will be used. For example, if there is a definition created by '
-      .'core with a priority of 10 and another by a custom module of 5 and yours is -1 then '
-      .'you definition will be used for that table because -1 is lighter then both 5 and 10.'),
-    '#options' => $priorities,
-    '#default_value' => $default,
-  );
-
-  $default = true;
-  if ($setup_id && isset($setup_obj->priority)) {
-    $default = ($setup_obj->priority >= 9) ? true : false;
-  }
-  $form['views_type']['new_integration'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Create a New Tripal Views Integration Record'),
-    '#description' => t('If this checkbox is checked then a new tripal views integration '
-      .'will be created rather then overriding the current one with your changes. This '
-      .'especially important if you are editing one of the default views integrations '
-      .'(ie: if the original priority was either 10 or 9).'),
-    '#default_value' => $default,
-  );
-
-  $default = true;
-  if ($setup_id && isset($setup_obj->base_table)) {
-    $default = $setup_obj->base_table;
-  }
-  $form['views_type']['base_table'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Base Table?'),
-    '#description' => t('If you want this table to show up as one of the options in the '
-      . 'add view page, then check this checkbox. It allows you to create listings '
-      . 'primarily from this table'),
-    '#default_value' => $default,
-  );
-
-  $default = '';
-  if ($setup_id && isset($setup_obj->comment)) {
-    $default = $setup_obj->comment;
-  }
-  $form['views_type']['row_description'] = array(
-    '#title' => t('Comment'),
-    '#type' => 'textarea',
-    '#description' => '(Optional). Provide any details regarding this setup you would like. This '.
-                      'description will appear when selecting a type for a new Drupal View',
-    '#required' => FALSE,
-    '#default_value' => $default,
-  );
-
-  // we need a div block where the table fields will get put when the
-  // AHAH callback is made
-  $form['view_setup_table'] = array(
-    '#type' => 'item',
-    '#prefix' => '<div id="fieldset-table-rows-wrapper">',
-    '#suffix' => '</div>',
+function tripal_views_get_integration_array_for_chado_table($table_name, $base_table = TRUE, $priority = 9) {
+
+  // Get the schema for this table (via the chado schema api)
+  $schema = chado_get_schema($table_name);
+
+  // Base definition array
+  $defn_array = array(
+    'table' => $table_name,
+    'type' => 'chado',
+    'name' => 'Chado ' . ucwords(str_replace('_', ' ', $table_name)),
+    'description' => (!empty($schema['description'])) ? $schema['description'] : ' ',
+    'priority' => $priority,
+    'base_table' => $base_table,
+    'fields' => array(),
   );
-
-
-  // add the fieldset for the table fields, but only if the $mview_id or $table_name
-  // is set. The only times these values are set is if we're editing an existing
-  // record or if the AHAH callback is being made.
-  if (isset($form_state['values']['mview_id']) or isset($form_state['values']['table_name'])) {
-    $mview_id = $form_state['values']['mview_id'];
-    $table_name = $form_state['values']['table_name'];
-    $form['view_setup_table'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Table Fields'),
-      '#prefix' => '<div id="fieldset-table-rows-wrapper">',
-      '#suffix' => '</div>',
-      '#collapsible' => TRUE
-    );
-
-    // get the columns in this materialized view.  They are separated by commas
-    // where the first word is the column name and the rest is the type
-    $columns = array();
-    if ($mview_id) {
-      // D7 TODO: Check DBTNG changes work
-      $sql = "SELECT mv_specs FROM {tripal_mviews} WHERE mview_id = :id";
-      $mview = db_query($sql, array(':id' => $mview_id));
-      $mview = $mview->fetchObject();
-      $columns = explode(",", $mview->mv_specs);
-    }
-    else {
-      $table_desc = chado_get_schema($table_name);
-      if ($table_desc) {
-        $fields = $table_desc['fields'];
-        // iterate through the columns and build the format
-        // compatible with the code below. The column name is first followed
-        // by the type with a separating space
-        foreach ($fields as $column => $attrs) {
-          $columns[] = "$column " . $attrs['type'];
-        }
-      }
-    }
-
-    $i=1;
-    $form['view_setup_table']["instructions"] = array(
-         '#type' => 'markup',
-         '#value' => filter_xss("Select an optional table to which the fields of the ".
-                     "materialized view can join.  If a field does not need to ".
-                     "join you may leave the selection blank."),
-    );
-    $data['field_types'] = array();
-
-    $form['view_setup_table']['header'] = array(
-      '#type' => 'markup',
-      '#prefix' => '<div class="joins-new-row field-headers">',
-      '#suffix' => '</div>',
-    );
-
-    $form['view_setup_table']['header']['column-1'] = array(
-         '#type' => 'markup',
-         '#prefix' => "<div class=\"column-one\">",
-         '#suffix' => "</div>",
-         '#markup' => 'Field'
-    );
-
-    $form['view_setup_table']['header']['column-2'] = array(
-         '#type' => 'markup',
-         '#prefix' => "<div class=\"column-two\">",
-         '#suffix' => "</div>",
-         '#markup' => 'Labels'
-    );
-
-    $form['view_setup_table']['header']['column-3'] = array(
-         '#type' => 'markup',
-         '#prefix' => "<div class=\"column-three\">",
-         '#suffix' => "</div>",
-         '#markup' => ''
-    );
-
-    $form['view_setup_table']['header']['column-4'] = array(
-         '#type' => 'markup',
-         '#prefix' => "<div class=\"column-four\">",
-         '#suffix' => "</div>",
-         '#markup' => 'Handlers'
-    );
-
-    // get the list of chado tables to join on
-    $chado_join_tables = chado_get_table_names(TRUE);
-    $chado_join_tables = array_merge(array('Select a Join Table'), $chado_join_tables);
-
-    // get list of all handlers
-    $all_handlers = tripal_views_integration_discover_handlers();
-    $handlers_fields = array(0 => "Select a field handler");
-    $handlers_filters = array(0 => "Select a filter handler");
-    $handlers_sort = array(0 => "Select a sort handler");
-    $handlers_argument = array(0 => "Select an argument handler");
-    $handlers_join = array(0 => "Select a join handler");
-    $handlers_rel = array(0 => "Select a relationship handler");
-    foreach ($all_handlers as $handler) {
-      if (preg_match("/views_handler_field/", $handler)) {
-        $handlers_fields[$handler] = $handler;
-      }
-      if (preg_match("/views_handler_filter/", $handler)) {
-        $handlers_filters[$handler] = $handler;
-      }
-      if (preg_match("/views_handler_sort/", $handler)) {
-        $handlers_sort[$handler] = $handler;
-      }
-      if (preg_match("/views_handler_argument/", $handler)) {
-        $handlers_argument[$handler] = $handler;
-      }
-      if (preg_match("/_join/", $handler)) {
-        $handlers_join[$handler] = $handler;
-      }
-      if (preg_match("/views_handler_relationship/", $handler)) {
-        $handlers_rel[$handler] = $handler;
-      }
-    }
-
-    // generate a unique $table_id for keeping track of the table
-    if ($mview_id) {
-      $table_id = $mview_id;
-    }
-    else {
-      $table_id = $table_name;
-    }
-
-    // Per Row (Fields) --------------
-    // now iterate through the columns of the materialized view or
-    // chado table and generate the join and handler fields
-    foreach ($columns as $column) {
-      $column = trim($column);  // trim trailing and leading spaces
-      preg_match("/^(.*?)\ (.*?)$/", $column, $matches);
-      $column_name = $matches[1];
-      $column_type = $matches[2];
-
-      $form['view_setup_table']["$table_id-$i"] = array(
-           '#type' => 'markup',
-           '#prefix' => "<div class=\"fields-new-row\">",
-           '#suffix' => "</div>",
-           '#value' => filter_xss('')
-      );
-
-      // COLUMN I
-      $form['view_setup_table']["$table_id-$i"]["fields_name_$table_id-$i"] = array(
-        '#type' => 'item',
-        '#prefix' => "<div class=\"column-one\">",
-        '#markup' => '<span class="column-name">' . filter_xss($column_name) . '</span>'.
-                    '<br /><span class="column-type">' . filter_xss($column_type) . '</span>',
-        '#suffix' => "</div>",
-      );
-      $data['field_types'][$column_name] = $column_type;
-
-      // COLUMN II
-      $form['view_setup_table']["$table_id-$i"]['column-2'] = array(
-           '#type' => 'markup',
-           '#prefix' => "<div class=\"column-two\">",
-           '#suffix' => "</div>",
-           '#value' => filter_xss('')
-      );
-
-      // set the default values for the human-readable name and description
-      $default_name = '';
-      $default_descrip = '';
-      if (isset($setup_id) && !isset($form_state['values']["fields_readable_name_$table_id-$i"])) {
-        $default_name = $default_fields[$column_name]['name'];
-        $default_descrip = $default_fields[$column_name]['description'];
-      }
-      elseif (isset($form_state['values']["fields_readable_name_$table_id-$i"])) {
-        $default_name = $form_state['values']["fields_readable_name_$table_id-$i"];
-        $default_descrip = $form_state['values']["fields_description_$table_id-$i"];
-      }
-      else {
-        $default_name = ucwords(str_replace('_',' ', $column_name));
-        $default_descrip = 'TODO: please describe this field!';
-      }
-      $form['view_setup_table']["$table_id-$i"]['column-2']["fields_readable_name_$table_id-$i"] = array(
-        '#type' => 'textfield',
-        '#title' => 'Human-Readable Name',
-        '#description' => 'This is the name of the field in the Views UI',
-        '#required' => TRUE,
-        '#default_value' => $default_name,
-        '#size' => 42,
-      );
-
-      $form['view_setup_table']["$table_id-$i"]['column-2']["fields_description_$table_id-$i"] = array(
-        '#type' => 'textarea',
-        '#title' => 'Short Description',
-        '#description' => 'This is the field help in the Views UI',
-        '#required' => TRUE,
-        '#cols' => 42,
-        '#rows' => 3,
-        '#default_value' => $default_descrip,
-      );
-
-      // COLUMN III
-      $form['view_setup_table']["$table_id-$i"]['column-3'] = array(
-           '#type' => 'markup',
-           '#prefix' => "<div class=\"column-three\">",
-           '#suffix' => "</div>",
-           '#value' => filter_xss('')
-      );
-
-      // COLUMN 4
-      $form['view_setup_table']["$table_id-$i"]['column-4'] = array(
-        '#type' => 'markup',
-        '#prefix' => "<div class=\"column-four\">",
-        '#suffix' => "</div>",
-        '#value' => filter_xss('')
-      );
-
-      // create the handler fields
-      $default_field_handler = 0;
-      if (isset($setup_id) && !isset($form_state['values']["fields_field_handler_$table_id-$i"])) {
-        $default_field_handler = $default_handlers[$column_name]['field']['handler_name'];
-        $form_state['values']["fields_field_handler_$table_id-$i"] = $default_field_handler;
-      }
-      else {
-        $default_field_handler = $form_state['values']["fields_field_handler_$table_id-$i"];
-        if (!$default_field_handler) {
-          if ($column_type == 'integer' or $column_type == 'int' or $column_type == 'serial') {
-            $default_field_handler = 'chado_views_handler_field_numeric';
-          }
-          elseif (preg_match("/character varying/", $column_type) or $column_type == 'char' or $column_type == 'text' or $column_type == 'varchar') {
-            $default_field_handler = 'chado_views_handler_field';
-          }
-          elseif ($column_type == 'boolean') {
-            $default_field_handler = 'chado_views_handler_field_boolean';
-          }
-          elseif ($column_type == 'float') {
-            $default_field_handler = 'chado_views_handler_field_numeric';
-          }
-          elseif ($column_type == 'datetime') {
-            $default_field_handler = 'chado_views_handler_field_date';
-          }
-        }
-      }
-
-      $form['view_setup_table']["$table_id-$i"]['column-4']["fields_field_handler_$table_id-$i"] = array(
-         '#type' => 'select',
-         '#prefix' => "<div class=\"fields-field-handler\">",
-         '#suffix' => "</div>",
-         '#options' => $handlers_fields,
-         '#required' => FALSE,
-         '#default_value' => $default_field_handler,
-      );
-
-      $default_filter_handler = 0;
-      if (isset($setup_id) && !isset($form_state['values']["fields_filter_handler_$table_id-$i"])) {
-        $default_filter_handler = $default_handlers[$column_name]['filter']['handler_name'];
-        $form_state['values']["fields_filter_handler_$table_id-$i"]= $default_filter_handler;
+  // Add fields
+  if (!isset($schema['fields'])) {
+    tripal_report_error('tripal_views', TRIPAL_NOTICE,
+      'There are no fields defined for %table in the Chado Schema API.', array('%table' => $table_name));
+    return FALSE;
+  }
+  foreach ($schema['fields'] as $field_name => $field_schema) {
+
+    // Base field definition
+    if (!empty($field_name) && !empty($field_schema['type'])) {
+      $defn_array['fields'][$field_name] = array(
+        'name' => $field_name,
+        'title' => ucwords(str_replace('_', ' ', $field_name)),
+        'type' => $field_schema['type'],
+        'description' => (isset($field_schema['description'])) ? $field_schema['description'] : ucwords(str_replace('_', ' ', $field_name)),
+        'handlers' => array(),
+        'joins' => array()
+      );
+
+      // Add handlers based on type
+      if (preg_match('/^int/', $field_schema['type'])) {
+        $defn_array['fields'][$field_name]['handlers'] = array(
+          /** D6
+          'field' => array('name' => 'chado_views_handler_field_numeric'),
+          'filter' => array('name' => 'chado_views_handler_filter_numeric'),
+          'sort' => array('name' => 'chado_views_handler_sort'),
+          */
+          'field' => array('name' => 'views_handler_field_numeric'),
+          'filter' => array('name' => 'views_handler_filter_numeric'),
+          'sort' => array('name' => 'views_handler_sort'),
+        );
       }
-      else {
-        $default_filter_handler = $form_state['values']["fields_filter_handler_$table_id-$i"];
-        if (!$default_filter_handler) {
-          if ($column_type == 'integer' or $column_type == 'int' or $column_type == 'serial') {
-            $default_filter_handler = 'chado_views_handler_filter_numeric';
-          }
-          elseif (preg_match("/^character varying/", $column_type) or $column_type == 'char' or $column_type == 'text' or $column_type == 'varchar') {
-            $default_filter_handler = 'chado_views_handler_filter_string';
-          }
-          elseif ($column_type == 'boolean') {
-            $default_filter_handler = 'chado_views_handler_filter_boolean';
-          }
-          elseif ($column_type == 'float') {
-            $default_filter_handler = 'chado_views_handler_filter_float';
-          }
-          elseif ($column_type == 'datetime') {
-            $default_filter_handler = 'chado_views_handler_filter_date';
-          }
-        }
+      elseif (preg_match('/^serial/', $field_schema['type'])) {
+        $defn_array['fields'][$field_name]['handlers'] = array(
+          /** D6
+          'field' => array('name' => 'chado_views_handler_field_numeric'),
+          'filter' => array('name' => 'chado_views_handler_filter_numeric'),
+          'sort' => array('name' => 'chado_views_handler_sort'),
+          */
+          'field' => array('name' => 'views_handler_field_numeric'),
+          'filter' => array('name' => 'views_handler_filter_numeric'),
+          'sort' => array('name' => 'views_handler_sort'),
+        );
+        $defn_array['fields'][$field_name]['type'] = 'int';
+      }
+      elseif (preg_match('/^varchar/', $field_schema['type'])) {
+        $defn_array['fields'][$field_name]['handlers'] = array(
+          /** D6
+          'field' => array('name' => 'chado_views_handler_field'),
+          'filter' => array('name' => 'chado_views_handler_filter_string'),
+          'sort' => array('name' => 'chado_views_handler_sort'),
+          */
+          'field' => array('name' => 'views_handler_field'),
+          'filter' => array('name' => 'views_handler_filter_string'),
+          'sort' => array('name' => 'views_handler_sort'),
+        );
       }
-      $form['view_setup_table']["$table_id-$i"]['column-4']["fields_filter_handler_$table_id-$i"] = array(
-        '#type' => 'select',
-        '#prefix' => "<div class=\"fields-filter-handler\">",
-        '#suffix' => "</div>",
-        '#options' => $handlers_filters,
-        '#required' => FALSE,
-        '#default_value' => $default_filter_handler,
-      );
-
-      $default_sort_handler = 0;
-      if (isset($setup_id) && !isset($form_state['values']["fields_sort_handler_$table_id-$i"])) {
-        $default_sort_handler = $default_handlers[$column_name]['sort']['handler_name'];
-        $form_state['values']["fields_sort_handler_$table_id-$i"] = $default_sort_handler;
+      elseif (preg_match('/^text/', $field_schema['type'])) {
+        $defn_array['fields'][$field_name]['handlers'] = array(
+          /** D6
+          'field' => array('name' => 'chado_views_handler_field'),
+          'filter' => array('name' => 'chado_views_handler_filter_string'),
+          'sort' => array('name' => 'chado_views_handler_sort'),
+          */
+          'field' => array('name' => 'views_handler_field'),
+          'filter' => array('name' => 'views_handler_filter_string'),
+          'sort' => array('name' => 'views_handler_sort'),
+        );
       }
-      else {
-        $default_sort_handler = $form_state['values']["fields_sort_handler_$table_id-$i"];
-        if (!$default_sort_handler) {
-          if ($column_type == 'integer' or $column_type == 'int' or $column_type == 'serial') {
-            $default_sort_handler = 'chado_views_handler_sort';
-          }
-          elseif (preg_match("/character varying/", $column_type) or $column_type == 'char' or $column_type == 'text' or $column_type == 'varchar') {
-            $default_sort_handler = 'chado_views_handler_sort';
-          }
-          elseif ($column_type == 'boolean') {
-            $default_sort_handler = 'chado_views_handler_sort';
-          }
-          elseif ($column_type == 'float') {
-            $default_sort_handler = 'chado_views_handler_sort';
-          }
-          elseif ($column_type == 'datetime') {
-            $default_sort_handler = 'chado_views_handler_sort_date';
-          }
-        }
+      elseif (preg_match('/^boolean/', $field_schema['type'])) {
+        $defn_array['fields'][$field_name]['handlers'] = array(
+          /**
+          'field' => array('name' => 'chado_views_handler_field_boolean'),
+          'filter' => array('name' => 'chado_views_handler_filter_boolean_operator'),
+          'sort' => array('name' => 'chado_views_handler_sort'),
+          */
+          'field' => array('name' => 'views_handler_field_boolean'),
+          'filter' => array('name' => 'views_handler_filter_boolean_operator'),
+          'sort' => array('name' => 'views_handler_sort'),
+        );
       }
-      $form['view_setup_table']["$table_id-$i"]['column-4']["fields_sort_handler_$table_id-$i"] = array(
-        '#type' => 'select',
-        '#prefix' => "<div class=\"fields-sort-handler\">",
-        '#suffix' => "</div>",
-        '#options' => $handlers_sort,
-        '#required' => FALSE,
-        '#default_value' => $default_sort_handler,
-      );
-
-      $default_argument_handler = 0;
-      if (isset($setup_id)
-        && !isset($form_state['values']["fields_argument_handler_$table_id-$i"])
-        && isset($default_handlers[$column_name]['argument']))
-      {
-        $default_argument_handler = $default_handlers[$column_name]['argument']['handler_name'];
-        $form_state['values']["fields_argument_handler_$table_id-$i"]=$default_argument_handler ;
+      elseif (preg_match('/^datetime/', $field_schema['type'])) {
+        $defn_array['fields'][$field_name]['handlers'] = array(
+          /** D6
+          'field' => array('name' => 'chado_views_handler_field_date'),
+          'filter' => array('name' => 'chado_views_handler_filter_date'),
+          'sort' => array('name' => 'views_handler_sort_date'),
+          */
+          'field' => array('name' => 'views_handler_field_date'),
+          'filter' => array('name' => 'views_handler_filter_date'),
+          'sort' => array('name' => 'views_handler_sort_date'),
+        );
       }
       else {
-        if (isset($form_state['values']["fields_argument_handler_$table_id-$i"])) {
-          $default_argument_handler = $form_state['values']["fields_argument_handler_$table_id-$i"];
-        }
-        if (!$default_argument_handler) {
-          if ($column_type == 'integer' or $column_type == 'int' or $column_type == 'serial') {
-            $default_argument_handler = 'views_handler_argument_numeric';
-          }
-          elseif (preg_match("/character varying/", $column_type) or $column_type == 'char' or $column_type == 'text' or $column_type == 'varchar') {
-            $default_argument_handler = 'views_handler_argument_string';
-          }
-          elseif ($column_type == 'boolean') {
-            $default_argument_handler = 'views_handler_argument_numeric';
-          }
-          elseif ($column_type == 'float') {
-            $default_argument_handler = 'views_handler_argument_numeric';
-          }
-          elseif ($column_type == 'datetime') {
-            $default_argument_handler = 'views_handler_argument_date';
-          }
-        }
+        $defn_array['fields'][$field_name]['handlers'] = array(
+          /** D6
+          'field' => array('name' => 'chado_views_handler_field'),
+          'filter' => array('name' => 'chado_views_handler_filter_string'),
+          'sort' => array('name' => 'chado_views_handler_sort'),
+          */
+          'field' => array('name' => 'views_handler_field'),
+          'filter' => array('name' => 'views_handler_filter_string'),
+          'sort' => array('name' => 'views_handler_sort'),
+        );
       }
-      $form['view_setup_table']["$table_id-$i"]['column-4']["fields_argument_handler_$table_id-$i"] = array(
-        '#type' => 'select',
-        '#prefix' => "<div class=\"fields-argument-handler\">",
-        '#suffix' => "</div>",
-        '#options' => $handlers_argument,
-        '#required' => FALSE,
-        '#default_value' => $default_argument_handler,
-      );
-
-      $i++;
-    }
-
-    $form['view_setup_join'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Joins & Relationships'),
-      '#prefix' => '<div id="fieldset-join-rows-wrapper">',
-      '#suffix' => '</div>',
-      '#description' => t('Below is a list of the joins/relationships between the '
-        . 'current base table and other chado tables.'),
-      '#collapsible' => TRUE,
-      '#collapsed' => TRUE
-    );
-
-    $form['view_setup_join']['header'] = array(
-      '#type' => 'markup',
-      '#prefix' => '<div class="joins-new-row field-headers">',
-      '#suffix' => '</div>',
-    );
-
-    $form['view_setup_join']['header']['column-1'] = array(
-         '#type' => 'markup',
-         '#prefix' => "<div class=\"join-column-one\">",
-         '#suffix' => "</div>",
-         '#markup' => 'Base'
-    );
-
-    $form['view_setup_join']['header']['column-2'] = array(
-         '#type' => 'markup',
-         '#prefix' => "<div class=\"join-column-two\">",
-         '#suffix' => "</div>",
-         '#markup' => 'Handlers'
-    );
-
-    $form['view_setup_join']['header']['column-3'] = array(
-         '#type' => 'markup',
-         '#prefix' => "<div class=\"join-column-three\">",
-         '#suffix' => "</div>",
-         '#markup' => 'Joined to'
-    );
-
-    $base_field_options = array('Select the Base Column');
-    $table_desc = chado_get_schema($table_name);
-    foreach ($table_desc['fields'] as $column => $def) {
-      $base_field_options[$column] = $column;
-    }
-    $chado_join_tables[0] = 'Select the Left Table';
-    unset($handlers_join[0]);
-
-    $query = db_select('tripal_views_join','tvj');
-    $query->fields('tvj')
-      ->condition('tvj.setup_id',$setup_id,'=')
-      ->orderBy('tvj.relationship_only','ASC')
-      ->orderBy('tvj.base_field', 'ASC')
-      ->orderBy('tvj.left_table', 'ASC');
-    foreach ($query->execute() as $i => $result) {
-      $form['view_setup_join']["$table_id-$i"] = array(
-           '#type' => 'markup',
-           '#prefix' => "<div class=\"joins-new-row\">",
-           '#suffix' => "</div>",
-           '#value' => filter_xss('')
-      );
-
-      // COLUMN I
-      $form['view_setup_join']["$table_id-$i"]['column-1'] = array(
-           '#type' => 'markup',
-           '#prefix' => "<div class=\"join-column-one\">",
-           '#suffix' => "</div>",
-      );
-
-      $form['view_setup_join']["$table_id-$i"]['column-1']['join_base_table'] = array(
-        '#type' => 'item',
-        '#markup' => '<span class="column-name">' . filter_xss($result->base_table) . '</span>'
-      );
-
-      $form['view_setup_join']["$table_id-$i"]['column-1']["join_base_table-$i"] = array(
-        '#type' => 'hidden',
-        '#value' => $result->base_table
-      );
-
-      $form['view_setup_join']["$table_id-$i"]['column-1']["join_base_field-$i"] = array(
-        '#type' => 'select',
-        '#options' => $base_field_options,
-        '#required' => FALSE,
-        '#default_value' => $result->base_field
-      );
-
-      // COLUMN II
-      $form['view_setup_join']["$table_id-$i"]['column-2'] = array(
-           '#type' => 'markup',
-           '#prefix' => "<div class=\"join-column-two\">",
-           '#suffix' => "</div>",
-           '#value' => filter_xss('')
-      );
-
-      $form['view_setup_join']["$table_id-$i"]['column-2']["join_join_handler-$i"] = array(
-        '#type' => 'select',
-        '#prefix' => "<div class=\"fields-join-handler\">",
-        '#suffix' => "</div>",
-        '#options' => $handlers_join,
-        '#required' => FALSE,
-        '#default_value' => $result->handler,
-      );
 
-      $form['view_setup_join']["$table_id-$i"]['column-2']["join_relationship_handler-$i"] = array(
-        '#type' => 'select',
-        '#prefix' => "<div class=\"fields-relationship-handler\">",
-        '#suffix' => "</div>",
-        '#options' => $handlers_rel,
-        '#required' => FALSE,
-        '#default_value' => $result->relationship_handler,
-      );
-
-      $form['view_setup_join']["$table_id-$i"]['column-2']["join_relationship_only-$i"] = array(
-        '#type' => 'checkbox',
-        '#title' => 'Relationship Only?',
-        '#default_value' => $result->relationship_only
-      );
-
-      // COLUMN III
-      $form['view_setup_join']["$table_id-$i"]['column-3'] = array(
-           '#type' => 'markup',
-           '#prefix' => "<div class=\"join-column-three\">",
-           '#suffix' => "</div>",
-           '#value' => filter_xss('')
-      );
-
-      $form['view_setup_join']["$table_id-$i"]['column-3']["join_left_table-$i"] = array(
-        '#type' => 'select',
-        '#options' => $chado_join_tables,
-        '#default_value' => $result->left_table,
-      );
-
-      $columns = array();
-      if ($result->left_table) {
-        // get the table description
-        $table_desc = chado_get_schema($result->left_table);
-        foreach ($table_desc['fields'] as $column => $def) {
-          $columns[$column] = $column;
-        }
+      // Specify specialty handlers
+      if ($field_name == 'type_id' OR $field_name == 'cvterm_id') {
+        $defn_array['fields'][$field_name]['handlers']['filter']['name'] = 'tripal_views_handler_filter_select_cvterm';
       }
-      else {
-        $columns = array('Select Left Column');
+      if (preg_match('/name/',$field_name)) {
+        $defn_array['fields'][$field_name]['handlers']['filter']['name'] = 'tripal_views_handler_filter_select_string';
       }
-      $form['view_setup_join']["$table_id-$i"]['column-3']["join_left_field-$i"] = array(
-        '#type' => 'select',
-        '#prefix' => "  <div id=\"fields-column-join-column-$table_id-$i\" class=\"fields-column-join-column\">",
-        '#suffix' => "</div>",
-        '#options' => $columns,
-        '#required' => FALSE,
-        '#default_value' => $result->left_field
-      );
-    }
-
-    $form['num_joins'] = array(
-      '#type' => 'hidden',
-      '#value' => $i
-    );
-
-    $form['save'] = array(
-      '#type'  => 'submit',
-      '#value' => t('Save'),
-    );
-
-    $data['row_count'] = $i - 1;
-  } //end of if table/mview
-
-  //use this to put values into $form_state['values']
-  $form['data'] = array();
-
-  // Ensure that we don't store an array
-  // since we will get a check_plain:htmlspecial_characters error if we do
-  foreach ($data as $key => $value) {
-    if (is_array($value)) {
-      $form['data'][$key] = array(
-        '#type' => 'hidden',
-        '#value' => serialize($value),
-      );
-    }
-    else {
-      $form['data'][$key] = array(
-        '#type' => 'hidden',
-        '#value' => $value,
-      );
     }
   }
 
-  $form['#redirect'] = 'admin/tripal/views-integration/list';
-
-  return $form;
-}
-
-/**
- * Purpose: validates the tripal_views_integration_form after submission
- *
- * @param $form
- *    The form object which is passed automatically by drupal
- *
- * @param $form_state
- *    The form state pbject which is passed automatically by drupal
- *
- * @ingroup tripal_views
- */
-function tripal_views_integration_form_validate($form, &$form_state) {
-  $name_array = explode(" ", $form_state['values']['row_name']);
-  $mview_id = $form_state['values']['mview_id'];
-  $table_name = $form_state['values']['table_name'];
-
-//  if (count($name_array) > 1) {
-//    form_set_error($form_state['values']['row_name'], 'The View type name must be a single word only.');
-//  }
-  if ($mview_id and $table_name) {
-    form_set_error('mview_id', 'Please select either a materialized view or a Chado table but not both');
-  }
-  if (!$mview_id and !$table_name) {
-    form_set_error('mview_id', 'Please select either a materialized view or a Chado table');
-  }
-
-  // Ensure that users don't override the default integrations
-  if ($form_state['values']['row_priority'] >= 9) {
-    form_set_error('row_priority', 'A priority of 10 or 9 is reserved for default tripal '
-      .'views integrations created by core modules. Please set the priority between '
-      .'0 and -10 to ensure your changes are used rather over the defaults.');
-  }
-}
-
-/**
- * Purpose: inserts or updates the record in the tripal views integration
- *   tables.  This function is only called if validation is passed.
- *
- * @param $form
- *    The form object which is passed automatically by drupal
- *
- * @param $form_state
- *    The form state pbject which is passed automatically by drupal
- *
- * @ingroup tripal_views
- */
-function tripal_views_integration_form_submit($form, &$form_state) {
-  $name = $form_state['values']['row_name'];
-  $mview_id = $form_state['values']['mview_id'];
-  $table_name = $form_state['values']['table_name'];
-  $setup_id = $form_state['values']['setup_id'];
-  $priority = $form_state['values']['row_priority'];
-  $comment = $form_state['values']['row_description'];
-
-  // get details about this mview
-  if ($mview_id) {
-    // D7 TODO: Check DBTNG changes work
-    $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = :id";
-    $mview = db_query($sql, array(':id' => $mview_id));
-    $mview = $mview->fetchObject();
-    $table_name = $mview->mv_table;
-    $table_id = $mview_id;
-    $type = 'mview';
-  }
-  else {
-    $type = 'chado';
-    $table_id = $table_name;
-  }
-
-  // If this is for a materialized view then we want to add/update that record
-  $tripal_views_record = array();
-  if ($mview_id) {
-    // get details about this mview
-    // D7 TODO: Check DBTNG changes work
-    $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = :id";
-    $mview = db_query($sql, array(':id' => $mview_id));
-    $mview = $mview->fetchObject();
-
-    // build the record for insert/update
-    $tripal_views_record = array(
-     'mview_id' => $mview_id,
-     'table_name' => $mview->mv_table,
-     'name' => $name,
-     'priority' => $priority,
-     'comment' => $comment,
-     'base_table' => $form_state['values']['base_table']
-    );
-  }
-  // if a chado table then...
-  else {
-    // build the record for insert/update
-    $tripal_views_record = array(
-     'table_name' => $table_name,
-     'name' => $name,
-     'priority' => $priority,
-     'comment' => $comment,
-     'base_table' => $form_state['values']['base_table']
-    );
-  }
-
-  // perform the insert or update
-  if (!$setup_id) {  // this is an insert
-    if (!drupal_write_record('tripal_views', $tripal_views_record)) {
-      drupal_set_message(t("Failed to add record."), 'error');
-      return;
-    }
+  // Add Joins & Relationships for foreign keys to fields
+  if (!isset($schema['foreign keys'])) {
+    $schema['foreign keys'] = array();
   }
-  else {  // this is an update
-    // check to see if it was specified to create a new integration
-    if ($form_state['values']['new_integration']) {
-      $setup_id = NULL;
-      if (!drupal_write_record('tripal_views', $tripal_views_record)) {
-        drupal_set_message(t("Failed to add record."), 'error');
-        return;
-      }
-    }
-    else {
-      $tripal_views_record['setup_id'] = $setup_id;
-      if (!drupal_write_record('tripal_views', $tripal_views_record, array('setup_id'))) {
-        drupal_set_message(t("Failed to update record."), 'error');
-        return;
-      }
+  foreach ($schema['foreign keys'] as $foreign_key_schema) {
+    foreach ($foreign_key_schema['columns'] as $left_field => $right_field) {
+      // Join
+      $defn_array['fields'][$left_field]['joins'][ $foreign_key_schema['table'] ] = array(
+        'table' => $foreign_key_schema['table'],
+        'field' => $right_field,
+        /**D6 'handler' => 'views_handler_join_chado_aggregator'*/
+        'handler' => 'views_handler_join',
+        'relationship_handler' => 'views_handler_relationship',
+      );
     }
   }
 
-  // if this is an update then clean out the existing joins and handlers so we can add new ones
-  if ($setup_id) {
-    db_query("DELETE FROM {tripal_views_field} WHERE setup_id = :setup", array(':setup' => $setup_id));
-    db_query("DELETE FROM {tripal_views_join} WHERE setup_id = :setup", array(':setup' => $setup_id));
-    db_query("DELETE FROM {tripal_views_handlers} WHERE setup_id = :setup", array(':setup' => $setup_id));
-  }
-
-  // iterate through the columns of the form and add
-  // the joins if provided, and the handlers
-  $i = 1;
-  foreach (unserialize($form_state['values']['field_types']) as $key => $value) {
-
-    // add the field definition
-    $view_field_record = array(
-      'setup_id' => $tripal_views_record['setup_id'],
-      'column_name' => $key,
-      'name' => $form_state['values']["fields_readable_name_$table_id-$i"],
-      'description' => $form_state['values']["fields_description_$table_id-$i"],
-      'type' => $value,
-    );
-    drupal_write_record('tripal_views_field', $view_field_record);
+  // Add in reverse relationships
+  if (isset($schema['referring_tables'])) {
+    foreach ($schema['referring_tables'] as $referring_table) {
 
-    // add the hanlders
-    $handlers = array('filter', 'field', 'sort', 'argument');
-
-    foreach ($handlers as $handler) {
-      $handler_name = $form_state['values']["fields_" . $handler . "_handler_$table_id-$i"];
-      if ($handler_name) {
-        $handler_record = array(
-          'setup_id' => $tripal_views_record['setup_id'],
-          'column_name' => $key,
-          'handler_type' => $handler,
-          'handler_name' => $handler_name,
+      // D7 @todo: fix referring_tables in schema to list the keys like foreign keys does
+      $referring_schema = chado_get_schema($referring_table);
+      $referring_schema_fk_columns = $referring_schema['foreign keys'][$table_name]['columns'];
+      foreach ($referring_schema_fk_columns as $left_field => $right_field) {
+        $defn_array['fields'][$right_field]['joins'][ $referring_table ] = array(
+          'table' => $referring_table,
+          'field' => $left_field,
+          'relationship_handler' => 'views_handler_relationship',
+          'relationship_only' => 1
         );
-        drupal_write_record('tripal_views_handlers', $handler_record);
       }
     }
-    $i++;
-  }
-
-  // Now add all the joins
-  for($i = 0; $i <= $form_state['values']['num_joins']; $i++) {
-    $join_record = array(
-      'setup_id' => $tripal_views_record['setup_id'],
-      'base_table' => $form_state['values']["join_base_table-$i"],
-      'base_field' => $form_state['values']["join_base_field-$i"],
-      'left_table' => $form_state['values']["join_left_table-$i"],
-      'left_field' => $form_state['values']["join_left_field-$i"],
-      'handler' => $form_state['values']["join_join_handler-$i"],
-      'relationship_handler' => $form_state['values']["join_relationship_handler-$i"],
-      'relationship_only' => $form_state['values']["join_relationship_only-$i"]
-    );
-    drupal_write_record('tripal_views_join', $join_record);
-  }
-
-  if ($setup_id) {
-    drupal_set_message(t('Record Updated'));
-  }
-  else {
-    drupal_set_message(t('Record Added'));
-  }
-
-  $form_state['redirect'] = 'admin/tripal/views-integration/list';
-
-  // now clear all the caches so that Drupal views picks up our chages
-  views_invalidate_cache();
-}
-
-/**
- * Purpose: this function queries all modules currently enabled on the site
- *   looking for custom handlers and returns a list of all available handerls.
- *   The base View handlers are also included.
- *
- * @return
- *   Returns an array of handler names
- *
- * @ingroup tripal_views
- */
-function tripal_views_integration_discover_handlers() {
-
-  $handlers = array();
-
-  // Get handlers from all modules.
-  foreach (module_implements('views_handlers') as $module) {
-    $function = $module . '_views_handlers';
-    $result = $function();
-    if (!is_array($result)) {
-      continue;
-    }
-    foreach ($result['handlers'] as $handler => $parent) {
-      $handlers[] = $handler;
-    }
   }
 
-  // these handlers are hard coded because I could not
-  // get the views_handlers() function to be called
-  // in the code above.  However, we will be creating
-  // Chado wrappers for many of these and once that work
-  // is done these will no longer be needed.
-
-  // argument handlers
-  $handlers[] = 'views_handler_argument';
-  $handlers[] = 'views_handler_argument_numeric';
-  $handlers[] = 'views_handler_argument_formula';
-  $handlers[] = 'views_handler_argument_date';
-  $handlers[] = 'views_handler_argument_string';
-  $handlers[] = 'views_handler_argument_many_to_one';
-  $handlers[] = 'views_handler_argument_null';
-
-  // field handlers
-  $handlers[] = 'views_handler_field';
-  $handlers[] = 'views_handler_field_date';
-  $handlers[] = 'views_handler_field_boolean';
-  $handlers[] = 'views_handler_field_markup';
-  $handlers[] = 'views_handler_field_xss';
-  $handlers[] = 'views_handler_field_url';
-  $handlers[] = 'views_handler_field_file_size';
-  $handlers[] = 'views_handler_field_prerender_list';
-  $handlers[] = 'views_handler_field_numeric';
-  $handlers[] = 'views_handler_field_custom';
-  $handlers[] = 'views_handler_field_counter';
-
-  // filter handlers
-  $handlers[] = 'views_handler_filter';
-  $handlers[] = 'views_handler_filter_equality';
-  $handlers[] = 'views_handler_filter_string';
-  $handlers[] = 'views_handler_filter_boolean_operator';
-  $handlers[] = 'views_handler_filter_boolean_operator_string';
-  $handlers[] = 'views_handler_filter_in_operator';
-  $handlers[] = 'views_handler_filter_numeric';
-  $handlers[] = 'views_handler_filter_float';
-  $handlers[] = 'views_handler_filter_date';
-  $handlers[] = 'views_handler_filter_many_to_one';
-
-  // relationship handlers
-  $handlers[] = 'views_handler_relationship';
-
-  // sort handlers
-  $handlers[] = 'views_handler_sort';
-  $handlers[] = 'views_handler_sort_formula';
-  $handlers[] = 'views_handler_sort_date';
-  $handlers[] = 'views_handler_sort_menu_hierarchy';
-  $handlers[] = 'views_handler_sort_random';
-
-  // join handler
-  $handlers[] = 'views_join';
-
-  return $handlers;
-}
-
-/*
- * Ajax Callback: Tripal Views Integration Form
- * Replaces the entire fields table when the table or materialized view is set/changed
- *
- * @ingroup tripal_views
- */
-function tripal_views_integration_ajax_view_setup_table($form, $form_state) {
-  return $form['view_setup_table'];
-}
-
-/*
- * Ajax Callback: Tripal Views Integration Form
- * Replaces the join db field dropdown when the join table dropdown is changed
- *
- * @ingroup tripal_views
- */
-function tripal_views_integration_ajax_join_field($form, $form_state) {
-
-  // Determine which row we are dealing with from the name of the triggering element
-  if (preg_match('/fields_join_(\w+-\d+)/', $form_state['triggering_element']['#name'], $matches)) {
-    $field = $matches[1];
-    $join_field = 'fields_join_column_' . $matches[1];
-    // return the form element to be updated
-    return $form['view_setup_table'][$field]['column-3'][$join_field];
-  }
-  else {
-    tripal_report_error('tripal_views', TRIPAL_ERROR,
-      'Tripal Views Integration Ajax failed due to being unable to determine which row needs updating', array());
-    return $form;
-  }
-}
+  return $defn_array;
+}

+ 1301 - 0
tripal_views/includes/tripal_views_integration_UI.inc

@@ -0,0 +1,1301 @@
+<?php
+/**
+ * @file
+ * Functions related to the UI for integrating tables with views
+ */
+
+/**
+ * Purpose: Generates a themable table containing the list of integrated tables
+ *   The look-and-feel of the table can be altered by overriding the theme for
+ *   tables.
+ *
+ * @return
+ *    a themed HTML table
+ *
+ * @ingroup tripal_views
+ */
+function tripal_views_integration_setup_list() {
+  $output = '';
+
+  $output .= '<ul class="action-links">';
+  $output .=  '<li>' . l(t('Add a New Entry'), "admin/tripal/views-integration/new") . '</li>';
+  $output .=  '<li style="float: right;">' . l(t('Delete ALL Entries'), "admin/tripal/views-integration/delete-all/confirm") . '</li>';
+  $output .= '</ul>';
+
+  $output .= '<p>' . t('The following tables are available for integration with Drupal Views. If '
+    . 'a table is integrated more than once, then the setup with the lightest '
+    . 'priority will be used. For example, if you have created a custom setup with a priority of -5 then '
+    . 'that will be used instead of the default setup with priority 10. '
+    . 'Priorities range from -10 to +10  where a setup with -10 has '
+    . 'greater precedent than any other and +10 has the least.') . '</p>';
+
+  // Start with materialized views
+  $output .= '<br /><h3>Legacy Materialized Views</h3>';
+  $header = array('', 'Drupal Views Type Name', 'Table Name', 'Is Legacy?', 'Priority', 'Comment');
+  $rows = array();
+
+  // get the list of materialized views
+  $tviews = db_query('SELECT tv.setup_id, tv.name, tv.table_name, tc.table_id, tv.priority, tv.comment '
+                     .'FROM {tripal_views} tv '
+                     .'LEFT JOIN {tripal_custom_tables} tc ON tc.table_name=tv.table_name '
+                     .'WHERE tv.mview_id IS NOT NULL '
+                     .'ORDER BY tv.table_name ASC, tv.priority ASC');
+  foreach ($tviews as $tview) {
+    $rows[] = array(
+      l(t('Edit'), "admin/tripal/views-integration/edit/" . $tview->setup_id) . "<br />"
+        . l(t('Export'), "admin/tripal/views-integration/export/" . $tview->setup_id) . "<br />"
+        . l(t('Delete'), "admin/tripal/views-integration/delete/" . $tview->setup_id),
+      $tview->name,
+      $tview->table_name,
+      ($tview->table_id) ? 'No' : 'Yes',
+      $tview->priority,
+      $tview->comment,
+    );
+  }
+
+  if ($rows) {
+    $output .= theme('table', array('header' => $header, 'rows' => $rows));
+  }
+  else {
+    $output .= '<p>There are currently no Materialized Views defined. ';
+
+  }
+
+  // Now list non-mview custom tables
+  $output .= '<br /><h3>Custom Tables & Non-Legacy Materialized Views</h3>';
+  $header = array('', 'Drupal Views Type Name', 'Table Name', 'Priority', 'Comment');
+  $rows = array();
+
+  // get the list of chado tables
+  $tviews = db_query('SELECT tv.setup_id, tv.name, tv.table_name, tv.priority, tv.comment '
+                     .'FROM {tripal_views} tv '
+                     .'LEFT JOIN {tripal_custom_tables} tc ON tc.table_name=tv.table_name '
+                     .'WHERE mview_id IS NULL AND tc.table_id IS NOT NULL '
+                     .'ORDER BY table_name ASC, priority ASC');
+  foreach ($tviews as $tview) {
+    $rows[] = array(
+      l(t('Edit'), "admin/tripal/views-integration/edit/" . $tview->setup_id) . "<br />"
+        . l(t('Export'), "admin/tripal/views-integration/export/" . $tview->setup_id) . "<br />"
+        . l(t('Delete'), "admin/tripal/views-integration/delete/" . $tview->setup_id),
+      $tview->name,
+      $tview->table_name,
+      $tview->priority,
+      $tview->comment,
+    );
+  }
+
+  if ($rows) {
+    $output .= theme('table', array('header' => $header, 'rows' => $rows));
+  }
+  else {
+    $output .= '<p>There are currently no non-Materialized View Custom Tables defined.</p>';
+  }
+
+  // Now list chado tables
+  $output .= '<br /><h3>Chado Tables</h3>';
+  $header = array('', 'Drupal Views Type Name', 'Table Name', 'Priority', 'Comment');
+  $rows = array();
+
+  // get the list of chado tables
+  $tviews = db_query('SELECT tv.setup_id, tv.name, tv.table_name, tv.priority, tv.comment '
+                     .'FROM {tripal_views} tv '
+                     .'LEFT JOIN {tripal_custom_tables} tc ON tc.table_name=tv.table_name '
+                     .'WHERE mview_id IS NULL AND tc.table_id IS NULL '
+                     .'ORDER BY table_name ASC, priority ASC');
+  foreach ($tviews as $tview) {
+    $rows[] = array(
+      l(t('Edit'), "admin/tripal/views-integration/edit/" . $tview->setup_id) . "<br />"
+        . l(t('Export'), "admin/tripal/views-integration/export/" . $tview->setup_id) . "<br />"
+        . l(t('Delete'), "admin/tripal/views-integration/delete/" . $tview->setup_id),
+      $tview->name,
+      $tview->table_name,
+      $tview->priority,
+      $tview->comment,
+    );
+  }
+
+  $output .= theme('table', array('header' => $header, 'rows' => $rows));
+  return $output;
+}
+
+/**
+ * Purpose: Deletes integration of a table with the Views module.  This
+ *   function is meant to be called from a menu item. After completion it
+ *   redirects the user to the views intergation page.
+ *
+ * @param $setup_id
+ *    the unique setup id for the integrated table
+ *
+ * @ingroup tripal_views
+ */
+function tripal_views_integration_delete($setup_id) {
+
+  tripal_views_integration_remove_entry_by_setup_id($setup_id);
+  drupal_set_message(t("Record Deleted"));
+  drupal_goto('admin/tripal/views-integration');
+
+}
+
+/**
+ * Purpose: Deletes ALL Tripal Views Integrations.  This
+ *   function is meant to be called from a menu item. After completion it
+ *   redirects the user to the views intergation page.
+ *
+ * @ingroup tripal_views
+ */
+function tripal_views_integration_delete_all_form ($form, $form_state) {
+
+  $form['extra'] = array(
+    '#type' => 'item',
+    '#markup' => t('This will REMOVE ALL views integrations (both custom and default) '
+      . 'from your website. This allows integrations to be rebuilt to new default '
+      . 'settings and is especially useful after an upgrade to the views integration system.'),
+  );
+
+  $form['description'] = array(
+    '#type' => 'item',
+    '#markup' => t('Are you sure you want to REMOVE ALL Views Integrations (including custom integrations) from your system?'),
+  );
+
+  $form['actions'] = array('#type' => 'actions');
+
+  $form['actions']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Confirm'),
+  );
+
+  $form['actions']['cancel'] = array(
+    '#type' => 'link',
+    '#title' => t('Cancel'),
+    '#href' => 'admin/tripal/views-integration/list',
+  );
+
+  // By default, render the form using theme_confirm_form().
+  if (!isset($form['#theme'])) {
+    $form['#theme'] = 'confirm_form';
+  }
+
+  return $form;
+}
+
+/**
+ * Purpose: Deletes ALL Tripal Views Integrations.  This
+ *   function is meant to be called from a menu item. After completion it
+ *   redirects the user to the views intergation page.
+ *
+ * @ingroup tripal_views
+ */
+function tripal_views_integration_delete_all_form_submit ($form, &$form_state) {
+
+  tripal_views_rebuild_views_integrations(TRUE);
+
+  $form_state['redirect'] = 'admin/tripal/views-integration/list';
+
+}
+
+/**
+ * Purpose: defines the web form used for specifing the base table, joins and
+ *   handlers when integrating a table with views.  This form is used for both
+ *   creating a new record and editing an existing record.
+ *
+ * @param $form_state
+ *    The form state which is passed automatically by drupal
+ *
+ * @param $setup_id
+ *    The unique setup for an integrated table.  This value is only set when
+ *    the form is used for updating an existing record.
+ *
+ * @return
+ *    A proper Drupal form associative array.
+ *
+ * D7 @todo: Add ability to manage custom fields
+ * D7 @todo: Update relationship handler to work with the new tripal_views_join method
+ *
+ * @ingroup tripal_views
+ */
+function tripal_views_integration_form($form, $form_state, $arg) {
+
+  $data = array();
+  $form['#cache'] = TRUE;
+  if (isset($form_state['build_info']['args'][0])) {
+    $setup_id = $form_state['build_info']['args'][0];
+  }
+  else {
+    $setup_id = NULL;
+  }
+
+  // if Ajax is triggered to change the fields table
+  // then make some tweaks before the form is rendered
+  if (isset($form_state['triggering_element'])) {
+
+    $triggering_element = $form_state['triggering_element']['#name'];
+    if (($triggering_element == 'table_name' OR $triggering_element == 'mview_id')) {
+      $form_state['values'][$triggering_element] = $form_state['triggering_element']['#value'];
+      $setup_id = NULL;
+    }
+  }
+
+  // if a setup_id is provided then we want to get the form defaults
+  $setup_obj = array();
+  if (isset($setup_id)) {
+
+    // get the default setup values
+    $sql = "SELECT * FROM {tripal_views} WHERE setup_id = :setup";
+    $setup_obj = db_query($sql, array(':setup' => $setup_id));
+    $setup_obj = $setup_obj->fetchObject();
+    $mview_id = $setup_obj->mview_id;
+    $table_name = $setup_obj->table_name;
+    $form_state['values']['mview_id'] = $mview_id;
+    $form_state['values']['table_name'] = $table_name;
+
+    // get the default field name/description
+    $sql = "SELECT * FROM {tripal_views_field} WHERE setup_id=:setup";
+    $query = db_query($sql, array(':setup' => $setup_id));
+    $default_fields = array();
+    foreach ($query as $field) {
+      $default_fields[$field->column_name]['name'] = $field->name;
+      $default_fields[$field->column_name]['description'] = $field->description;
+    }
+
+    // get the default join settings and handlers
+    $sql = "SELECT * FROM {tripal_views_join} WHERE setup_id = :setup";
+    $query = db_query($sql, array(':setup' => $setup_id));
+    $default_joins = array();
+    foreach ($query as $join) {
+      $default_joins[$join->base_field]['left_table'] = $join->left_table;
+      $default_joins[$join->base_field]['left_field'] = $join->left_field;
+    }
+
+    // get the default handlers
+    $sql = "SELECT * FROM {tripal_views_handlers} WHERE setup_id = :setup";
+    $query = db_query($sql, array(':setup' => $setup_id));
+    $default_handlers = array();
+    foreach ($query as $handler) {
+      $default_handlers[$handler->column_name][$handler->handler_type]['handler_name'] = $handler->handler_name;
+      $default_handlers[$handler->column_name][$handler->handler_type]['arguments'] = $handler->arguments;
+    }
+
+    // get the default join handlers
+    $sql = "SELECT * FROM {tripal_views_join} WHERE setup_id = :setup";
+    $query = db_query($sql, array(':setup' => $setup_id));
+    foreach ($query as $handler) {
+      $default_handlers[$handler->base_field]['join']['handler_name'] = $handler->handler;
+      //$default_handlers[$handler->base_field]['join']['arguments'] = $handler->arguments;
+    }
+
+    // add in the setup_id for the form so we know this is an update not an insert
+    $form['setup_id'] = array(
+       '#type' => 'hidden',
+       '#value' => $setup_id,
+    );
+
+  }
+
+  // add a fieldset for the MView & Chado table selectors
+  $form['base_table_type'] = array(
+    '#type' => 'fieldset',
+    '#title' => 'Base Table',
+    '#description' => 'Please select either a materialized view or a Chado table for integration with '.
+                       'Drupal Views.  In Drupal Views terminology, the selected table becomes the "base table". '.
+                       'After you select a table from either list, the fields from that table will appear below '.
+                       'and you can specify other tables to join with and handlers.',
+  );
+
+  // build the form element for the Chado tables
+  $chado_tables = chado_get_table_names(TRUE);
+  $chado_tables = array_merge(array('Select'), $chado_tables);
+  $default = '';
+  if ($setup_id) {
+    $default = (!$setup_obj->mview_id) ? $setup_obj->table_name : '';
+  }
+  $form['base_table_type']['table_name'] = array(
+    '#title' => t('Chado/Custom Table'),
+    '#type' => 'select',
+    '#options' => $chado_tables,
+    '#description' => t('Tables from Chado, custom tables and materialized view tables (non-legacy MViews) can be selected for integration.'),
+    '#default_value' => $default,
+    '#ajax' => array(
+       //D6: 'path' => 'tripal/views-integration/ajax/view_setup_table',
+       'callback' => 'tripal_views_integration_ajax_view_setup_table',
+       'wrapper' => 'fieldset-table-rows-wrapper',
+       'effect' => 'fade',
+       'event' => 'change',
+       'method' => 'replace',
+    ),
+  );
+
+
+  // build the form element that lists the materialized views
+  // D7 TODO: Check DBTNG changes work
+  $query = db_query("SELECT mview_id, name FROM {tripal_mviews} WHERE mv_schema is NULL or mv_schema = '' ORDER BY name");
+  $mview_tables = array();
+  $mview_tables['0'] = 'Select';
+  foreach ($query as $mview) {
+    $mview_tables[$mview->mview_id] = $mview->name;
+  }
+  $default = '';
+  if ($setup_id && isset($setup_obj->mview_id)) {
+    $default = $setup_obj->mview_id;
+  }
+  $form['base_table_type']['mview_id'] = array(
+    '#title' => t('Legacy Materialized View'),
+    '#type' => 'select',
+    '#options' => $mview_tables,
+    '#description' => 'Which materialized view to use.',
+    '#default_value' => $default,
+    '#ajax' => array(
+       //D6: 'path' => 'tripal/views-integration/ajax/view_setup_table',
+       'callback' => 'tripal_views_integration_ajax_view_setup_table',
+       'wrapper' => 'fieldset-table-rows-wrapper',
+       'effect' => 'fade',
+       'event' => 'change',
+       'method' => 'replace',
+    ),
+  );
+
+  $form['views_type'] = array(
+    '#type' => 'fieldset',
+    '#title' => 'View Type',
+    '#description' => 'Here you can provide the "type" of View you want to create.',
+  );
+
+  // field for the name of the
+  $default = '';
+  if ($setup_id && isset($setup_obj->name)) {
+    $default = $setup_obj->name;
+  }
+  $form['views_type']['row_name'] = array(
+    '#title' => t('View Type Name'),
+    '#type' => 'textfield',
+    '#default_value' => $default,
+    '#size' => 60,
+    '#maxlength' => 128,
+    '#description' => 'Provide the view type name.  This is the name that will appear in '.
+                      'the Drupal Views interface when adding a new view.  The view type name '.
+                      'must be unique.',
+    '#required' => TRUE,
+  );
+
+  if (isset($setup_id)) {
+    $form['row_name']['#attributes'] = array('readonly' => 'readonly');
+  }
+
+  $priorities = array();
+  foreach (range(-10, 10) as $v) {
+    $priorities[$v] = (string) $v;
+  }
+  $default = -1;
+  if ($setup_id && isset($setup_obj->priority)) {
+    $default = $setup_obj->priority;
+    if ($setup_obj->priority >= 9) {
+      drupal_set_message('You are editing a default views integration. To ensure your changes
+        are used, change the priority to -10.', 'warning');
+    }
+  }
+  $form['views_type']['row_priority'] = array(
+    '#type' => 'select',
+    '#title' => t('Priority'),
+    '#description' => t('The level of priority your Views integration has in relation to the '
+      .'default core and module definitions. The views integration definition with the '
+      .'lightest priority will be used. For example, if there is a definition created by '
+      .'core with a priority of 10 and another by a custom module of 5 and yours is -1 then '
+      .'you definition will be used for that table because -1 is lighter then both 5 and 10.'),
+    '#options' => $priorities,
+    '#default_value' => $default,
+  );
+
+  $default = true;
+  if ($setup_id && isset($setup_obj->priority)) {
+    $default = ($setup_obj->priority >= 9) ? true : false;
+  }
+  $form['views_type']['new_integration'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Create a New Tripal Views Integration Record'),
+    '#description' => t('If this checkbox is checked then a new tripal views integration '
+      .'will be created rather then overriding the current one with your changes. This '
+      .'especially important if you are editing one of the default views integrations '
+      .'(ie: if the original priority was either 10 or 9).'),
+    '#default_value' => $default,
+  );
+
+  $default = true;
+  if ($setup_id && isset($setup_obj->base_table)) {
+    $default = $setup_obj->base_table;
+  }
+  $form['views_type']['base_table'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Base Table?'),
+    '#description' => t('If you want this table to show up as one of the options in the '
+      . 'add view page, then check this checkbox. It allows you to create listings '
+      . 'primarily from this table'),
+    '#default_value' => $default,
+  );
+
+  $default = '';
+  if ($setup_id && isset($setup_obj->comment)) {
+    $default = $setup_obj->comment;
+  }
+  $form['views_type']['row_description'] = array(
+    '#title' => t('Comment'),
+    '#type' => 'textarea',
+    '#description' => '(Optional). Provide any details regarding this setup you would like. This '.
+                      'description will appear when selecting a type for a new Drupal View',
+    '#required' => FALSE,
+    '#default_value' => $default,
+  );
+
+  // we need a div block where the table fields will get put when the
+  // AHAH callback is made
+  $form['view_setup_table'] = array(
+    '#type' => 'item',
+    '#prefix' => '<div id="fieldset-table-rows-wrapper">',
+    '#suffix' => '</div>',
+  );
+
+
+  // add the fieldset for the table fields, but only if the $mview_id or $table_name
+  // is set. The only times these values are set is if we're editing an existing
+  // record or if the AHAH callback is being made.
+  if (isset($form_state['values']['mview_id']) or isset($form_state['values']['table_name'])) {
+    $mview_id = $form_state['values']['mview_id'];
+    $table_name = $form_state['values']['table_name'];
+    $form['view_setup_table'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Table Fields'),
+      '#prefix' => '<div id="fieldset-table-rows-wrapper">',
+      '#suffix' => '</div>',
+      '#collapsible' => TRUE
+    );
+
+    // get the columns in this materialized view.  They are separated by commas
+    // where the first word is the column name and the rest is the type
+    $columns = array();
+    if ($mview_id) {
+      // D7 TODO: Check DBTNG changes work
+      $sql = "SELECT mv_specs FROM {tripal_mviews} WHERE mview_id = :id";
+      $mview = db_query($sql, array(':id' => $mview_id));
+      $mview = $mview->fetchObject();
+      $columns = explode(",", $mview->mv_specs);
+    }
+    else {
+      $table_desc = chado_get_schema($table_name);
+      if ($table_desc) {
+        $fields = $table_desc['fields'];
+        // iterate through the columns and build the format
+        // compatible with the code below. The column name is first followed
+        // by the type with a separating space
+        foreach ($fields as $column => $attrs) {
+          $columns[] = "$column " . $attrs['type'];
+        }
+      }
+    }
+
+    $i=1;
+    $form['view_setup_table']["instructions"] = array(
+         '#type' => 'markup',
+         '#value' => filter_xss("Select an optional table to which the fields of the ".
+                     "materialized view can join.  If a field does not need to ".
+                     "join you may leave the selection blank."),
+    );
+    $data['field_types'] = array();
+
+    $form['view_setup_table']['header'] = array(
+      '#type' => 'markup',
+      '#prefix' => '<div class="joins-new-row field-headers">',
+      '#suffix' => '</div>',
+    );
+
+    $form['view_setup_table']['header']['column-1'] = array(
+         '#type' => 'markup',
+         '#prefix' => "<div class=\"column-one\">",
+         '#suffix' => "</div>",
+         '#markup' => 'Field'
+    );
+
+    $form['view_setup_table']['header']['column-2'] = array(
+         '#type' => 'markup',
+         '#prefix' => "<div class=\"column-two\">",
+         '#suffix' => "</div>",
+         '#markup' => 'Labels'
+    );
+
+    $form['view_setup_table']['header']['column-3'] = array(
+         '#type' => 'markup',
+         '#prefix' => "<div class=\"column-three\">",
+         '#suffix' => "</div>",
+         '#markup' => ''
+    );
+
+    $form['view_setup_table']['header']['column-4'] = array(
+         '#type' => 'markup',
+         '#prefix' => "<div class=\"column-four\">",
+         '#suffix' => "</div>",
+         '#markup' => 'Handlers'
+    );
+
+    // get the list of chado tables to join on
+    $chado_join_tables = chado_get_table_names(TRUE);
+    $chado_join_tables = array_merge(array('Select a Join Table'), $chado_join_tables);
+
+    // get list of all handlers
+    $all_handlers = tripal_views_integration_discover_handlers();
+    $handlers_fields = array(0 => "Select a field handler");
+    $handlers_filters = array(0 => "Select a filter handler");
+    $handlers_sort = array(0 => "Select a sort handler");
+    $handlers_argument = array(0 => "Select an argument handler");
+    $handlers_join = array(0 => "Select a join handler");
+    $handlers_rel = array(0 => "Select a relationship handler");
+    foreach ($all_handlers as $handler) {
+      if (preg_match("/views_handler_field/", $handler)) {
+        $handlers_fields[$handler] = $handler;
+      }
+      if (preg_match("/views_handler_filter/", $handler)) {
+        $handlers_filters[$handler] = $handler;
+      }
+      if (preg_match("/views_handler_sort/", $handler)) {
+        $handlers_sort[$handler] = $handler;
+      }
+      if (preg_match("/views_handler_argument/", $handler)) {
+        $handlers_argument[$handler] = $handler;
+      }
+      if (preg_match("/_join/", $handler)) {
+        $handlers_join[$handler] = $handler;
+      }
+      if (preg_match("/views_handler_relationship/", $handler)) {
+        $handlers_rel[$handler] = $handler;
+      }
+    }
+
+    // generate a unique $table_id for keeping track of the table
+    if ($mview_id) {
+      $table_id = $mview_id;
+    }
+    else {
+      $table_id = $table_name;
+    }
+
+    // Per Row (Fields) --------------
+    // now iterate through the columns of the materialized view or
+    // chado table and generate the join and handler fields
+    foreach ($columns as $column) {
+      $column = trim($column);  // trim trailing and leading spaces
+      preg_match("/^(.*?)\ (.*?)$/", $column, $matches);
+      $column_name = $matches[1];
+      $column_type = $matches[2];
+
+      $form['view_setup_table']["$table_id-$i"] = array(
+           '#type' => 'markup',
+           '#prefix' => "<div class=\"fields-new-row\">",
+           '#suffix' => "</div>",
+           '#value' => filter_xss('')
+      );
+
+      // COLUMN I
+      $form['view_setup_table']["$table_id-$i"]["fields_name_$table_id-$i"] = array(
+        '#type' => 'item',
+        '#prefix' => "<div class=\"column-one\">",
+        '#markup' => '<span class="column-name">' . filter_xss($column_name) . '</span>'.
+                    '<br /><span class="column-type">' . filter_xss($column_type) . '</span>',
+        '#suffix' => "</div>",
+      );
+      $data['field_types'][$column_name] = $column_type;
+
+      // COLUMN II
+      $form['view_setup_table']["$table_id-$i"]['column-2'] = array(
+           '#type' => 'markup',
+           '#prefix' => "<div class=\"column-two\">",
+           '#suffix' => "</div>",
+           '#value' => filter_xss('')
+      );
+
+      // set the default values for the human-readable name and description
+      $default_name = '';
+      $default_descrip = '';
+      if (isset($setup_id) && !isset($form_state['values']["fields_readable_name_$table_id-$i"])) {
+        $default_name = $default_fields[$column_name]['name'];
+        $default_descrip = $default_fields[$column_name]['description'];
+      }
+      elseif (isset($form_state['values']["fields_readable_name_$table_id-$i"])) {
+        $default_name = $form_state['values']["fields_readable_name_$table_id-$i"];
+        $default_descrip = $form_state['values']["fields_description_$table_id-$i"];
+      }
+      else {
+        $default_name = ucwords(str_replace('_',' ', $column_name));
+        $default_descrip = 'TODO: please describe this field!';
+      }
+      $form['view_setup_table']["$table_id-$i"]['column-2']["fields_readable_name_$table_id-$i"] = array(
+        '#type' => 'textfield',
+        '#title' => 'Human-Readable Name',
+        '#description' => 'This is the name of the field in the Views UI',
+        '#required' => TRUE,
+        '#default_value' => $default_name,
+        '#size' => 42,
+      );
+
+      $form['view_setup_table']["$table_id-$i"]['column-2']["fields_description_$table_id-$i"] = array(
+        '#type' => 'textarea',
+        '#title' => 'Short Description',
+        '#description' => 'This is the field help in the Views UI',
+        '#required' => TRUE,
+        '#cols' => 42,
+        '#rows' => 3,
+        '#default_value' => $default_descrip,
+      );
+
+      // COLUMN III
+      $form['view_setup_table']["$table_id-$i"]['column-3'] = array(
+           '#type' => 'markup',
+           '#prefix' => "<div class=\"column-three\">",
+           '#suffix' => "</div>",
+           '#value' => filter_xss('')
+      );
+
+      // COLUMN 4
+      $form['view_setup_table']["$table_id-$i"]['column-4'] = array(
+        '#type' => 'markup',
+        '#prefix' => "<div class=\"column-four\">",
+        '#suffix' => "</div>",
+        '#value' => filter_xss('')
+      );
+
+      // create the handler fields
+      $default_field_handler = 0;
+      if (isset($setup_id) && !isset($form_state['values']["fields_field_handler_$table_id-$i"])) {
+        $default_field_handler = $default_handlers[$column_name]['field']['handler_name'];
+        $form_state['values']["fields_field_handler_$table_id-$i"] = $default_field_handler;
+      }
+      else {
+        $default_field_handler = $form_state['values']["fields_field_handler_$table_id-$i"];
+        if (!$default_field_handler) {
+          if ($column_type == 'integer' or $column_type == 'int' or $column_type == 'serial') {
+            $default_field_handler = 'chado_views_handler_field_numeric';
+          }
+          elseif (preg_match("/character varying/", $column_type) or $column_type == 'char' or $column_type == 'text' or $column_type == 'varchar') {
+            $default_field_handler = 'chado_views_handler_field';
+          }
+          elseif ($column_type == 'boolean') {
+            $default_field_handler = 'chado_views_handler_field_boolean';
+          }
+          elseif ($column_type == 'float') {
+            $default_field_handler = 'chado_views_handler_field_numeric';
+          }
+          elseif ($column_type == 'datetime') {
+            $default_field_handler = 'chado_views_handler_field_date';
+          }
+        }
+      }
+
+      $form['view_setup_table']["$table_id-$i"]['column-4']["fields_field_handler_$table_id-$i"] = array(
+         '#type' => 'select',
+         '#prefix' => "<div class=\"fields-field-handler\">",
+         '#suffix' => "</div>",
+         '#options' => $handlers_fields,
+         '#required' => FALSE,
+         '#default_value' => $default_field_handler,
+      );
+
+      $default_filter_handler = 0;
+      if (isset($setup_id) && !isset($form_state['values']["fields_filter_handler_$table_id-$i"])) {
+        $default_filter_handler = $default_handlers[$column_name]['filter']['handler_name'];
+        $form_state['values']["fields_filter_handler_$table_id-$i"]= $default_filter_handler;
+      }
+      else {
+        $default_filter_handler = $form_state['values']["fields_filter_handler_$table_id-$i"];
+        if (!$default_filter_handler) {
+          if ($column_type == 'integer' or $column_type == 'int' or $column_type == 'serial') {
+            $default_filter_handler = 'chado_views_handler_filter_numeric';
+          }
+          elseif (preg_match("/^character varying/", $column_type) or $column_type == 'char' or $column_type == 'text' or $column_type == 'varchar') {
+            $default_filter_handler = 'chado_views_handler_filter_string';
+          }
+          elseif ($column_type == 'boolean') {
+            $default_filter_handler = 'chado_views_handler_filter_boolean';
+          }
+          elseif ($column_type == 'float') {
+            $default_filter_handler = 'chado_views_handler_filter_float';
+          }
+          elseif ($column_type == 'datetime') {
+            $default_filter_handler = 'chado_views_handler_filter_date';
+          }
+        }
+      }
+      $form['view_setup_table']["$table_id-$i"]['column-4']["fields_filter_handler_$table_id-$i"] = array(
+        '#type' => 'select',
+        '#prefix' => "<div class=\"fields-filter-handler\">",
+        '#suffix' => "</div>",
+        '#options' => $handlers_filters,
+        '#required' => FALSE,
+        '#default_value' => $default_filter_handler,
+      );
+
+      $default_sort_handler = 0;
+      if (isset($setup_id) && !isset($form_state['values']["fields_sort_handler_$table_id-$i"])) {
+        $default_sort_handler = $default_handlers[$column_name]['sort']['handler_name'];
+        $form_state['values']["fields_sort_handler_$table_id-$i"] = $default_sort_handler;
+      }
+      else {
+        $default_sort_handler = $form_state['values']["fields_sort_handler_$table_id-$i"];
+        if (!$default_sort_handler) {
+          if ($column_type == 'integer' or $column_type == 'int' or $column_type == 'serial') {
+            $default_sort_handler = 'chado_views_handler_sort';
+          }
+          elseif (preg_match("/character varying/", $column_type) or $column_type == 'char' or $column_type == 'text' or $column_type == 'varchar') {
+            $default_sort_handler = 'chado_views_handler_sort';
+          }
+          elseif ($column_type == 'boolean') {
+            $default_sort_handler = 'chado_views_handler_sort';
+          }
+          elseif ($column_type == 'float') {
+            $default_sort_handler = 'chado_views_handler_sort';
+          }
+          elseif ($column_type == 'datetime') {
+            $default_sort_handler = 'chado_views_handler_sort_date';
+          }
+        }
+      }
+      $form['view_setup_table']["$table_id-$i"]['column-4']["fields_sort_handler_$table_id-$i"] = array(
+        '#type' => 'select',
+        '#prefix' => "<div class=\"fields-sort-handler\">",
+        '#suffix' => "</div>",
+        '#options' => $handlers_sort,
+        '#required' => FALSE,
+        '#default_value' => $default_sort_handler,
+      );
+
+      $default_argument_handler = 0;
+      if (isset($setup_id)
+        && !isset($form_state['values']["fields_argument_handler_$table_id-$i"])
+        && isset($default_handlers[$column_name]['argument']))
+      {
+        $default_argument_handler = $default_handlers[$column_name]['argument']['handler_name'];
+        $form_state['values']["fields_argument_handler_$table_id-$i"]=$default_argument_handler ;
+      }
+      else {
+        if (isset($form_state['values']["fields_argument_handler_$table_id-$i"])) {
+          $default_argument_handler = $form_state['values']["fields_argument_handler_$table_id-$i"];
+        }
+        if (!$default_argument_handler) {
+          if ($column_type == 'integer' or $column_type == 'int' or $column_type == 'serial') {
+            $default_argument_handler = 'views_handler_argument_numeric';
+          }
+          elseif (preg_match("/character varying/", $column_type) or $column_type == 'char' or $column_type == 'text' or $column_type == 'varchar') {
+            $default_argument_handler = 'views_handler_argument_string';
+          }
+          elseif ($column_type == 'boolean') {
+            $default_argument_handler = 'views_handler_argument_numeric';
+          }
+          elseif ($column_type == 'float') {
+            $default_argument_handler = 'views_handler_argument_numeric';
+          }
+          elseif ($column_type == 'datetime') {
+            $default_argument_handler = 'views_handler_argument_date';
+          }
+        }
+      }
+      $form['view_setup_table']["$table_id-$i"]['column-4']["fields_argument_handler_$table_id-$i"] = array(
+        '#type' => 'select',
+        '#prefix' => "<div class=\"fields-argument-handler\">",
+        '#suffix' => "</div>",
+        '#options' => $handlers_argument,
+        '#required' => FALSE,
+        '#default_value' => $default_argument_handler,
+      );
+
+      $i++;
+    }
+
+    $form['view_setup_join'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Joins & Relationships'),
+      '#prefix' => '<div id="fieldset-join-rows-wrapper">',
+      '#suffix' => '</div>',
+      '#description' => t('Below is a list of the joins/relationships between the '
+        . 'current base table and other chado tables.'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE
+    );
+
+    $form['view_setup_join']['header'] = array(
+      '#type' => 'markup',
+      '#prefix' => '<div class="joins-new-row field-headers">',
+      '#suffix' => '</div>',
+    );
+
+    $form['view_setup_join']['header']['column-1'] = array(
+         '#type' => 'markup',
+         '#prefix' => "<div class=\"join-column-one\">",
+         '#suffix' => "</div>",
+         '#markup' => 'Base'
+    );
+
+    $form['view_setup_join']['header']['column-2'] = array(
+         '#type' => 'markup',
+         '#prefix' => "<div class=\"join-column-two\">",
+         '#suffix' => "</div>",
+         '#markup' => 'Handlers'
+    );
+
+    $form['view_setup_join']['header']['column-3'] = array(
+         '#type' => 'markup',
+         '#prefix' => "<div class=\"join-column-three\">",
+         '#suffix' => "</div>",
+         '#markup' => 'Joined to'
+    );
+
+    $base_field_options = array('Select the Base Column');
+    $table_desc = chado_get_schema($table_name);
+    foreach ($table_desc['fields'] as $column => $def) {
+      $base_field_options[$column] = $column;
+    }
+    $chado_join_tables[0] = 'Select the Left Table';
+    unset($handlers_join[0]);
+
+    $query = db_select('tripal_views_join','tvj');
+    $query->fields('tvj')
+      ->condition('tvj.setup_id',$setup_id,'=')
+      ->orderBy('tvj.relationship_only','ASC')
+      ->orderBy('tvj.base_field', 'ASC')
+      ->orderBy('tvj.left_table', 'ASC');
+    foreach ($query->execute() as $i => $result) {
+      $form['view_setup_join']["$table_id-$i"] = array(
+           '#type' => 'markup',
+           '#prefix' => "<div class=\"joins-new-row\">",
+           '#suffix' => "</div>",
+           '#value' => filter_xss('')
+      );
+
+      // COLUMN I
+      $form['view_setup_join']["$table_id-$i"]['column-1'] = array(
+           '#type' => 'markup',
+           '#prefix' => "<div class=\"join-column-one\">",
+           '#suffix' => "</div>",
+      );
+
+      $form['view_setup_join']["$table_id-$i"]['column-1']['join_base_table'] = array(
+        '#type' => 'item',
+        '#markup' => '<span class="column-name">' . filter_xss($result->base_table) . '</span>'
+      );
+
+      $form['view_setup_join']["$table_id-$i"]['column-1']["join_base_table-$i"] = array(
+        '#type' => 'hidden',
+        '#value' => $result->base_table
+      );
+
+      $form['view_setup_join']["$table_id-$i"]['column-1']["join_base_field-$i"] = array(
+        '#type' => 'select',
+        '#options' => $base_field_options,
+        '#required' => FALSE,
+        '#default_value' => $result->base_field
+      );
+
+      // COLUMN II
+      $form['view_setup_join']["$table_id-$i"]['column-2'] = array(
+           '#type' => 'markup',
+           '#prefix' => "<div class=\"join-column-two\">",
+           '#suffix' => "</div>",
+           '#value' => filter_xss('')
+      );
+
+      $form['view_setup_join']["$table_id-$i"]['column-2']["join_join_handler-$i"] = array(
+        '#type' => 'select',
+        '#prefix' => "<div class=\"fields-join-handler\">",
+        '#suffix' => "</div>",
+        '#options' => $handlers_join,
+        '#required' => FALSE,
+        '#default_value' => $result->handler,
+      );
+
+      $form['view_setup_join']["$table_id-$i"]['column-2']["join_relationship_handler-$i"] = array(
+        '#type' => 'select',
+        '#prefix' => "<div class=\"fields-relationship-handler\">",
+        '#suffix' => "</div>",
+        '#options' => $handlers_rel,
+        '#required' => FALSE,
+        '#default_value' => $result->relationship_handler,
+      );
+
+      $form['view_setup_join']["$table_id-$i"]['column-2']["join_relationship_only-$i"] = array(
+        '#type' => 'checkbox',
+        '#title' => 'Relationship Only?',
+        '#default_value' => $result->relationship_only
+      );
+
+      // COLUMN III
+      $form['view_setup_join']["$table_id-$i"]['column-3'] = array(
+           '#type' => 'markup',
+           '#prefix' => "<div class=\"join-column-three\">",
+           '#suffix' => "</div>",
+           '#value' => filter_xss('')
+      );
+
+      $form['view_setup_join']["$table_id-$i"]['column-3']["join_left_table-$i"] = array(
+        '#type' => 'select',
+        '#options' => $chado_join_tables,
+        '#default_value' => $result->left_table,
+      );
+
+      $columns = array();
+      if ($result->left_table) {
+        // get the table description
+        $table_desc = chado_get_schema($result->left_table);
+        foreach ($table_desc['fields'] as $column => $def) {
+          $columns[$column] = $column;
+        }
+      }
+      else {
+        $columns = array('Select Left Column');
+      }
+      $form['view_setup_join']["$table_id-$i"]['column-3']["join_left_field-$i"] = array(
+        '#type' => 'select',
+        '#prefix' => "  <div id=\"fields-column-join-column-$table_id-$i\" class=\"fields-column-join-column\">",
+        '#suffix' => "</div>",
+        '#options' => $columns,
+        '#required' => FALSE,
+        '#default_value' => $result->left_field
+      );
+    }
+
+    $form['num_joins'] = array(
+      '#type' => 'hidden',
+      '#value' => $i
+    );
+
+    $form['save'] = array(
+      '#type'  => 'submit',
+      '#value' => t('Save'),
+    );
+
+    $data['row_count'] = $i - 1;
+  } //end of if table/mview
+
+  //use this to put values into $form_state['values']
+  $form['data'] = array();
+
+  // Ensure that we don't store an array
+  // since we will get a check_plain:htmlspecial_characters error if we do
+  foreach ($data as $key => $value) {
+    if (is_array($value)) {
+      $form['data'][$key] = array(
+        '#type' => 'hidden',
+        '#value' => serialize($value),
+      );
+    }
+    else {
+      $form['data'][$key] = array(
+        '#type' => 'hidden',
+        '#value' => $value,
+      );
+    }
+  }
+
+  $form['#redirect'] = 'admin/tripal/views-integration/list';
+
+  return $form;
+}
+
+/**
+ * Purpose: validates the tripal_views_integration_form after submission
+ *
+ * @param $form
+ *    The form object which is passed automatically by drupal
+ *
+ * @param $form_state
+ *    The form state pbject which is passed automatically by drupal
+ *
+ * @ingroup tripal_views
+ */
+function tripal_views_integration_form_validate($form, &$form_state) {
+  $name_array = explode(" ", $form_state['values']['row_name']);
+  $mview_id = $form_state['values']['mview_id'];
+  $table_name = $form_state['values']['table_name'];
+
+//  if (count($name_array) > 1) {
+//    form_set_error($form_state['values']['row_name'], 'The View type name must be a single word only.');
+//  }
+  if ($mview_id and $table_name) {
+    form_set_error('mview_id', 'Please select either a materialized view or a Chado table but not both');
+  }
+  if (!$mview_id and !$table_name) {
+    form_set_error('mview_id', 'Please select either a materialized view or a Chado table');
+  }
+
+  // Ensure that users don't override the default integrations
+  if ($form_state['values']['row_priority'] >= 9) {
+    form_set_error('row_priority', 'A priority of 10 or 9 is reserved for default tripal '
+      .'views integrations created by core modules. Please set the priority between '
+      .'0 and -10 to ensure your changes are used rather over the defaults.');
+  }
+}
+
+/**
+ * Purpose: inserts or updates the record in the tripal views integration
+ *   tables.  This function is only called if validation is passed.
+ *
+ * @param $form
+ *    The form object which is passed automatically by drupal
+ *
+ * @param $form_state
+ *    The form state pbject which is passed automatically by drupal
+ *
+ * @ingroup tripal_views
+ */
+function tripal_views_integration_form_submit($form, &$form_state) {
+  $name = $form_state['values']['row_name'];
+  $mview_id = $form_state['values']['mview_id'];
+  $table_name = $form_state['values']['table_name'];
+  $setup_id = $form_state['values']['setup_id'];
+  $priority = $form_state['values']['row_priority'];
+  $comment = $form_state['values']['row_description'];
+
+  // get details about this mview
+  if ($mview_id) {
+    // D7 TODO: Check DBTNG changes work
+    $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = :id";
+    $mview = db_query($sql, array(':id' => $mview_id));
+    $mview = $mview->fetchObject();
+    $table_name = $mview->mv_table;
+    $table_id = $mview_id;
+    $type = 'mview';
+  }
+  else {
+    $type = 'chado';
+    $table_id = $table_name;
+  }
+
+  // If this is for a materialized view then we want to add/update that record
+  $tripal_views_record = array();
+  if ($mview_id) {
+    // get details about this mview
+    // D7 TODO: Check DBTNG changes work
+    $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = :id";
+    $mview = db_query($sql, array(':id' => $mview_id));
+    $mview = $mview->fetchObject();
+
+    // build the record for insert/update
+    $tripal_views_record = array(
+     'mview_id' => $mview_id,
+     'table_name' => $mview->mv_table,
+     'name' => $name,
+     'priority' => $priority,
+     'comment' => $comment,
+     'base_table' => $form_state['values']['base_table']
+    );
+  }
+  // if a chado table then...
+  else {
+    // build the record for insert/update
+    $tripal_views_record = array(
+     'table_name' => $table_name,
+     'name' => $name,
+     'priority' => $priority,
+     'comment' => $comment,
+     'base_table' => $form_state['values']['base_table']
+    );
+  }
+
+  // perform the insert or update
+  if (!$setup_id) {  // this is an insert
+    if (!drupal_write_record('tripal_views', $tripal_views_record)) {
+      drupal_set_message(t("Failed to add record."), 'error');
+      return;
+    }
+  }
+  else {  // this is an update
+    // check to see if it was specified to create a new integration
+    if ($form_state['values']['new_integration']) {
+      $setup_id = NULL;
+      if (!drupal_write_record('tripal_views', $tripal_views_record)) {
+        drupal_set_message(t("Failed to add record."), 'error');
+        return;
+      }
+    }
+    else {
+      $tripal_views_record['setup_id'] = $setup_id;
+      if (!drupal_write_record('tripal_views', $tripal_views_record, array('setup_id'))) {
+        drupal_set_message(t("Failed to update record."), 'error');
+        return;
+      }
+    }
+  }
+
+  // if this is an update then clean out the existing joins and handlers so we can add new ones
+  if ($setup_id) {
+    db_query("DELETE FROM {tripal_views_field} WHERE setup_id = :setup", array(':setup' => $setup_id));
+    db_query("DELETE FROM {tripal_views_join} WHERE setup_id = :setup", array(':setup' => $setup_id));
+    db_query("DELETE FROM {tripal_views_handlers} WHERE setup_id = :setup", array(':setup' => $setup_id));
+  }
+
+  // iterate through the columns of the form and add
+  // the joins if provided, and the handlers
+  $i = 1;
+  foreach (unserialize($form_state['values']['field_types']) as $key => $value) {
+
+    // add the field definition
+    $view_field_record = array(
+      'setup_id' => $tripal_views_record['setup_id'],
+      'column_name' => $key,
+      'name' => $form_state['values']["fields_readable_name_$table_id-$i"],
+      'description' => $form_state['values']["fields_description_$table_id-$i"],
+      'type' => $value,
+    );
+    drupal_write_record('tripal_views_field', $view_field_record);
+
+    // add the hanlders
+    $handlers = array('filter', 'field', 'sort', 'argument');
+
+    foreach ($handlers as $handler) {
+      $handler_name = $form_state['values']["fields_" . $handler . "_handler_$table_id-$i"];
+      if ($handler_name) {
+        $handler_record = array(
+          'setup_id' => $tripal_views_record['setup_id'],
+          'column_name' => $key,
+          'handler_type' => $handler,
+          'handler_name' => $handler_name,
+        );
+        drupal_write_record('tripal_views_handlers', $handler_record);
+      }
+    }
+    $i++;
+  }
+
+  // Now add all the joins
+  for($i = 0; $i <= $form_state['values']['num_joins']; $i++) {
+    $join_record = array(
+      'setup_id' => $tripal_views_record['setup_id'],
+      'base_table' => $form_state['values']["join_base_table-$i"],
+      'base_field' => $form_state['values']["join_base_field-$i"],
+      'left_table' => $form_state['values']["join_left_table-$i"],
+      'left_field' => $form_state['values']["join_left_field-$i"],
+      'handler' => $form_state['values']["join_join_handler-$i"],
+      'relationship_handler' => $form_state['values']["join_relationship_handler-$i"],
+      'relationship_only' => $form_state['values']["join_relationship_only-$i"]
+    );
+    drupal_write_record('tripal_views_join', $join_record);
+  }
+
+  if ($setup_id) {
+    drupal_set_message(t('Record Updated'));
+  }
+  else {
+    drupal_set_message(t('Record Added'));
+  }
+
+  $form_state['redirect'] = 'admin/tripal/views-integration/list';
+
+  // now clear all the caches so that Drupal views picks up our chages
+  views_invalidate_cache();
+}
+
+/**
+ * Purpose: this function queries all modules currently enabled on the site
+ *   looking for custom handlers and returns a list of all available handerls.
+ *   The base View handlers are also included.
+ *
+ * @return
+ *   Returns an array of handler names
+ *
+ * @ingroup tripal_views
+ */
+function tripal_views_integration_discover_handlers() {
+
+  $handlers = array();
+
+  // Get handlers from all modules.
+  foreach (module_implements('views_handlers') as $module) {
+    $function = $module . '_views_handlers';
+    $result = $function();
+    if (!is_array($result)) {
+      continue;
+    }
+    foreach ($result['handlers'] as $handler => $parent) {
+      $handlers[] = $handler;
+    }
+  }
+
+  // these handlers are hard coded because I could not
+  // get the views_handlers() function to be called
+  // in the code above.  However, we will be creating
+  // Chado wrappers for many of these and once that work
+  // is done these will no longer be needed.
+
+  // argument handlers
+  $handlers[] = 'views_handler_argument';
+  $handlers[] = 'views_handler_argument_numeric';
+  $handlers[] = 'views_handler_argument_formula';
+  $handlers[] = 'views_handler_argument_date';
+  $handlers[] = 'views_handler_argument_string';
+  $handlers[] = 'views_handler_argument_many_to_one';
+  $handlers[] = 'views_handler_argument_null';
+
+  // field handlers
+  $handlers[] = 'views_handler_field';
+  $handlers[] = 'views_handler_field_date';
+  $handlers[] = 'views_handler_field_boolean';
+  $handlers[] = 'views_handler_field_markup';
+  $handlers[] = 'views_handler_field_xss';
+  $handlers[] = 'views_handler_field_url';
+  $handlers[] = 'views_handler_field_file_size';
+  $handlers[] = 'views_handler_field_prerender_list';
+  $handlers[] = 'views_handler_field_numeric';
+  $handlers[] = 'views_handler_field_custom';
+  $handlers[] = 'views_handler_field_counter';
+
+  // filter handlers
+  $handlers[] = 'views_handler_filter';
+  $handlers[] = 'views_handler_filter_equality';
+  $handlers[] = 'views_handler_filter_string';
+  $handlers[] = 'views_handler_filter_boolean_operator';
+  $handlers[] = 'views_handler_filter_boolean_operator_string';
+  $handlers[] = 'views_handler_filter_in_operator';
+  $handlers[] = 'views_handler_filter_numeric';
+  $handlers[] = 'views_handler_filter_float';
+  $handlers[] = 'views_handler_filter_date';
+  $handlers[] = 'views_handler_filter_many_to_one';
+
+  // relationship handlers
+  $handlers[] = 'views_handler_relationship';
+
+  // sort handlers
+  $handlers[] = 'views_handler_sort';
+  $handlers[] = 'views_handler_sort_formula';
+  $handlers[] = 'views_handler_sort_date';
+  $handlers[] = 'views_handler_sort_menu_hierarchy';
+  $handlers[] = 'views_handler_sort_random';
+
+  // join handler
+  $handlers[] = 'views_join';
+
+  return $handlers;
+}
+
+/*
+ * Ajax Callback: Tripal Views Integration Form
+ * Replaces the entire fields table when the table or materialized view is set/changed
+ *
+ * @ingroup tripal_views
+ */
+function tripal_views_integration_ajax_view_setup_table($form, $form_state) {
+  return $form['view_setup_table'];
+}
+
+/*
+ * Ajax Callback: Tripal Views Integration Form
+ * Replaces the join db field dropdown when the join table dropdown is changed
+ *
+ * @ingroup tripal_views
+ */
+function tripal_views_integration_ajax_join_field($form, $form_state) {
+
+  // Determine which row we are dealing with from the name of the triggering element
+  if (preg_match('/fields_join_(\w+-\d+)/', $form_state['triggering_element']['#name'], $matches)) {
+    $field = $matches[1];
+    $join_field = 'fields_join_column_' . $matches[1];
+    // return the form element to be updated
+    return $form['view_setup_table'][$field]['column-3'][$join_field];
+  }
+  else {
+    tripal_report_error('tripal_views', TRIPAL_ERROR,
+      'Tripal Views Integration Ajax failed due to being unable to determine which row needs updating', array());
+    return $form;
+  }
+}

+ 3 - 0
tripal_views/tripal_views.module

@@ -12,9 +12,12 @@
  * @}
  */
 
+require_once 'api/tripal_views.api.inc';
+
 require_once 'tripal_views.views.inc';
 
 require_once 'includes/tripal_views_integration.inc';
+require_once 'includes/tripal_views_integration_UI.inc';
 require_once 'includes/tripal_views_integration_port.inc';
 
 /**

+ 0 - 1
tripal_views/tripal_views.views.inc

@@ -4,7 +4,6 @@
  * Tripal Views Integration
  */
 
-include 'api/tripal_views.api.inc';
 include 'views/handlers/tripal_views_handler_area_action_links.inc';
 
 /**