Browse Source

Merge branch '7.x-2.x' of git.drupal.org:sandbox/spficklin/1337878 into 7.x-2.x

Stephen Ficklin 11 years ago
parent
commit
63ed8033a6

+ 204 - 63
tripal_core/api/tripal_core.DEPRECATED.inc

@@ -7,14 +7,16 @@
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_get_id_from_nid().
+ * This function has been replaced by chado_get_id_from_nid().
+ *
+ * @see chado_get_id_from_nid()
  */
-function chado_get_id_for_node($table, $nid) {
+function chado_get_id_for_node($table, $node) {
 
   tripal_report_error(
     'tripal_api',
     TRIPAL_NOTICE,
-    "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
+    "DEPRECATED: %old_function has been replaced with %new_function. The arguments have been changed slightly (ie: $nid instead of $node). Please update your code.",
     array(
       '%old_function'=>'chado_get_id_for_node',
       '%new_function' => 'chado_get_id_from_nid'
@@ -22,13 +24,15 @@ function chado_get_id_for_node($table, $nid) {
   );
 
   //New API Function
-  return chado_get_id_from_nid($table, $nid);
+  return chado_get_id_from_nid($table, $node->nid);
 }
 
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_get_nid_from_id().
+ * This function has been replaced by chado_get_nid_from_id().
+ *
+ * @see chado_get_nid_from_id().
  */
 function chado_get_node_id($table, $id) {
 
@@ -49,7 +53,9 @@ function chado_get_node_id($table, $id) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_cleanup_orphaned_nodes().
+ * This function has been replaced by chado_cleanup_orphaned_nodes().
+ *
+ * @see chado_cleanup_orphaned_nodes().
  */
 function tripal_core_chado_node_cleanup_orphaned($table, $job_id = NULL) {
 
@@ -70,7 +76,9 @@ function tripal_core_chado_node_cleanup_orphaned($table, $job_id = NULL) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_add_node_form_dbxrefs().
+ * This function has been replaced by chado_add_node_form_dbxrefs().
+ *
+ * @see chado_add_node_form_dbxrefs().
  */
 function chado_node_additional_dbxrefs_form(&$form, &$form_state, $details) {
 
@@ -91,7 +99,9 @@ function chado_node_additional_dbxrefs_form(&$form, &$form_state, $details) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_retrieve_node_form_dbxrefs().
+ * This function has been replaced by chado_retrieve_node_form_dbxrefs().
+ *
+ * @see chado_retrieve_node_form_dbxrefs().
  */
 function chado_node_additional_dbxrefs_form_retreive($node) {
 
@@ -112,7 +122,9 @@ function chado_node_additional_dbxrefs_form_retreive($node) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_update_node_form_dbxrefs().
+ * This function has been replaced by chado_update_node_form_dbxrefs().
+ *
+ * @see chado_update_node_form_dbxrefs().
  */
 function chado_node_additional_dbxrefs_form_update_dbxrefs($node, $details, $retrieved_dbxrefs = FALSE) {
 
@@ -133,7 +145,9 @@ function chado_node_additional_dbxrefs_form_update_dbxrefs($node, $details, $ret
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_add_node_form_properties().
+ * This function has been replaced by chado_add_node_form_properties().
+ *
+ * @see chado_add_node_form_properties().
  */
 function chado_node_properties_form($form, $form_state, $details) {
 
@@ -154,7 +168,9 @@ function chado_node_properties_form($form, $form_state, $details) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_retrieve_node_form_properties().
+ * This function has been replaced by chado_retrieve_node_form_properties().
+ *
+ * @see chado_retrieve_node_form_properties().
  */
 function chado_node_properties_form_retreive($node) {
 
@@ -175,7 +191,9 @@ function chado_node_properties_form_retreive($node) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_update_node_form_properties().
+ * This function has been replaced by chado_update_node_form_properties().
+ *
+ * @see chado_update_node_form_properties().
  */
 function chado_node_properties_form_update_properties($node, $details, $retrieved_properties = FALSE) {
 
@@ -196,7 +214,9 @@ function chado_node_properties_form_update_properties($node, $details, $retrieve
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_add_node_form_relationships().
+ * This function has been replaced by chado_add_node_form_relationships().
+ *
+ * @see chado_add_node_form_relationships().
  */
 function chado_node_relationships_form(&$form, &$form_state, $details) {
 
@@ -217,7 +237,9 @@ function chado_node_relationships_form(&$form, &$form_state, $details) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_retrieve_node_form_relationships().
+ * This function has been replaced by chado_retrieve_node_form_relationships().
+ *
+ * @see chado_retrieve_node_form_relationships().
  */
 function chado_node_relationships_form_retreive($node) {
 
@@ -238,7 +260,9 @@ function chado_node_relationships_form_retreive($node) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_update_node_form_relationships().
+ * This function has been replaced by chado_update_node_form_relationships().
+ *
+ * @see chado_update_node_form_relationships().
  */
 function chado_node_relationships_form_update_relationships($node, $details, $retrieved_relationships = FALSE) {
 
@@ -259,7 +283,9 @@ function chado_node_relationships_form_update_relationships($node, $details, $re
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_node_sync_form().
+ * This function has been replaced by chado_node_sync_form().
+ *
+ * @see chado_node_sync_form().
  */
 function tripal_core_chado_node_sync_form($form, &$form_state) {
 
@@ -280,7 +306,9 @@ function tripal_core_chado_node_sync_form($form, &$form_state) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_node_sync_records().
+ * This function has been replaced by chado_node_sync_records().
+ *
+ * @see chado_node_sync_records().
  */
 function tripal_core_chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id = FALSE,
     $types = array(), $ids = array(), $job_id = NULL) {
@@ -320,7 +348,9 @@ function tripal_core_is_tripal_node_type() {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_schema_get_foreign_key().
+ * This function has been replaced by chado_schema_get_foreign_key().
+ *
+ * @see chado_schema_get_foreign_key().
  */
 function tripal_core_chado_get_foreign_key($table_desc, $field, $values, $options = NULL) {
 
@@ -341,7 +371,9 @@ function tripal_core_chado_get_foreign_key($table_desc, $field, $values, $option
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_delete_record().
+ * This function has been replaced by chado_delete_record().
+ *
+ * @see chado_delete_record().
  */
 function tripal_core_chado_delete($table, $match, $options = NULL) {
 
@@ -362,7 +394,9 @@ function tripal_core_chado_delete($table, $match, $options = NULL) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_expand_var().
+ * This function has been replaced by chado_expand_var().
+ *
+ * @see chado_expand_var().
  */
 function tripal_core_expand_chado_vars($object, $type, $to_expand, $table_options = array()) {
 
@@ -383,7 +417,9 @@ function tripal_core_expand_chado_vars($object, $type, $to_expand, $table_option
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_generate_var().
+ * This function has been replaced by chado_generate_var().
+ *
+ * @see chado_generate_var().
  */
 function tripal_core_generate_chado_var($table, $values, $base_options = array()) {
 
@@ -404,7 +440,9 @@ function tripal_core_generate_chado_var($table, $values, $base_options = array()
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_insert_record().
+ * This function has been replaced by chado_insert_record().
+ *
+ * @see chado_insert_record().
  */
 function tripal_core_chado_insert($table, $values, $options = array()) {
 
@@ -425,7 +463,9 @@ function tripal_core_chado_insert($table, $values, $options = array()) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_select_record();
+ * This function has been replaced by chado_select_record().
+ *
+ * @see chado_select_record().
  */
 function tripal_core_chado_select($table, $columns, $values, $options = NULL) {
   tripal_report_error(
@@ -445,7 +485,9 @@ function tripal_core_chado_select($table, $columns, $values, $options = NULL) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_update_record();
+ * This function has been replaced by chado_update_record().
+ *
+ * @see chado_update_record().
  */
 function tripal_core_chado_update($table, $match, $values, $options = NULL) {
   tripal_report_error(
@@ -465,7 +507,9 @@ function tripal_core_chado_update($table, $match, $values, $options = NULL) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_create_files_dir();
+ * This function has been replaced by tripal_create_files_dir().
+ *
+ * @see tripal_create_files_dir().
  */
 function tripal_create_moddir($module_name) {
   tripal_report_error(
@@ -485,7 +529,9 @@ function tripal_create_moddir($module_name) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_create_files_dir();
+ * This function has been replaced by tripal_create_files_dir().
+ *
+ * @see tripal_create_files_dir().
  */
 function tripal_create_mod_subdir($module_name, $path) {
   tripal_report_error(
@@ -505,7 +551,10 @@ function tripal_create_mod_subdir($module_name, $path) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_create_files_dir().
+ * This function has been replaced by tripal_create_files_dir().
+ *
+ * @see tripal_create_files_dir().
+ * @todo Remove. This was not in Tripal 1.x.
  */
 function tripal_file_directory_path() {
   tripal_report_error(
@@ -525,7 +574,9 @@ function tripal_file_directory_path() {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_get_files_dir().
+ * This function has been replaced by tripal_get_files_dir().
+ *
+ * @see tripal_get_files_dir().
  */
 function tripal_get_moddir($module_name) {
   tripal_report_error(
@@ -545,7 +596,9 @@ function tripal_get_moddir($module_name) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_cancel_job().
+ * This function has been replaced by tripal_cancel_job().
+ *
+ * @see tripal_cancel_job().
  */
 function tripal_jobs_cancel($job_id, $redirect = TRUE) {
   tripal_report_error(
@@ -565,7 +618,9 @@ function tripal_jobs_cancel($job_id, $redirect = TRUE) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_get_active_jobs().
+ * This function has been replaced by tripal_get_active_jobs().
+ *
+ * @see tripal_get_active_jobs().
  */
 function tripal_get_module_active_jobs($modulename) {
   tripal_report_error(
@@ -585,7 +640,9 @@ function tripal_get_module_active_jobs($modulename) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_get_job_end().
+ * This function has been replaced by tripal_get_job_end().
+ *
+ * @see tripal_get_job_end().
  */
 function tripal_jobs_get_end_time($job) {
   tripal_report_error(
@@ -605,7 +662,9 @@ function tripal_jobs_get_end_time($job) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_get_job_start().
+ * This function has been replaced by tripal_get_job_start().
+ *
+ * @see tripal_get_job_start().
  */
 function tripal_jobs_get_start_time($job) {
   tripal_report_error(
@@ -625,7 +684,9 @@ function tripal_jobs_get_start_time($job) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_get_job_submit_date().
+ * This function has been replaced by tripal_get_job_submit_date().
+ *
+ * @see tripal_get_job_submit_date().
  */
 function tripal_jobs_get_submit_date($job) {
   tripal_report_error(
@@ -645,7 +706,9 @@ function tripal_jobs_get_submit_date($job) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_is_job_running().
+ * This function has been replaced by tripal_is_job_running().
+ *
+ * @see tripal_is_job_running().
  */
 function tripal_jobs_check_running() {
   tripal_report_error(
@@ -665,7 +728,9 @@ function tripal_jobs_check_running() {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_launch_job().
+ * This function has been replaced by tripal_launch_job().
+ *
+ * @see tripal_launch_job().
  */
 function tripal_jobs_launch($do_parallel = 0, $job_id = NULL) {
   tripal_report_error(
@@ -685,7 +750,9 @@ function tripal_jobs_launch($do_parallel = 0, $job_id = NULL) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_rerun_job().
+ * This function has been replaced by tripal_rerun_job().
+ *
+ * @see tripal_rerun_job().
  */
 function tripal_jobs_rerun($job_id, $goto_jobs_page = TRUE) {
   tripal_report_error(
@@ -705,7 +772,9 @@ function tripal_jobs_rerun($job_id, $goto_jobs_page = TRUE) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_set_job_progress().
+ * This function has been replaced by tripal_set_job_progress().
+ *
+ * @see tripal_set_job_progress().
  */
 function tripal_job_set_progress($job_id, $percentage) {
   tripal_report_error(
@@ -725,7 +794,9 @@ function tripal_job_set_progress($job_id, $percentage) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_update_mview().
+ * This function has been replaced by tripal_update_mview().
+ *
+ * @see tripal_update_mview().
  */
 function tripal_mviews_action($op, $mview_id, $redirect = FALSE) {
 
@@ -781,7 +852,9 @@ function tripal_add_legacy_mview($name, $modulename, $mv_table, $mv_specs, $inde
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_populate_mview();
+ * This function has been replaced by tripal_populate_mview().
+ *
+ * @see tripal_populate_mview().
  */
 function tripal_update_mview($mview_id) {
   tripal_report_error(
@@ -802,6 +875,8 @@ function tripal_update_mview($mview_id) {
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
  * This function is considered to be no easier to use than chado_delete_record directly
+ * chado_delete_record().
+ *
  * @see chado_delete_record().
  */
 function tripal_core_delete_property_by_id($basetable, $property_id) {
@@ -830,7 +905,9 @@ function tripal_core_delete_property_by_id($basetable, $property_id) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_delete_property().
+ * This function has been replaced by chado_delete_property().
+ *
+ * @see chado_delete_property().
  */
 function tripal_core_delete_property($basetable, $record_id, $property, $cv_name) {
   tripal_report_error(
@@ -850,7 +927,9 @@ function tripal_core_delete_property($basetable, $record_id, $property, $cv_name
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_get_property().
+ * This function has been replaced by chado_get_property().
+ *
+ * @see chado_get_property().
  */
 function tripal_core_get_property($basetable, $record_id, $property, $cv_name) {
   tripal_report_error(
@@ -870,15 +949,39 @@ function tripal_core_get_property($basetable, $record_id, $property, $cv_name) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_get_table_max_rank().
+ * This function has been replaced by chado_get_table_max_rank().
+ *
+ * @see chado_get_table_max_rank().
+ */
+function tripal_get_max_chado_rank($tablename, $where_options) {
+  tripal_report_error(
+    'tripal_api',
+    TRIPAL_NOTICE,
+    "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
+    array(
+      '%old_function'=>'tripal_get_max_chado_rank',
+      '%new_function' => 'chado_get_table_max_rank'
+    )
+  );
+
+  //New API Function
+  return chado_get_table_max_rank($tablename, $where_options);
+}
+
+/**
+ * @deprecated Restructured API to make naming more readable and consistent.
+ * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
+ * This function has been replaced by chado_get_table_max_rank().
+ *
+ * @see chado_get_table_max_rank().
  */
-function tripal_core_get_max_chado_rank($tablename, $where_options) {
+function get_max_chado_rank($tablename, $where_options) {
   tripal_report_error(
     'tripal_api',
     TRIPAL_NOTICE,
     "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
     array(
-      '%old_function'=>'tripal_core_get_max_chado_rank',
+      '%old_function'=>'get_max_chado_rank',
       '%new_function' => 'chado_get_table_max_rank'
     )
   );
@@ -887,10 +990,13 @@ function tripal_core_get_max_chado_rank($tablename, $where_options) {
   return chado_get_table_max_rank($tablename, $where_options);
 }
 
+
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_insert_property().
+ * This function has been replaced by chado_insert_property().
+ *
+ * @see chado_insert_property().
  */
 function tripal_core_insert_property($basetable, $record_id, $property,
 $cv_name, $value, $update_if_present = 0) {
@@ -911,7 +1017,9 @@ $cv_name, $value, $update_if_present = 0) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_update_property().
+ * This function has been replaced by chado_update_property().
+ *
+ * @see chado_update_property().
  */
 function tripal_core_update_property_by_id($basetable, $record_id, $property,
 $cv_name, $value) {
@@ -933,7 +1041,9 @@ $cv_name, $value) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_update_property().
+ * This function has been replaced by chado_update_property().
+ *
+ * @see chado_update_property().
  */
 function tripal_core_update_property($basetable, $record_id, $property,
 $cv_name, $value, $insert_if_missing = 0) {
@@ -954,13 +1064,17 @@ $cv_name, $value, $insert_if_missing = 0) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_create_custom_table().
+ * This function has been replaced by chado_create_custom_table().
+ *
+ * @see chado_create_custom_table().
  */
-function tripal_core_create_custom_table($table, $schema, $skip_creation = 1) {
+function tripal_core_create_custom_table(&$ret, $table, $schema, $skip_creation = 1) {
   tripal_report_error(
     'tripal_api',
     TRIPAL_NOTICE,
-    "DEPRECATED: %old_function has been replaced with %new_function. Please update your code.",
+    "DEPRECATED: %old_function has been replaced with %new_function. Note that $ret has
+      been removed from the paramters since this is not longer used in Drupal 7.
+      Please update your code.",
     array(
       '%old_function'=>'tripal_core_create_custom_table',
       '%new_function' => 'chado_create_custom_table'
@@ -974,7 +1088,9 @@ function tripal_core_create_custom_table($table, $schema, $skip_creation = 1) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_edit_custom_table().
+ * This function has been replaced by chado_edit_custom_table().
+ *
+ * @see chado_edit_custom_table().
  */
 function tripal_core_edit_custom_table($table_id, $table_name, $schema, $skip_creation = 1) {
   tripal_report_error(
@@ -994,7 +1110,9 @@ function tripal_core_edit_custom_table($table_id, $table_name, $schema, $skip_cr
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_get_custom_table_id().
+ * This function has been replaced by chado_get_custom_table_id().
+ *
+ * @see chado_get_custom_table_id().
  */
 function tripal_custom_tables_get_table_id($table_name) {
   tripal_report_error(
@@ -1014,7 +1132,9 @@ function tripal_custom_tables_get_table_id($table_name) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_get_custom_table_schema().
+ * This function has been replaced by chado_get_custom_table_schema().
+ *
+ * @see chado_get_custom_table_schema().
  */
 function tripal_get_chado_custom_schema($table) {
   tripal_report_error(
@@ -1034,7 +1154,9 @@ function tripal_get_chado_custom_schema($table) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_is_installed().
+ * This function has been replaced by chado_is_installed().
+ *
+ * @see chado_is_installed().
  */
 function tripal_core_is_chado_installed() {
   tripal_report_error(
@@ -1054,7 +1176,9 @@ function tripal_core_is_chado_installed() {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_get_schema().
+ * This function has been replaced by chado_get_schema().
+ *
+ * @see chado_get_schema().
  */
 function tripal_core_get_chado_table_schema($table) {
   tripal_report_error(
@@ -1074,7 +1198,9 @@ function tripal_core_get_chado_table_schema($table) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_get_version().
+ * This function has been replaced by chado_get_version().
+ *
+ * @see chado_get_version().
  */
 function tripal_core_get_chado_version($exact = FALSE, $warn_if_unsupported = FALSE) {
   tripal_report_error(
@@ -1094,7 +1220,9 @@ function tripal_core_get_chado_version($exact = FALSE, $warn_if_unsupported = FA
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_set_active().
+ * This function has been replaced by chado_set_active().
+ *
+ * @see chado_set_active().
  */
 function tripal_db_set_active($dbname  = 'default') {
   tripal_report_error(
@@ -1114,7 +1242,9 @@ function tripal_db_set_active($dbname  = 'default') {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_is_local().
+ * This function has been replaced by chado_is_local().
+ *
+ * @see chado_is_local().
  */
 function tripal_core_is_chado_local() {
   tripal_report_error(
@@ -1134,7 +1264,9 @@ function tripal_core_is_chado_local() {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_get_table_names().
+ * This function has been replaced by chado_get_table_names().
+ *
+ * @see chado_get_table_names().
  */
 function tripal_core_get_chado_tables($include_custom = NULL) {
   tripal_report_error(
@@ -1154,7 +1286,9 @@ function tripal_core_get_chado_tables($include_custom = NULL) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_is_local().
+ * This function has been replaced by chado_is_local().
+ *
+ * @see chado_is_local().
  */
 function tripal_core_chado_schema_exists() {
   tripal_report_error(
@@ -1174,7 +1308,9 @@ function tripal_core_chado_schema_exists() {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see chado_dbschema_exists().
+ * This function has been replaced by chado_dbschema_exists().
+ *
+ * @see chado_dbschema_exists().
  */
 function tripal_core_schema_exists($schema) {
   tripal_report_error(
@@ -1194,7 +1330,9 @@ function tripal_core_schema_exists($schema) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_set_admin_message().
+ * This function has been replaced by tripal_set_admin_message().
+ *
+ * @see tripal_set_admin_message().
  *
 function theme_tripal_admin_message($variables) {
   tripal_report_error(
@@ -1215,7 +1353,10 @@ function theme_tripal_admin_message($variables) {
 /**
  * @deprecated Restructured API to make naming more readable and consistent.
  * Function was deprecated in Tripal 2.0 and will be removed 2 releases from now.
- * This function has been replaced by @see tripal_report_error().
+ * This function has been replaced by tripal_report_error().
+ *
+ * @see tripal_report_error().
+ * @todo Remove. This was not in Tripal 1.x.
  */
 function tripal_core_report_error($type, $severity, $message, $variables = array(), $options = array()) {
 

+ 264 - 128
tripal_core/api/tripal_core.chado_general.api.inc

@@ -40,118 +40,6 @@ require_once 'tripal_core.schema_v1.11.api.inc';
  *
  */
 
-// Globals used by Tripals Error catching functions
-// Should match those defined by watchdog
-define('TRIPAL_CRITICAL',2);
-define('TRIPAL_ERROR',3);
-define('TRIPAL_WARNING',4);
-define('TRIPAL_NOTICE',5);
-define('TRIPAL_INFO',6);
-define('TRIPAL_DEBUG',7);
-
-/**
- * Provide better error notice for Tripal
- * @param $type
- *   The catagory to which this message belongs. Can be any string, but the general
- *   practice is to use the name of the module.
- * @param $message
- *   The message to store in the log. Keep $message translatable by not concatenating
- *   dynamic values into it! Variables in the message should be added by using placeholder
- *   strings alongside the variables argument to declare the value of the placeholders.
- *   See t() for documentation on how $message and $variables interact.
- * @param $variables
- *   Array of variables to replace in the message on display or NULL if message is
- *   already translated or not possible to translate.
- * @param $severity
- *   The severity of the message; one of the following values:
- *     - TRIPAL_CRITICAL: Critical conditions.
- *     - TRIPAL_ERROR: Error conditions.
- *     - TRIPAL_WARNING: Warning conditions.
- *     - TRIPAL_NOTICE: (default) Normal but significant conditions.
- *     - TRIPAL_INFO: Informational messages.
- *     - TRIPAL_DEBUG: Debug-level messages.
- * @param $options
- *   An array of options. Some available options include:
- *     - print: prints the error message to the terminal screen. Useful when display is the command-line
- *
- * @ingroup tripal_chado_api
- */
-function tripal_report_error($type, $severity, $message, $variables = array(), $options = array()) {
-
-  // Get human-readable severity string
-  $severity_string = '';
-  switch ($severity) {
-    case TRIPAL_CRITICAL:
-      $severity_string = 'CRITICAL';
-      break;
-    case TRIPAL_ERROR:
-      $severity_string = 'ERROR';
-      break;
-    case TRIPAL_WARNING:
-      $severity_string = 'WARNING';
-      break;
-    case TRIPAL_NOTICE:
-      $severity_string = 'NOTICE';
-      break;
-    case TRIPAL_INFO:
-      $severity_string = 'INFO';
-      break;
-    case TRIPAL_DEBUG:
-      $severity_string = 'DEBUG';
-      break;
-  }
-
-  // Send to watchdog
-  try {
-    watchdog($type, $message, $variables, $severity);
-  }
-  catch (Exception $e) {
-    print "CRITICAL (TRIPAL_CORE): Unable to register error message with watchdog";
-    $options['print'] = TRUE;
-  }
-
-  // If print option supplied then print directly to the screen
-  if (isset($options['print'])) {
-    if (sizeof($variables) > 0) {
-      $message = str_replace(array_keys($variables), $variables, $message);
-    }
-    print $severity_string . ' (' . strtoupper($type) . '):' . $message . "\n";
-  }
-}
-
-/**
- * Get chado id for a node. E.g, if you want to get 'analysis_id' from the
- * 'analysis' table for a synced 'chado_analysis' node, (the same for
- * organisms and features):
- * $analysis_id = chado_get_id_from_nid ('analysis', $node->nid)
- * $organism_id = chado_get_id_from_nid ('organism', $node->nid)
- * $feature_id  = chado_get_id_from_nid ('feature', $node->nid)
- *
- * @param $table
- * @param $nid
- *
- * @ingroup tripal_chado_api
- */
-function chado_get_id_from_nid($table, $nid) {
-  $sql = "SELECT " . $table . "_id as id FROM {chado_$table} WHERE nid = :nid";
-  return db_query($sql, array(':nid' => $nid))->fetchField();
-}
-
-/**
- *  Get node id for a chado feature/organism/analysis. E.g, if you want to
- *  get the node id for an analysis, use:
- *  $nid = chado_get_nid_from_id ('analysis', $analysis_id)
- *  Likewise,
- *  $nid = chado_get_nid_from_id ('organism', $organism_id)
- *  $nid = chado_get_nid_from_id ('feature', $feature_id)
- *
- *  @ingroup tripal_chado_api
- */
-function chado_get_nid_from_id($table, $id) {
-  $sql = "SELECT nid FROM {chado_$table} WHERE " . $table . "_id = :" . $table . "_id";
-  return db_query($sql, array(":" . $table . "_id" => $id))->fetchField();
-}
-
 /**
  * Set the Tripal Database
  *
@@ -234,27 +122,275 @@ function chado_get_table_max_rank($tablename, $where_options) {
 }
 
 /**
- * Use this function to encapsulate text intended to be
- * visible only by the site administrator. A small tripal logo
- * appears alongside the text.  Do not call this function directly, but
- * rather, use the theme() function:
+ * Retrieve a property for a given base table record
+ *
+ * @param $basetable
+ *   The base table for which the property should be retrieved. Thus to retrieve a property
+ *   for a feature the basetable=feature and property is retrieved from featureprop
+ * @param $record_id
+ *   The foriegn key field of the base table. This should be in integer.
+ * @param $property
+ *   The cvterm name describing the type of properties to be retrieved
+ * @param $cv_name
+ *   The name of the cv that the above cvterm is part of
+ *
+ * @return
+ *   An array in the same format as that generated by the function
+ *   chado_generate_var().  If only one record is returned it
+ *   is a single object.  If more than one record is returned then it is an array
+ *   of objects
+ *
+ * @ingroup tripal_chado_api
+ */
+function chado_get_property($basetable, $record_id, $property, $cv_name, $property_id = FALSE) {
+  // get the foreign key for this property table
+  $table_desc = chado_get_schema($basetable . 'prop');
+  $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
+
+  // construct the array of values to be selected
+  $values = array(
+    $fkcol => $record_id,
+    'type_id' => array(
+      'cv_id' => array(
+        'name' => $cv_name,
+      ),
+      'name' => $property,
+      'is_obsolete' => 0
+    ),
+  );
+  // if we have the unique property_id make sure to add that to the values
+  if ($property_id) {
+    $property_pkey = $table_desc['primary key'][0];
+    $values[$property_pkey] = $property_id;
+  }
+  $results = chado_generate_var($basetable . 'prop', $values);
+  if ($results) {
+    $results = chado_expand_var($results, 'field', $basetable . 'prop.value');
+  }
+
+  return $results;
+}
+
+/**
+ * Insert a property for a given base table.  By default if the property already
+ * exists a new property is added with the next available rank.  If
+ * $update_if_present argument is specified then the record will be updated if it
+ * exists rather than adding a new property.
+ *
+ * @param $basetable
+ *   The base table for which the property should be inserted. Thus to insert a property
+ *   for a feature the basetable=feature and property is inserted into featureprop
+ * @param $record_id
+ *   The foriegn key value of the base table. This should be in integer.
+ * @param $property
+ *   The cvterm name describing the type of properties to be inserted
+ * @param $cv_name
+ *   The name of the cv that the above cvterm is part of
+ * @param $value
+ *   The value of the property to be inserted (can be empty)
+ * @param $update_if_present
+ *   A boolean indicating whether an existing record should be updated. If the
+ *   property already exists and this value is not specified or is zero then
+ *   a new property will be added with the next largest rank.
+ *
+ * @return
+ *   Return True on Insert/Update and False otherwise
+ *
+ * @ingroup tripal_chado_api
+ */
+function chado_insert_property($basetable, $record_id, $property,
+$cv_name, $value, $update_if_present = 0) {
+
+  // first see if the property already exists, if the user want's to update
+  // then we can do that, but otherwise we want to increment the rank and
+  // insert
+  $props = chado_get_property($basetable, $record_id, $property, $cv_name);
+  if (!is_array($props) and $props) {
+    $props = array($props);
+  }
+
+  $rank = 0;
+  if (count($props) > 0) {
+    if ($update_if_present) {
+      return chado_update_property($basetable, $record_id, $property, $cv_name, $value);
+    }
+    else {
+      // iterate through the properties returned and check to see if the
+      // property with this value already exists if not, get the largest rank
+      // and insert the same property but with this new value
+      foreach ($props as $p) {
+        if ($p->rank > $rank) {
+          $rank = $p->rank;
+        }
+        if (strcmp($p->value, $value) == 0) {
+          return TRUE;
+        }
+      }
+      // now add 1 to the rank
+      $rank++;
+    }
+  }
+
+  // make sure the cvterm exists.  Otherwise we'll get an error with
+  // prepared statements not matching
+  $values = array(
+    'cv_id' => array(
+      'name' => $cv_name,
+    ),
+    'name' => $property,
+  );
+
+  $options = array();
+  $term = chado_select_record('cvterm', array('cvterm_id'), $values, $options);
+  if (!$term or count($term) == 0) {
+    tripal_report_error('tripal_core', TRIPAL_ERROR, "Cannot find property '%prop_name' in vocabulary '%cvname'.",
+    array('%prop_name' => $property, '%cvname' => $cv_name));
+    return FALSE;
+  }
+
+  // get the foreign key for this property table
+  $table_desc = chado_get_schema($basetable . 'prop');
+  $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
+
+  // construct the array of values to be inserted
+  $values = array(
+    $fkcol => $record_id,
+    'type_id' => array(
+      'cv_id' => array(
+        'name' => $cv_name,
+      ),
+      'name' => $property,
+    ),
+    'value' => $value,
+    'rank' => $rank,
+  );
+
+  $options = array();
+  $result = chado_insert_record($basetable . 'prop', $values, $options);
+  return $result;
+}
+
+/**
+ * Update a property for a given base table record and property name.  This
+ * function should be used only if one record of the property will be present.
+ * If the property name can have multiple entries (with increasing rank) then
+ * use the function named chado_update_propertyID
  *
- *   theme('tripal_admin_message', array('message' => $my_message));
+ * @param $basetable
+ *   The base table for which the property should be updated. The property table
+ *   is constructed using  a combination of the base table name and the suffix
+ *   'prop' (e.g. basetable = feature then property tabie is featureprop).
+ * @param $record_id
+ *   The foreign key of the basetable to update a property for. This should be in integer.
+ *   For example, if the basetable is 'feature' then the $record_id should be the feature_id
+ * @param $property
+ *   The cvterm name of property to be updated
+ * @param $cv_name
+ *   The name of the cv that the above cvterm is part of
+ * @param $value
+ *   The value of the property to be inserted (can be empty)
+ * @param $insert_if_missing
+ *   A boolean indicating whether a record should be inserted if one doesn't exist to update
  *
- * @param $message
- *   The message to be displayed to the site administrator
+ * Note: The property to be updated is select via the unique combination of $record_id and
+ * $property and then it is updated with the supplied value
+ *
+ * @return
+ *   Return True on Update/Insert and False otherwise
  *
  * @ingroup tripal_chado_api
  */
-function theme_tripal_admin_message($variables) {
+function chado_update_property($basetable, $record_id, $property,
+$cv_name, $value, $insert_if_missing = FALSE, $property_id = FALSE) {
 
-  $message = $variables['message'];
+  // first see if the property is missing (we can't update a missing property
+  $prop = chado_get_property($basetable, $record_id, $property, $cv_name, $property_id);
+  if (count($prop)==0) {
+    if ($insert_if_missing) {
+      return chado_insert_property($basetable, $record_id, $property, $cv_name, $value);
+    }
+    else {
+      return FALSE;
+    }
+  }
+
+  // get the foreign key for this property table
+  $table_desc = chado_get_schema($basetable . 'prop');
+  $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
+
+  // construct the array that will match the exact record to update
+  $match = array(
+    $fkcol => $record_id,
+    'type_id' => array(
+      'cv_id' => array(
+        'name' => $cv_name,
+      ),
+      'name' => $property,
+    ),
+  );
+  // If we have the unique property_id, make sure to use it in the match to ensure
+  // we get the exact record. Doesn't rely on there only being one property of that type
+  if ($property_id) {
+    $property_pkey = $table_desc['primary key'][0];
+    $match = array(
+      $property_pkey => $property_id
+    );
+  }
 
-  if (!user_access('access administration pages')) {
-    return '';
+  // construct the array of values to be updated
+  $values = array(
+    'value' => $value,
+  );
+  // If we have the unique property_id then we can also update the type
+  // thus add it to the values to be updated
+  if ($property_id) {
+    $values['type_id'] = array(
+      'cv_id' => array(
+        'name' => $cv_name,
+      ),
+      'name' => $property,
+    );
   }
-  return "
-    <div class=\"tripal-site-admin-only\">
-      <div class=\"tripal-site-admin-message\">$message</div>
-    </div>";
-}
+
+  return chado_update_record($basetable . 'prop', $match, $values);
+}
+
+/**
+ * Deletes a property for a given base table record using the property name
+ *
+ * @param $basetable
+ *   The base table for which the property should be deleted. Thus to deleted a property
+ *   for a feature the basetable=feature and property is deleted from featureprop
+ * @param $record_id
+ *   The primary key of the basetable to delete a property for. This should be in integer.
+ * @param $property
+ *   The cvterm name describing the type of property to be deleted
+ * @param $cv_name
+ *   The name of the cv that the above cvterm is part of
+ *
+ * Note: The property to be deleted is select via the unique combination of $record_id and $property
+ *
+ * @return
+ *   Return True on Delete and False otherwise
+ *
+ * @ingroup tripal_chado_api
+ */
+function chado_delete_property($basetable, $record_id, $property, $cv_name) {
+
+  // get the foreign key for this property table
+  $table_desc = chado_get_schema($basetable . 'prop');
+  $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
+
+  // construct the array that will match the exact record to update
+  $match = array(
+    $fkcol => $record_id,
+    'type_id' => array(
+      'cv_id' => array(
+        'name' => $cv_name,
+      ),
+      'name' => $property,
+    ),
+  );
+
+  return chado_delete_record($basetable . 'prop', $match);
+}

+ 162 - 76
tripal_core/api/tripal_core.chado_nodes.api.inc

@@ -34,9 +34,45 @@
  */
 
 /**
- * Sync'ing chado records with Drupal by creating nodes
+ * Get chado id for a node. E.g, if you want to get 'analysis_id' from the
+ * 'analysis' table for a synced 'chado_analysis' node, (the same for
+ * organisms and features):
+ * $analysis_id = chado_get_id_from_nid ('analysis', $node->nid)
+ * $organism_id = chado_get_id_from_nid ('organism', $node->nid)
+ * $feature_id  = chado_get_id_from_nid ('feature', $node->nid)
  *
- * How to Use:
+ * @param $table
+ * @param $nid
+ *
+ * @ingroup tripal_chado_node_api
+ */
+function chado_get_id_from_nid($table, $nid) {
+  $sql = "SELECT " . $table . "_id as id FROM {chado_$table} WHERE nid = :nid";
+  return db_query($sql, array(':nid' => $nid))->fetchField();
+}
+
+/**
+ *  Get node id for a chado feature/organism/analysis. E.g, if you want to
+ *  get the node id for an analysis, use:
+ *  $nid = chado_get_nid_from_id ('analysis', $analysis_id)
+ *  Likewise,
+ *  $nid = chado_get_nid_from_id ('organism', $organism_id)
+ *  $nid = chado_get_nid_from_id ('feature', $feature_id)
+ *
+ *  @ingroup tripal_chado_node_api
+ */
+function chado_get_nid_from_id($table, $id) {
+  $sql = "SELECT nid FROM {chado_$table} WHERE " . $table . "_id = :" . $table . "_id";
+  return db_query($sql, array(":" . $table . "_id" => $id))->fetchField();
+}
+
+/**
+ * Generic Sync Form to aid in sync'ing (create drupal nodes linking to chado content)
+ * any chado node type.
+ *
+ * To use this you need to add a call to it from your hook_menu() and
+ * add some additional information to your hook_node_info(). The Following code gives an
+ * example of how this might be done:
  * @code
 
   function modulename_menu() {
@@ -58,7 +94,7 @@
     return $items;
   }
 
-  modulename_node_info() {
+  function modulename_node_info() {
     return array(
       'chado_example' => array(
         'name' => t('example'),
@@ -89,81 +125,12 @@
       ),
     );
   }
-
-  // Create New Node
-  // @param $new_node: a basic new node object
-  // @param $record: the record object from chado specifying the biological data for this node
-  function chado_example_chado_node_sync_create_new_node($new_node, $record) {
-
-    // Add relevant chado details to the new node object
-    // This really only needs to be the fields from the node used during node creation
-    // including values used to generate the title, etc.
-    // All additional chado data will be added via nodetype_load when the node is later used
-    $new_node->uniquename = $record->uniquename;
-
-    return $new_node;
-  }
-
-  // Alter the sync form (optional)
-  function chado_example_chado_node_sync_form($form, $form_state) {
-
-    // Change or add to the form array as needed
-    // Any changes should be made in accordance with the Drupal Form API
-
-    return $form;
-  }
-
-  // Bypass chado node api sync form submit (optional)
-  // Allows you to use this function as your own submit
-  function chado_example_chado_node_sync_form ($form, $form_state) {
-
-    global $user;
-
-    $job_args = array(
-      $base_table,      // the base chado table (ie: feature)
-      $max_sync,        // the maximum number of records to sync or FALSE for sync all that match
-      $organism_id,     // the organism_id to restrict records to or FALSE if not to restrict by organism_id
-      $types            // A string with the cvterm.name of the types to restrict to separated by |||
-    );
-
-    // You should register a tripal job
-    tripal_add_job(
-      $title,                                   // the title of the job -be descriptive
-      $module,                                  // the name of your module
-      'chado_node_sync_records',    // the chado node api sync function
-      $job_args,                                // an array with the arguments to pass to the above function
-      $user->uid                                // the user who submitted the job
-    );
-
-  }
-
-
-  // Alter the query for the chado database which gets the chado records to be sync'd (optional)
-  // @param $select: an array of select clauses
-  // @param $joins: an array of joins (ie: a single join could be 'LEFT JOIN {chadotable} alias ON base.id=alias.id')
-  // @param $where_clauses: an array of where clauses which will all be AND'ed together. Use :placeholders for values.
-  // @param $where_args: an associative array of arguments to be subbed in to the where clause
-  //           where the key = :placeholder and the value is the actual argument to be subbed in
-  function chado_example_chado_node_sync_select_query (&$select, &$joins, &$where_clauses, &$where_args) {
-
-    // You can add fields to be selected
-    $select[] = 'example.myfavfield';
-
-    // Or joins to important tables
-    $joins[] = 'LEFT JOIN {exampleprop} PROP ON PROP.example_id=EXAMPLE.example_id';
-
-    // Or filter the query using where clauses
-    $where_clauses[] = 'example.myfavfield = :favvalue';
-    $where_args[':favvalue'] = 'awesome-ness';
-  }
-
  * @endcode
  *
- * @ingroup tripal_chado_node_api
- */
-
-/**
- * Generic Sync Form
+ * For more information on how you can override some of this behaviour while still
+ * benifiting from as much of the common architecture as possible see the following
+ * functions: hook_chado_node_sync_create_new_node(), hook_chado_node_sync_form(),
+ * hook_chado_node_sync_select_query().
  *
  * @ingroup tripal_chado_node_api
  */
@@ -697,4 +664,123 @@ function chado_cleanup_orphaned_nodes($table, $job_id = NULL) {
   print "\t$deleted nodes did not have corresponding chado_$table entries.\n";
 
   return '';
+}
+
+/**
+ * Create New Node
+ *
+ * Note: For your own module, replace hook in the function name with the machine-name of
+ * your chado node type (ie: chado_feature).
+ *
+ * @param $new_node:
+ *   a basic new node object
+ * @param $record:
+ *   the record object from chado specifying the biological data for this node
+ *
+ * @return
+ *   A node object containing all the fields necessary to create a new node during sync
+ *
+ * @ingroup tripal_chado_node_api
+ */
+function hook_chado_node_sync_create_new_node($new_node, $record) {
+
+  // Add relevant chado details to the new node object
+  // This really only needs to be the fields from the node used during node creation
+  // including values used to generate the title, etc.
+  // All additional chado data will be added via nodetype_load when the node is later used
+  $new_node->uniquename = $record->uniquename;
+
+  return $new_node;
+}
+
+/**
+ * Alter the sync form (optional)
+ *
+ * This might be necessary if you need additional filtering options for choosing which
+ * chado records to sync or even if you just want to further customize the help text
+ * provided by the form.
+ *
+ * Note: For your own module, replace hook in the function name with the machine-name of
+ * your chado node type (ie: chado_feature).
+ *
+ * @ingroup tripal_chado_node_api
+ */
+function hook_chado_node_sync_form($form, $form_state) {
+
+  // Change or add to the form array as needed
+  // Any changes should be made in accordance with the Drupal Form API
+
+  return $form;
+}
+
+/**
+ * Bypass chado node api sync form submit (optional). Allows you to use this function
+ * as your own submit.
+ *
+ * This might be necessary if you want to add additional arguements to the tripal job or
+ * to call your own sync'ing function if the generic chado_node_sync_records() is not
+ * sufficient.
+ *
+ * Note: For your own module, replace hook in the function name with the machine-name of
+ * your chado node type (ie: chado_feature).
+ *
+ * @ingroup tripal_chado_node_api
+ */
+function hook_chado_node_sync_form_submit ($form, $form_state) {
+
+  global $user;
+
+  $job_args = array(
+    $base_table,      // the base chado table (ie: feature)
+    $max_sync,        // the maximum number of records to sync or FALSE for sync all that match
+    $organism_id,     // the organism_id to restrict records to or FALSE if not to restrict by organism_id
+    $types            // A string with the cvterm.name of the types to restrict to separated by |||
+  );
+
+  // You should register a tripal job
+  tripal_add_job(
+    $title,                                   // the title of the job -be descriptive
+    $module,                                  // the name of your module
+    'chado_node_sync_records',    // the chado node api sync function
+    $job_args,                                // an array with the arguments to pass to the above function
+    $user->uid                                // the user who submitted the job
+  );
+
+}
+
+
+/**
+ * Alter the query for the chado database which gets the chado records to be sync'd (optional)
+ *
+ * This might be necessary if you need fields from other chado tables to create your node
+ * or if your chado node type only supports a subset of a given table (ie: a germplasm node
+ * type might only support node creation for cerain types of stock records in which case
+ * you would need to filter the results to only those types).
+ *
+ * Note: For your own module, replace hook in the function name with the machine-name of
+ * your chado node type (ie: chado_feature).
+ *
+ * @param $select:
+ *   An array of select clauses
+ * @param $joins:
+ *   An array of joins (ie: a single join could be 'LEFT JOIN {chadotable} alias ON base.id=alias.id')
+ * @param $where_clauses:
+ *   An array of where clauses which will all be AND'ed together. Use :placeholders for values.
+ * @param $where_args:
+ *   An associative array of arguments to be subbed in to the where clause where the
+ *   key = :placeholder and the value is the actual argument to be subbed in.
+ *
+ * @ingroup tripal_chado_node_api
+ */
+function hook_chado_node_sync_select_query (&$select, &$joins, &$where_clauses, &$where_args) {
+
+  // You can add fields to be selected
+  $select[] = 'example.myfavfield';
+
+  // Or joins to important tables
+  $joins[] = 'LEFT JOIN {exampleprop} PROP ON PROP.example_id=EXAMPLE.example_id';
+
+  // Or filter the query using where clauses
+  $where_clauses[] = 'example.myfavfield = :favvalue';
+  $where_args[':favvalue'] = 'awesome-ness';
 }

+ 18 - 0
tripal_core/api/tripal_core.chado_nodes.dbxrefs.api.inc

@@ -140,6 +140,19 @@ function chado_add_node_form_dbxrefs(&$form, &$form_state, $details) {
     }
   }
 
+  // Tell tripal administrators how to add terms to the property types drop down.
+  $importance = (empty($db_options)) ? TRIPAL_WARNING : TRIPAL_INFO;
+  $tripal_message = tripal_set_message(
+    t('To add databases to the drop down list, you need to <a href="@dblink">add
+      an external database reference</a>.',
+      array(
+        '@dblink' => url('admin/tripal/chado/tripal_db/add')
+      )
+    ),
+    $importance,
+    array('return_html' => TRUE)
+  );
+
   // the fieldset of the dbxref elements
   $form['addtl_dbxrefs'] = array(
     '#type' => 'fieldset',
@@ -153,6 +166,11 @@ function chado_add_node_form_dbxrefs(&$form, &$form_state, $details) {
     '#weight'      => 9
   );
 
+  $form['addtl_dbxrefs']['admin_message'] = array(
+    '#type' => 'markup',
+    '#markup' => $tripal_message
+  );
+
   // this form element is a tree, so that we don't puke all of the values into then node variable
   // it is set as a tree, and keeps them in the $form_state['values']['dbxref_table'] heading.
   $form['addtl_dbxrefs']['dbxref_table'] = array(

+ 48 - 283
tripal_core/api/tripal_core.chado_nodes.properties.api.inc

@@ -97,285 +97,6 @@
  * @ingroup tripal_chado_node_api
  */
 
-/**
- * Retrieve a property for a given base table record
- *
- * @param $basetable
- *   The base table for which the property should be retrieved. Thus to retrieve a property
- *   for a feature the basetable=feature and property is retrieved from featureprop
- * @param $record_id
- *   The foriegn key field of the base table. This should be in integer.
- * @param $property
- *   The cvterm name describing the type of properties to be retrieved
- * @param $cv_name
- *   The name of the cv that the above cvterm is part of
- *
- * @return
- *   An array in the same format as that generated by the function
- *   chado_generate_var().  If only one record is returned it
- *   is a single object.  If more than one record is returned then it is an array
- *   of objects
- *
- * @ingroup tripal_chado_node_api
- */
-function chado_get_property($basetable, $record_id, $property, $cv_name, $property_id = FALSE) {
-  // get the foreign key for this property table
-  $table_desc = chado_get_schema($basetable . 'prop');
-  $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
-
-  // construct the array of values to be selected
-  $values = array(
-    $fkcol => $record_id,
-    'type_id' => array(
-      'cv_id' => array(
-        'name' => $cv_name,
-      ),
-      'name' => $property,
-      'is_obsolete' => 0
-    ),
-  );
-  // if we have the unique property_id make sure to add that to the values
-  if ($property_id) {
-    $property_pkey = $table_desc['primary key'][0];
-    $values[$property_pkey] = $property_id;
-  }
-  $results = chado_generate_var($basetable . 'prop', $values);
-  if ($results) {
-    $results = chado_expand_var($results, 'field', $basetable . 'prop.value');
-  }
-
-  return $results;
-}
-
-/**
- * Insert a property for a given base table.  By default if the property already
- * exists a new property is added with the next available rank.  If
- * $update_if_present argument is specified then the record will be updated if it
- * exists rather than adding a new property.
- *
- * @param $basetable
- *   The base table for which the property should be inserted. Thus to insert a property
- *   for a feature the basetable=feature and property is inserted into featureprop
- * @param $record_id
- *   The foriegn key value of the base table. This should be in integer.
- * @param $property
- *   The cvterm name describing the type of properties to be inserted
- * @param $cv_name
- *   The name of the cv that the above cvterm is part of
- * @param $value
- *   The value of the property to be inserted (can be empty)
- * @param $update_if_present
- *   A boolean indicating whether an existing record should be updated. If the
- *   property already exists and this value is not specified or is zero then
- *   a new property will be added with the next largest rank.
- *
- * @return
- *   Return True on Insert/Update and False otherwise
- *
- * @ingroup tripal_chado_node_api
- */
-function chado_insert_property($basetable, $record_id, $property,
-$cv_name, $value, $update_if_present = 0) {
-
-  // first see if the property already exists, if the user want's to update
-  // then we can do that, but otherwise we want to increment the rank and
-  // insert
-  $props = chado_get_property($basetable, $record_id, $property, $cv_name);
-  if (!is_array($props) and $props) {
-    $props = array($props);
-  }
-
-  $rank = 0;
-  if (count($props) > 0) {
-    if ($update_if_present) {
-      return chado_update_property($basetable, $record_id, $property, $cv_name, $value);
-    }
-    else {
-      // iterate through the properties returned and check to see if the
-      // property with this value already exists if not, get the largest rank
-      // and insert the same property but with this new value
-      foreach ($props as $p) {
-        if ($p->rank > $rank) {
-          $rank = $p->rank;
-        }
-        if (strcmp($p->value, $value) == 0) {
-          return TRUE;
-        }
-      }
-      // now add 1 to the rank
-      $rank++;
-    }
-  }
-
-  // make sure the cvterm exists.  Otherwise we'll get an error with
-  // prepared statements not matching
-  $values = array(
-    'cv_id' => array(
-      'name' => $cv_name,
-    ),
-    'name' => $property,
-  );
-
-  $options = array();
-  $term = chado_select_record('cvterm', array('cvterm_id'), $values, $options);
-  if (!$term or count($term) == 0) {
-    tripal_report_error('tripal_core', TRIPAL_ERROR, "Cannot find property '%prop_name' in vocabulary '%cvname'.",
-    array('%prop_name' => $property, '%cvname' => $cv_name));
-    return FALSE;
-  }
-
-  // get the foreign key for this property table
-  $table_desc = chado_get_schema($basetable . 'prop');
-  $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
-
-  // construct the array of values to be inserted
-  $values = array(
-    $fkcol => $record_id,
-    'type_id' => array(
-      'cv_id' => array(
-        'name' => $cv_name,
-      ),
-      'name' => $property,
-    ),
-    'value' => $value,
-    'rank' => $rank,
-  );
-
-  $options = array();
-  $result = chado_insert_record($basetable . 'prop', $values, $options);
-  return $result;
-}
-
-/**
- * Update a property for a given base table record and property name.  This
- * function should be used only if one record of the property will be present.
- * If the property name can have multiple entries (with increasing rank) then
- * use the function named chado_update_propertyID
- *
- * @param $basetable
- *   The base table for which the property should be updated. The property table
- *   is constructed using  a combination of the base table name and the suffix
- *   'prop' (e.g. basetable = feature then property tabie is featureprop).
- * @param $record_id
- *   The foreign key of the basetable to update a property for. This should be in integer.
- *   For example, if the basetable is 'feature' then the $record_id should be the feature_id
- * @param $property
- *   The cvterm name of property to be updated
- * @param $cv_name
- *   The name of the cv that the above cvterm is part of
- * @param $value
- *   The value of the property to be inserted (can be empty)
- * @param $insert_if_missing
- *   A boolean indicating whether a record should be inserted if one doesn't exist to update
- *
- * Note: The property to be updated is select via the unique combination of $record_id and
- * $property and then it is updated with the supplied value
- *
- * @return
- *   Return True on Update/Insert and False otherwise
- *
- * @ingroup tripal_chado_node_api
- */
-function chado_update_property($basetable, $record_id, $property,
-$cv_name, $value, $insert_if_missing = FALSE, $property_id = FALSE) {
-
-  // first see if the property is missing (we can't update a missing property
-  $prop = chado_get_property($basetable, $record_id, $property, $cv_name, $property_id);
-  if (count($prop)==0) {
-    if ($insert_if_missing) {
-      return chado_insert_property($basetable, $record_id, $property, $cv_name, $value);
-    }
-    else {
-      return FALSE;
-    }
-  }
-
-  // get the foreign key for this property table
-  $table_desc = chado_get_schema($basetable . 'prop');
-  $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
-
-  // construct the array that will match the exact record to update
-  $match = array(
-    $fkcol => $record_id,
-    'type_id' => array(
-      'cv_id' => array(
-        'name' => $cv_name,
-      ),
-      'name' => $property,
-    ),
-  );
-  // If we have the unique property_id, make sure to use it in the match to ensure
-  // we get the exact record. Doesn't rely on there only being one property of that type
-  if ($property_id) {
-    $property_pkey = $table_desc['primary key'][0];
-    $match = array(
-      $property_pkey => $property_id
-    );
-  }
-
-  // construct the array of values to be updated
-  $values = array(
-    'value' => $value,
-  );
-  // If we have the unique property_id then we can also update the type
-  // thus add it to the values to be updated
-  if ($property_id) {
-    $values['type_id'] = array(
-      'cv_id' => array(
-        'name' => $cv_name,
-      ),
-      'name' => $property,
-    );
-  }
-
-  return chado_update_record($basetable . 'prop', $match, $values);
-}
-
-/**
- * Deletes a property for a given base table record using the property name
- *
- * @param $basetable
- *   The base table for which the property should be deleted. Thus to deleted a property
- *   for a feature the basetable=feature and property is deleted from featureprop
- * @param $record_id
- *   The primary key of the basetable to delete a property for. This should be in integer.
- * @param $property
- *   The cvterm name describing the type of property to be deleted
- * @param $cv_name
- *   The name of the cv that the above cvterm is part of
- *
- * Note: The property to be deleted is select via the unique combination of $record_id and $property
- *
- * @return
- *   Return True on Delete and False otherwise
- *
- * @ingroup tripal_chado_node_api
- */
-function chado_delete_property($basetable, $record_id, $property, $cv_name) {
-
-  // get the foreign key for this property table
-  $table_desc = chado_get_schema($basetable . 'prop');
-  $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
-
-  // construct the array that will match the exact record to update
-  $match = array(
-    $fkcol => $record_id,
-    'type_id' => array(
-      'cv_id' => array(
-        'name' => $cv_name,
-      ),
-      'name' => $property,
-    ),
-  );
-
-  return chado_delete_record($basetable . 'prop', $match);
-}
-
-/**
- * @section
- * Properties Form to be added to node forms
- */
-
 /**
  * Provides a form for adding to BASEprop table
  *
@@ -415,7 +136,7 @@ function chado_add_node_form_properties(&$form, &$form_state, $details) {
       $property_options = array();
       $property_options[] = 'Select a Property';
       $sql = "
-        SELECT DISTINCT CVT.cvterm_id, CVT.name, CVT.definition
+        SELECT DISTINCT CVT.cvterm_id, CVT.name, CVT.definition, CV.cv_id as cv_id
         FROM  {cvterm} CVT
           INNER JOIN {cv} CV ON CVT.cv_id = CV.cv_id
         WHERE
@@ -426,12 +147,17 @@ function chado_add_node_form_properties(&$form, &$form_state, $details) {
       $prop_types = chado_query($sql, array(':cv_name' => $details['cv_name']));
       while ($prop = $prop_types->fetchObject()) {
         $property_options[$prop->cvterm_id] = $prop->name;
+        $details['cv_id'] = $prop->cv_id;
+      }
+      if (!isset($details['cv_id'])) {
+        $result = chado_select_record('cv',array('cv_id'),array('name' => $details['cv_name']));
+        $details['cv_id'] = $result[0]->cv_id;
       }
     } elseif (isset($details['cv_id'])) {
       $property_options = array();
       $property_options[] = 'Select a Property';
       $sql = "
-        SELECT DISTINCT CVT.cvterm_id, CVT.name, CVT.definition
+        SELECT DISTINCT CVT.cvterm_id, CVT.name, CVT.definition, CV.name as cv_name
         FROM  {cvterm} CVT
           INNER JOIN {cv} CV ON CVT.cv_id = CV.cv_id
         WHERE
@@ -442,23 +168,62 @@ function chado_add_node_form_properties(&$form, &$form_state, $details) {
       $prop_types = chado_query($sql, array(':cv_id' => $details['cv_id']));
       while ($prop = $prop_types->fetchObject()) {
         $property_options[$prop->cvterm_id] = $prop->name;
+        $details['cv_name'] = $prop->cv_name;
+      }
+      if (!isset($details['cv_name'])) {
+        $result = chado_select_record('cv',array('name'),array('cv_id' => $details['cv_id']));
+        $details['cv_name'] = $result[0]->name;
       }
     }
   }
 
+  // Tell tripal administrators how to add terms to the property types drop down.
+  if (empty($property_options)) {
+    $tripal_message = tripal_set_message(
+      t('There are currently no proeprty types! To add additional properties to the drop
+        down list, you need to <a href="@cvtermlink">add a controlled vocabulary term</a>
+        to the %cv_name controlled vocabulary.',
+        array(
+          '%cv_name' => $details['cv_name'],
+          '@cvtermlink' => url('admin/tripal/chado/tripal_cv/cv/'.$details['cv_id'].'/cvterm/add')
+        )
+      ),
+      TRIPAL_WARNING,
+      array('return_html' => TRUE)
+    );
+  }
+  else {
+    $tripal_message = tripal_set_message(
+      t('To add additional properties to the drop down list, you need to <a href="@cvtermlink">add
+        a controlled vocabulary term</a> to the %cv_name controlled vocabulary.',
+        array(
+          '%cv_name' => $details['cv_name'],
+          '@cvtermlink' => url('admin/tripal/chado/tripal_cv/cv/'.$details['cv_id'].'/cvterm/add')
+        )
+      ),
+      TRIPAL_INFO,
+      array('return_html' => TRUE)
+    );
+  }
+
   // the fieldset of the property elements
   $form['properties'] = array(
     '#type' => 'fieldset',
     '#title' => t($details['fieldset_title']),
     '#description' => t('You may add additional properties by selecting a property type
       from the dropdown and adding text. You may add as many properties as desired by
-      clicking the add button on the right. To remove a property, click the remove button.
-      To add additional properties to the drop down. ' . $details['additional_instructions']),
+      clicking the add button on the right. To remove a property, click the remove button.'
+      . $details['additional_instructions']),
     '#prefix' => "<div id='properties-fieldset'>",
     '#suffix' => '</div>',
     '#weight'      => 8
   );
 
+  $form['properties']['admin_message'] = array(
+    '#type' => 'markup',
+    '#markup' => $tripal_message
+  );
+
   // this form element is a tree, so that we don't puke all of the values into then node variable
   // it is set as a tree, and keeps them in the $form_state['values']['property_table'] heading.
   $form['properties']['property_table'] = array(

+ 46 - 2
tripal_core/api/tripal_core.chado_nodes.relationships.api.inc

@@ -150,7 +150,7 @@ function chado_add_node_form_relationships(&$form, &$form_state, $details) {
       $type_options = array();
       $type_options[] = 'Select a Property';
       $sql = "
-        SELECT DISTINCT CVT.cvterm_id, CVT.name, CVT.definition
+        SELECT DISTINCT CVT.cvterm_id, CVT.name, CVT.definition, CV.cv_id as cv_id
         FROM  {cvterm} CVT
           INNER JOIN {cv} CV ON CVT.cv_id = CV.cv_id
         WHERE
@@ -161,12 +161,17 @@ function chado_add_node_form_relationships(&$form, &$form_state, $details) {
       $prop_types = chado_query($sql, array(':cv_name' => $details['cv_name']));
       while ($prop = $prop_types->fetchObject()) {
         $type_options[$prop->cvterm_id] = $prop->name;
+        $details['cv_id'] = $prop->cv_id;
+      }
+      if (!isset($details['cv_id'])) {
+        $result = chado_select_record('cv',array('cv_id'),array('name' => $details['cv_name']));
+        $details['cv_id'] = $result[0]->cv_id;
       }
     } elseif (isset($details['cv_id'])) {
       $type_options = array();
       $type_options[] = 'Select a Property';
       $sql = "
-        SELECT DISTINCT CVT.cvterm_id, CVT.name, CVT.definition
+        SELECT DISTINCT CVT.cvterm_id, CVT.name, CVT.definition, CV.name AS cv_name
         FROM  {cvterm} CVT
           INNER JOIN {cv} CV ON CVT.cv_id = CV.cv_id
         WHERE
@@ -177,10 +182,44 @@ function chado_add_node_form_relationships(&$form, &$form_state, $details) {
       $prop_types = chado_query($sql, array(':cv_id' => $details['cv_id']));
       while ($prop = $prop_types->fetchObject()) {
         $type_options[$prop->cvterm_id] = $prop->name;
+        $details['cv_name'] = $prop->cv_name;
+      }
+      if (!isset($details['cv_name'])) {
+        $result = chado_select_record('cv',array('name'),array('cv_id' => $details['cv_id']));
+        $details['cv_name'] = $result[0]->name;
       }
     }
   }
 
+  // Tell tripal administrators how to add terms to the property types drop down.
+  if (empty($type_options)) {
+    $tripal_message = tripal_set_message(
+      t('There are currently no proeprty types! To add additional properties to the drop
+        down list, you need to <a href="@cvtermlink">add a controlled vocabulary term</a>
+        to the %cv_name controlled vocabulary.',
+        array(
+          '%cv_name' => $details['cv_name'],
+          '@cvtermlink' => url('admin/tripal/chado/tripal_cv/cv/'.$details['cv_id'].'/cvterm/add')
+        )
+      ),
+      TRIPAL_WARNING,
+      array('return_html' => TRUE)
+    );
+  }
+  else {
+    $tripal_message = tripal_set_message(
+      t('To add additional properties to the drop down list, you need to <a href="@cvtermlink">add
+        a controlled vocabulary term</a> to the %cv_name controlled vocabulary.',
+        array(
+          '%cv_name' => $details['cv_name'],
+          '@cvtermlink' => url('admin/tripal/chado/tripal_cv/cv/'.$details['cv_id'].'/cvterm/add')
+        )
+      ),
+      TRIPAL_INFO,
+      array('return_html' => TRUE)
+    );
+  }
+
   $form['relationships'] = array(
     '#type' => 'fieldset',
     '#title' => t($details['fieldset_title']),
@@ -194,6 +233,11 @@ function chado_add_node_form_relationships(&$form, &$form_state, $details) {
     '#weight'      => 10
   );
 
+  $form['relationships']['admin_message'] = array(
+    '#type' => 'markup',
+    '#markup' => $tripal_message
+  );
+
   // this form element is a tree, so that we don't puke all of the values into then node variable
   // it is set as a tree, and keeps them in the $form_state['values']['relationship_table'] heading.
   $form['relationships']['relationship_table'] = array(

+ 42 - 0
tripal_core/api/tripal_core.chado_query.api.inc

@@ -136,6 +136,7 @@
  * @endcode
  *
  * Generic Queries for any SQL:
+ *
  * Often it is necessary to select from more then one table in chado or to execute
  * other complex queries that cannot be handled efficiently by the above functions. It is
  * for this reason that the chado_query( [sql string], [arguments to sub-in to the sql] )
@@ -160,6 +161,47 @@
  * If you are going to need more then a couple fields, you might want to use the
  * Chado Variables API (specifically chado_generate_var()) to select all
  * of the common fields needed including following foreign keys.
+ *
+ * Loading of Variables from chado data:
+ *
+ * These functions, chado_generate_var() and  chado_expand_var(), generate objects
+ * containing the full details of a record(s) in chado. These should be used in all
+ * theme templates.
+ *
+ * This differs from the objects returned by chado_select_record in so far as all foreign key
+ * relationships have been followed meaning you have more complete details. Thus this function
+ * should be used whenever you need a full variable and chado_select_record should be used if
+ * you only case about a few columns.
+ *
+ * The initial variable is generated by the
+ * chado_generate_var([table], [filter criteria], [optional options])
+ * function. An example of how to use this function is:
+ * @code
+   $values = array(
+     'name' => 'Medtr4g030710'
+   );
+   $features = chado_generate_var('feature', $values);
+ * @endcode
+ * This will return an object if there is only one feature with the name Medtr4g030710 or it will
+ * return an array of feature objects if more than one feature has that name.
+ *
+ * Some tables and fields are excluded by default. To have those tables & fields added to
+ * your variable you can use the
+ * chado_expand_var([chado variable], [type], [what to expand], [optional options])
+ * function. An example of how to use this function is:
+ * @code
+   // Get a chado object to be expanded
+   $values = array(
+     'name' => 'Medtr4g030710'
+   );
+   $features = chado_generate_var('feature', $values);
+   // Expand the organism node
+   $feature = chado_expand_var($feature, 'node', 'organism');
+   // Expand the feature.residues field
+   $feature = chado_expand_var($feature, 'field', 'feature.residues');
+   // Expand the feature properties (featureprop table)
+   $feature = chado_expand_var($feature, 'table', 'featureprop');
+ * @endcode
  */
 
 /**

+ 4 - 47
tripal_core/api/tripal_core.chado_variables.api.inc

@@ -4,49 +4,6 @@
  * This API generates objects containing the full details of a record(s) in chado.
  */
 
-/**
- * @defgroup tripal_chado_variables_api Chado Variables API
- * @ingroup tripal_chado_api
- * @{
- * This API generates objects containing the full details of a record(s) in chado.
- * These should be used in all theme templates.
- *
- * This differs from the objects returned by chado_select_record in so far as all foreign key
- * relationships have been followed meaning you have more complete details. Thus this function
- * should be used whenever you need a full variable and chado_select_record should be used if
- * you only case about a few columns.
- *
- * The initial variable is generated by the
- * chado_generate_var([table], [filter criteria], [optional options])
- * function. An example of how to use this function is:
- * @code
-   $values = array(
-     'name' => 'Medtr4g030710'
-   );
-   $features = chado_generate_var('feature', $values);
- * @endcode
- * This will return an object if there is only one feature with the name Medtr4g030710 or it will
- * return an array of feature objects if more than one feature has that name.
- *
- * Some tables and fields are excluded by default. To have those tables & fields added to
- * your variable you can use the
- * chado_expand_var([chado variable], [type], [what to expand], [optional options])
- * function. An example of how to use this function is:
- * @code
-   // Get a chado object to be expanded
-   $values = array(
-     'name' => 'Medtr4g030710'
-   );
-   $features = chado_generate_var('feature', $values);
-   // Expand the organism node
-   $feature = chado_expand_var($feature, 'node', 'organism');
-   // Expand the feature.residues field
-   $feature = chado_expand_var($feature, 'field', 'feature.residues');
-   // Expand the feature properties (featureprop table)
-   $feature = chado_expand_var($feature, 'table', 'featureprop');
- * @endcode
- */
-
 /**
  * Implements hook_exclude_type_by_default()
  *
@@ -70,7 +27,7 @@
  * @return
  *   An array of type => criteria where the type is excluded if the criteria evaluates to TRUE
  *
- * @ingroup tripal_chado_variables_api
+ * @ingroup tripal_chado_query_api
  */
 function tripal_core_exclude_type_by_default() {
   return array('text' => 'strlen("&gt;field_value&lt; ") > 100');
@@ -99,7 +56,7 @@ function tripal_core_exclude_type_by_default() {
  * @return
  *   An array of type => criteria where the type is excluded if the criteria evaluates to TRUE
  *
- * @ingroup tripal_chado_variables_api
+ * @ingroup tripal_chado_query_api
  */
 function tripal_core_exclude_field_from_feature_by_default() {
   return array();
@@ -194,7 +151,7 @@ function tripal_core_exclude_field_from_feature_by_default() {
  * @endcode
  *      will exclude all text fields with a length > 50. Thus if $feature.residues is longer than 50 *      it will be excluded, otherwise it will be added.
  *
- * @ingroup tripal_chado_variables_api
+ * @ingroup tripal_chado_query_api
  */
 function chado_generate_var($table, $values, $base_options = array()) {
   $all = new stdClass();
@@ -498,7 +455,7 @@ function chado_generate_var($table, $values, $base_options = array()) {
    $feature = chado_expand_var($feature, 'table', 'featureprop');
  * @endcode
  *
- * @ingroup tripal_chado_variables_api
+ * @ingroup tripal_chado_query_api
  */
 function chado_expand_var($object, $type, $to_expand, $table_options = array()) {
 

+ 1 - 1
tripal_core/api/tripal_core.custom_tables.api.inc

@@ -5,7 +5,7 @@
  */
 
 /**
- * @defgroup tripal_custom_tables_api Custom Tables API
+ * @defgroup tripal_custom_tables_api Tripal Custom Tables API
  * @ingroup tripal_core_api
  * @{
  * Provides an API to manage custom tables in Chado.

+ 2 - 2
tripal_core/api/tripal_core.files.api.inc

@@ -6,7 +6,7 @@
  */
 
 /**
- * @defgroup tripal_files_api Files API
+ * @defgroup tripal_files_api Tripal Files API
  * @ingroup tripal_core_api
  * @{
  * Provides an application programming interface (API) for managing files within
@@ -47,7 +47,7 @@ function tripal_create_files_dir($module_name, $path = FALSE) {
     // make sure the module data directory exists, we make a recursive call
     // but without the path
     tripal_create_files_dir($module_name);
-  
+
     // now make sure the sub dir exists
     $sub_dir = tripal_get_files_dir() . $module_name . $path;
     if (!file_prepare_directory($sub_dir, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {

+ 1 - 1
tripal_core/api/tripal_core.jobs.api.inc

@@ -6,7 +6,7 @@
  */
 
 /**
- * @defgroup tripal_jobs_api Jobs API
+ * @defgroup tripal_jobs_api Tripal Jobs API
  * @ingroup tripal_core_api
  * @{
  * Tripal offers a job management subsystem for managing tasks that may require an extended period of time for

+ 1 - 1
tripal_core/api/tripal_core.mviews.api.inc

@@ -5,7 +5,7 @@
  */
 
 /**
- * @defgroup tripal_mviews_api Materalized Views API
+ * @defgroup tripal_mviews_api Tripal Materalized Views API
  * @ingroup tripal_core_api
  * @{
  * Provides an application programming interface (API) to manage materialized views in Chado.

+ 207 - 0
tripal_core/api/tripal_core.tripal.api.inc

@@ -0,0 +1,207 @@
+<?php
+/**
+ * @file
+ * Provides an application programming interface (API) for Tripal
+ *
+ * The Tripal API currently provides generic insert/update/select functions for all chado content as
+ * well as some module specific functions that insert/update/delete/select specific chado content.
+ *
+ * This API is currently in its infancy and some necessary functions might be missing. If you find
+ * a missing function that you think should be included go to the sourceforge feature request
+ * page and request it's inclusion in the API. Such feature requests with a working function
+ * definition will be given priority.
+ */
+
+/**
+ * @defgroup tripal_api Tripal API
+ * @{
+ * Provides an application programming interface (API) for Tripal
+ *
+ * The Tripal API currently provides generic insert/update/select functions for all chado content as
+ * well as some module specific functions that insert/update/delete/select specific chado content.
+ *
+ * This API is currently in its infancy and some necessary functions might be missing. If you find
+ * a missing function that you think should be included go to the sourceforge feature request
+ * page and request it's inclusion in the API. Such feature requests with a working function
+ * definition will be given priority.
+ * @}
+ */
+
+// Globals used by Tripals Error catching functions
+// Should match those defined by watchdog
+define('TRIPAL_CRITICAL',2);
+define('TRIPAL_ERROR',3);
+define('TRIPAL_WARNING',4);
+define('TRIPAL_NOTICE',5);
+define('TRIPAL_INFO',6);
+define('TRIPAL_DEBUG',7);
+
+/**
+ * Provide better error notice for Tripal
+ * @param $type
+ *   The catagory to which this message belongs. Can be any string, but the general
+ *   practice is to use the name of the module.
+ * @param $message
+ *   The message to store in the log. Keep $message translatable by not concatenating
+ *   dynamic values into it! Variables in the message should be added by using placeholder
+ *   strings alongside the variables argument to declare the value of the placeholders.
+ *   See t() for documentation on how $message and $variables interact.
+ * @param $variables
+ *   Array of variables to replace in the message on display or NULL if message is
+ *   already translated or not possible to translate.
+ * @param $severity
+ *   The severity of the message; one of the following values:
+ *     - TRIPAL_CRITICAL: Critical conditions.
+ *     - TRIPAL_ERROR: Error conditions.
+ *     - TRIPAL_WARNING: Warning conditions.
+ *     - TRIPAL_NOTICE: (default) Normal but significant conditions.
+ *     - TRIPAL_INFO: Informational messages.
+ *     - TRIPAL_DEBUG: Debug-level messages.
+ * @param $options
+ *   An array of options. Some available options include:
+ *     - print: prints the error message to the terminal screen. Useful when display is the command-line
+ *
+ * @ingroup tripal_api
+ */
+function tripal_report_error($type, $severity, $message, $variables = array(), $options = array()) {
+
+  // Get human-readable severity string
+  $severity_string = '';
+  switch ($severity) {
+    case TRIPAL_CRITICAL:
+      $severity_string = 'CRITICAL';
+      break;
+    case TRIPAL_ERROR:
+      $severity_string = 'ERROR';
+      break;
+    case TRIPAL_WARNING:
+      $severity_string = 'WARNING';
+      break;
+    case TRIPAL_NOTICE:
+      $severity_string = 'NOTICE';
+      break;
+    case TRIPAL_INFO:
+      $severity_string = 'INFO';
+      break;
+    case TRIPAL_DEBUG:
+      $severity_string = 'DEBUG';
+      break;
+  }
+
+  // Send to watchdog
+  try {
+    watchdog($type, $message, $variables, $severity);
+  }
+  catch (Exception $e) {
+    print "CRITICAL (TRIPAL_CORE): Unable to register error message with watchdog";
+    $options['print'] = TRUE;
+  }
+
+  // If print option supplied then print directly to the screen
+  if (isset($options['print'])) {
+    if (sizeof($variables) > 0) {
+      $message = str_replace(array_keys($variables), $variables, $message);
+    }
+    print $severity_string . ' (' . strtoupper($type) . '):' . $message . "\n";
+  }
+}
+
+/**
+ * Display messages to tripal administrators. This can be used instead of
+ * drupal_set_message when you want to target tripal administrators.
+ *
+ * @param $message
+ *   The message to be displayed to the tripal administrators
+ * @param $importance
+ *   The level of importance for this message. In the future this will be used to allow
+ *   administrators to filter some of these messages. It can be one of the following:
+ *     - TRIPAL_CRITICAL: Critical conditions.
+ *     - TRIPAL_ERROR: Error conditions.
+ *     - TRIPAL_WARNING: Warning conditions.
+ *     - TRIPAL_NOTICE: Normal but significant conditions.
+ *     - TRIPAL_INFO: (default) Informational messages.
+ *     - TRIPAL_DEBUG: Debug-level messages.
+ * @param $options
+ *   Any options to apply to the current message. Supported options include:
+ *     - return_html: return HTML instead of setting a drupal message. This can be
+ *         used to place a tripal message in a particular place in the page.
+ *         The default is FALSE.
+ */
+function tripal_set_message($message, $importance = TRIPAL_INFO, $options = array()) {
+  global $user;
+
+  // Only show the message to the administrator user (uid=1)
+  // thus if the current user is not the administrator then return nothing
+  if ($user->uid > 1) {
+    return '';
+  }
+
+  // set defaults
+  $options['return_html'] = (isset($options['return_html'])) ? $options['return_html'] : FALSE;
+
+  // Get human-readable severity string
+  $importance_string = '';
+  switch ($importance) {
+    case TRIPAL_CRITICAL:
+      $importance_string = 'CRITICAL';
+      break;
+    case TRIPAL_ERROR:
+      $importance_string = 'ERROR';
+      break;
+    case TRIPAL_WARNING:
+      $importance_string = 'WARNING';
+      break;
+    case TRIPAL_NOTICE:
+      $importance_string = 'NOTICE';
+      break;
+    case TRIPAL_INFO:
+      $importance_string = 'INFO';
+      break;
+    case TRIPAL_DEBUG:
+      $importance_string = 'DEBUG';
+      break;
+  }
+
+  // Mark-up the Message
+  $full_message =
+     '<div class="tripal-site-admin-message">'
+       . '<span class="tripal-serverity-string ' . strtolower($importance_string) . '">' . $importance_string . ': </span>'
+       . $message
+   . '</div>';
+
+  // Handle whether to return the HTML & let the caller deal with it
+  // or to use drupal_set_message to put it near the top of the page  & let the theme deal with it
+  if ($options['return_html']) {
+    return '<div class="messages tripal-site-admin-only">' . $full_message . '</div>';
+  }
+  else {
+    drupal_set_message($full_message, 'tripal-site-admin-only');
+  }
+
+}
+
+/**
+ * Use this function to encapsulate text intended to be
+ * visible only by the site administrator. A small tripal logo
+ * appears alongside the text.  Do not call this function directly, but
+ * rather, use the theme() function:
+ *
+ *   theme('tripal_admin_message', array('message' => $my_message));
+ *
+ * @param $message
+ *   The message to be displayed to the site administrator
+ *
+ * @ingroup tripal_api
+ */
+function theme_tripal_admin_message($variables) {
+
+  $message = $variables['message'];
+
+  if (!user_access('access administration pages')) {
+    return '';
+  }
+  return "
+    <div class=\"tripal-site-admin-only\">
+      <div class=\"tripal-site-admin-message\">$message</div>
+    </div>";
+}

+ 35 - 23
tripal_core/theme/css/tripal.css

@@ -1,8 +1,8 @@
 /**
  * The Tripal generic node template (node--chado-generc.tpl.php)
- * has an outer div box with class 'tripal-contents' and with an inner 
+ * has an outer div box with class 'tripal-contents' and with an inner
  * table with an id of 'tripal-contents-table'.  The table has a single
- * row with two columns.  The smaller left column houses the table of 
+ * row with two columns.  The smaller left column houses the table of
  * contents (TOC) for the node data.  The larger right column houses the data:
  *
  * |-----------------------------------------------|
@@ -42,9 +42,9 @@
  * the table is meant for organizing the sidebar and contents so they don't
  * slip and slide around as would happen with div boxes that were floated.
  * Therefore, we use !important to keep the default theme from overrideing
- * the table settings. 
+ * the table settings.
  */
- 
+
 .tripal-contents-table tbody {
   padding: 0px !important;
   margin:  0px !important;
@@ -57,7 +57,7 @@
   border:  none !important;
   background-color: transparent !important;
 }
-.tripal-contents-table-td-toc { 
+.tripal-contents-table-td-toc {
   border-right: 1px solid #CCCCCC !important;
   margin:  0px !important;
   padding: 0px !important;
@@ -65,7 +65,7 @@
   text-align: left !important;
   vertical-align: top !important;
 }
-.tripal-contents-table-td-data { 
+.tripal-contents-table-td-data {
   border: none !important;
   margin:  0px !important;
   padding: 0px 0px 0px 20px !important;
@@ -76,7 +76,7 @@
 
 /**
  * The table of contents is an unordered list. The following can are used
- * to style the list 
+ * to style the list
  */
 .tripal_toc_list {
 
@@ -93,11 +93,11 @@
  * Column. Initially, the JavaScript hids all "blocks" except for the "Details"
  * block.  There will be as many blocks as there are TOC links.
  *
- * By default, all blocks have the following layout that consists of a 
+ * By default, all blocks have the following layout that consists of a
  * container div box with the class 'tripal-info-box', a div box to house the
  * block title with the class 'tripal-info-box-title', and a div box to
- * house a brief description about the block with the class 
- * 'tripal-info-box-desc' 
+ * house a brief description about the block with the class
+ * 'tripal-info-box-desc'
  *
  * |-----------------------------------------------|
  * |  .tripal-data-block                           |
@@ -129,7 +129,7 @@
 }
 
 /**
- * Within the block data 
+ * Within the block data
  */
  .tripal-data-table {
    margin-top: 0px;
@@ -139,7 +139,7 @@
 /******************************************************************************
  * The teaser appears anywhere that a small snippet of the content is required.
  * When any node in Drupal is published to the home page a teaser is used.
- * Teasers can also be used in views to provide lists of content. The 
+ * Teasers can also be used in views to provide lists of content. The
  * teaser template is similar to the block but with the following sections and
  * classes
  *
@@ -168,35 +168,47 @@
 
 /**
  * some nodes such as the organism node may have images. This class
- * is used to format any image that appears in the teaser 
+ * is used to format any image that appears in the teaser
  */
 .tripal-teaser-img {
-  width: 100px; 
-  float: left; 
-  padding-right: 10px; 
+  width: 100px;
+  float: left;
+  padding-right: 10px;
   padding-bottom: 5px;
 }
 
 /******************************************************************************
  * Administrative CSS classes
  *****************************************************************************/
- 
+
  /**
-  * This class is used when providing hints or other instructions to the 
+  * This class is used when providing hints or other instructions to the
   * site administrator
-  */ 
- 
-.tripal-site-admin-only {
+  */
+
+div.messages.tripal-site-admin-only{
   background-image: url("../images/TripalLogo-sm.png");
   background-repeat: no-repeat;
   background-color: #cce3ff;
   margin-top: 10px;
   margin-bottom: 10px;
-  border: 1px solid #888888;
+  border: 1px solid #7DA1D4;
   min-height: 50px;
   clear: both;
 }
 
+.tripal-serverity-string {
+  font-weight: bold;
+}
+
+.tripal-serverity-string.critical, .tripal-serverity-string.error {
+  color: #FF0000;
+}
+
+.tripal-serverity-string.warning {
+  color: #FF8000;
+}
+
 .tripal-site-admin-message {
    padding: 10px 10px 10px 55px;
    font-style: italic;
@@ -204,6 +216,6 @@
 
 .tripal-site-admin-only-table-row {
   background-color: #cce3ff;
-  border: 1px solid #888888;
+  border: 1px solid #7DA1D4;
   color: black;
 }

+ 1 - 30
tripal_core/tripal_core.module

@@ -4,36 +4,6 @@
  * The Tripal Core module
  */
 
- /**
- * @defgroup tripal_modules Tripal Modules
- * @{
- * All documented functions for the various Tripal Modules excluding API functions and Views Integration functions.
- * @}
- */
-
-/**
- * @defgroup tripal_api Tripal API
- * @{
- * Provides an application programming interface (API) for Tripal
- *
- * The Tripal API currently provides generic insert/update/select functions for all chado content as
- * well as some module specific functions that insert/update/delete/select specific chado content.
- *
- * This API is currently in its infancy and some necessary functions might be missing. If you find
- * a missing function that you think should be included go to the sourceforge feature request
- * page and request it's inclusion in the API. Such feature requests with a working function
- * definition will be given priority.
- * @}
- */
-
- /**
- * @defgroup tripal_core_api Core Module API
- * @ingroup tripal_api
- * @{
- * Functions providing support for all Tripal modules.
- * @}
- */
-
 /**
  * @defgroup tripal_core Tripal Core Module
  * @ingroup tripal_modules
@@ -61,6 +31,7 @@ require_once 'api/tripal_core.mviews.api.inc';
 // Miscellaneous API
 require_once 'api/tripal_core.files.api.inc';
 require_once 'api/tripal_core.jobs.api.inc';
+require_once 'api/tripal_core.tripal.api.inc';
 
 require_once 'api/tripal_core.DEPRECATED.inc';
 

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

@@ -8,12 +8,281 @@
  * @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 +313,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 +342,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 +370,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 +407,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 +432,13 @@ function tripal_views_is_lightest_priority_setup($setup_id, $table_name) {
 }
 
 /**
- * Programatically enable 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_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.
+ * Rebuilds all the default 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 +456,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 +686,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 +755,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 +795,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 +818,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 +1037,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';
 
 /**