Browse Source

Resolved merge conflict where we both fixed the same bug (in stock & feature check ->op is set before ensuring it's save on validation of node form)

Lacey Sanderson 10 năm trước cách đây
mục cha
commit
8bebb35274
33 tập tin đã thay đổi với 1010 bổ sung853 xóa
  1. 0 2
      .gitignore
  2. 11 9
      tripal_contact/includes/tripal_contact.chado_node.inc
  3. 27 26
      tripal_core/api/tripal_core.chado_nodes.api.inc
  4. 23 16
      tripal_core/api/tripal_core.chado_nodes.title_and_path.inc
  5. 2 2
      tripal_core/api/tripal_core.chado_query.api.inc
  6. 51 0
      tripal_core/api/tripal_core.chado_schema.api.inc
  7. 30 24
      tripal_core/api/tripal_core.custom_tables.api.inc
  8. 5 2
      tripal_core/api/tripal_core.jobs.api.inc
  9. 11 11
      tripal_core/api/tripal_core.schema_v1.2.api.inc
  10. 36 13
      tripal_core/includes/tripal_core.chado_install.inc
  11. 65 52
      tripal_core/includes/tripal_core.custom_tables.inc
  12. 15 15
      tripal_example/README.txt
  13. 15 13
      tripal_example/api/tripal_example.api.inc
  14. 13 11
      tripal_example/includes/tripal_example.admin.inc
  15. 276 241
      tripal_example/includes/tripal_example.chado_node.inc
  16. 12 12
      tripal_example/theme/templates/tripal_example_base.tpl.php
  17. 16 15
      tripal_example/theme/templates/tripal_example_properties.tpl.php
  18. 14 13
      tripal_example/theme/templates/tripal_example_references.tpl.php
  19. 43 42
      tripal_example/theme/templates/tripal_example_relationships.tpl.php
  20. 20 19
      tripal_example/theme/tripal_example.theme.inc
  21. 9 9
      tripal_example/tripal_example.info
  22. 67 68
      tripal_example/tripal_example.install
  23. 119 121
      tripal_example/tripal_example.module
  24. 2 2
      tripal_example/tripal_example.views.inc
  25. 9 9
      tripal_example/tripal_example.views_default.inc
  26. 31 29
      tripal_feature/includes/tripal_feature.chado_node.inc
  27. 7 9
      tripal_feature/includes/tripal_feature.gff_loader.inc
  28. 9 7
      tripal_featuremap/includes/tripal_featuremap.chado_node.inc
  29. 11 9
      tripal_library/includes/tripal_library.chado_node.inc
  30. 20 15
      tripal_organism/includes/tripal_organism.chado_node.inc
  31. 9 7
      tripal_project/includes/tripal_project.chado_node.inc
  32. 19 18
      tripal_pub/includes/tripal_pub.chado_node.inc
  33. 13 12
      tripal_stock/includes/tripal_stock.chado_node.inc

+ 0 - 2
.gitignore

@@ -1,2 +0,0 @@
-.project
-.settings

+ 11 - 9
tripal_contact/includes/tripal_contact.chado_node.inc

@@ -250,19 +250,19 @@ function chado_contact_validate($node, $form, &$form_state) {
   // Since this validate can be called on AJAX and Deletion of the node
   // we need to make this check to ensure queries are not executed
   // without the proper values.
-  if($node->op != 'Save') {
+  if(property_exists($node, "op") and $node->op != 'Save') {
     return;
   }
 
   // we are syncing if we do not have a node ID but we do have a contact_id. We don't
   // need to validate during syncing so just skip it.
-  if (is_null($node->nid) and property_exists($node, 'contact_id') and $node->contact_id != 0) {
+  if (!property_exists($node, 'nid') and property_exists($node, 'contact_id') and $node->contact_id != 0) {
     return;
   }
 
   // remove surrounding white-space on submitted values
-  $node->contactname    = trim($node->contactname);
-  $node->description    = trim($node->description);
+  $node->contactname = property_exists($node, 'contactname') ? trim($node->contactname) : '';
+  $node->description = property_exists($node, 'description') ? trim($node->description) : '';
 
 
   // Validating for an update
@@ -367,15 +367,17 @@ function chado_contact_node_access($node, $op, $account ) {
  * @ingroup tripal_contact
  */
 function chado_contact_insert($node) {
-
-  // remove surrounding white-space on submitted values
-  $node->contactname    = trim($node->contactname);
-  $node->description    = trim($node->description);
+  $contact_id = '';
 
   // if there is a contact_id in the $node object then this must be a sync so
   // we can skip adding the contact as it is already there, although
-  // we do need to proceed with the rest of the insert
+  // we do need to proceed with insertion into the chado/drupal linking table.
   if (!property_exists($node, 'contact_id')) {
+    // remove surrounding white-space on submitted values
+    $node->contactname    = trim($node->contactname);
+    $node->description    = trim($node->description);
+
+
     // insert and then get the newly inserted contact record
     $values = array(
       'name'           => $node->contactname,

+ 27 - 26
tripal_core/api/tripal_core.chado_nodes.api.inc

@@ -115,7 +115,7 @@ function chado_node_get_base_table($content_type, $module = FALSE) {
   }
   else {
     $node_types = module_invoke_all('node_info');
-  
+
     if (isset($node_types[$content_type])) {
       $node_info = $node_types[$content_type];
     }
@@ -123,7 +123,7 @@ function chado_node_get_base_table($content_type, $module = FALSE) {
       return FALSE;
     }
   }
-  
+
   if (isset($node_info['chado_node_api']['base_table'])) {
     return $node_info['chado_node_api']['base_table'];
   }
@@ -456,18 +456,18 @@ function chado_node_sync_form_submit($form, $form_state) {
 
 /**
  * Generic function for syncing records in Chado with Drupal nodes.
- * 
+ *
  * @param $base_table
  *   The name of the Chado table containing the record that should be synced
  * @param $max_sync
- *   Optional: A numeric value to indicate the maximum number of records to sync. 
+ *   Optional: A numeric value to indicate the maximum number of records to sync.
  * @param $organism_id
  *   Optional: Limit the list of records to be synced to only those that
  *   are associated with this organism_id. If the record is not assocaited
  *   with an organism then this field is not needed.
  * @param $types
  *   Optional: Limit the list of records to be synced to only those that
- *   match the types listed in this array. 
+ *   match the types listed in this array.
  * @param $ids
  *   Optional:  Limit the list of records to bye synced to only those whose
  *   primary key value matches the ID provided in this array.
@@ -480,7 +480,7 @@ function chado_node_sync_form_submit($form, $form_state) {
  * @param $job_id
  *   Optional. Used by the Trpial Jobs system when running this function
  *   as a job. It is not needed othewise.
- * 
+ *
  * @ingroup tripal_chado_node_api
  */
 function chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id = FALSE,
@@ -539,9 +539,9 @@ function chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id =
   $hook_query_alter = $linking_table . '_chado_node_sync_select_query';
   if (function_exists($hook_query_alter)) {
     $update = call_user_func($hook_query_alter, array(
-      'select' => $select, 
-      'joins' => $joins, 
-      'where_clauses' => $where_clauses, 
+      'select' => $select,
+      'joins' => $joins,
+      'where_clauses' => $where_clauses,
       'where_args' => $where_args,
     ));
     // Now add in any new changes
@@ -573,7 +573,7 @@ function chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id =
     $where .= ') ';
     $sql_args = array_merge($sql_args, $where_args[$category]);
   }
-  
+
   if ($where) {
     $query .= $where;
   }
@@ -610,6 +610,7 @@ function chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id =
       "If the sync fails or is terminated prematurely then the entire set of \n" .
       "synced items is rolled back and will not be found in the database\n\n";
   try {
+    $percent = 0;
     foreach ($results as $record) {
 
       //print "\nLoading $base_table " . ($i + 1) . " of $count ($base_table_id=" . $record->{$base_table_id} . ")...";
@@ -652,6 +653,7 @@ function chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id =
         $form = array();
         $form_state = array();
         node_validate($new_node, $form, $form_state);
+
         if (!form_get_errors()) {
           $node = node_submit($new_node);
           node_save($node);
@@ -665,14 +667,13 @@ function chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id =
     }
     print "\n\nComplete!\n";
   }
-  
+
   catch (Exception $e) {
     $transaction->rollback();
     print "\n"; // make sure we start errors on new line
     watchdog_exception('trp-fsync', $e);
     print "FAILED: Rolling back database changes...\n";
   }
-
 }
 
 /**
@@ -883,43 +884,43 @@ function hook_chado_node_sync_form_submit ($form, $form_state) {
  * Note: For your own module, replace hook in the function name with the machine-name of
  * your chado node type (ie: chado_feature).
  *
- * @param $query 
- *   An array containing the following: 
+ * @param $query
+ *   An array containing the following:
  *    'select': An array of select clauses
- *    'joins:  An array of joins (ie: a single join could be 
+ *    'joins:  An array of joins (ie: a single join could be
  *      'LEFT JOIN {chadotable} alias ON base.id=alias.id')
- *    'where_clauses: An array of where clauses which will all be AND'ed 
+ *    'where_clauses: An array of where clauses which will all be AND'ed
  *      together. Use :placeholders for values.
- *    'where_args: An associative array of arguments to be subbed in to the 
+ *    'where_args: An associative array of arguments to be subbed in to the
  *      where clause where the
  *
  * @ingroup tripal_chado_node_api
  */
 function hook_chado_node_sync_select_query($query) {
 
-  // You can add fields to be selected. Be sure to prefix each field with the 
+  // You can add fields to be selected. Be sure to prefix each field with the
   // tale name.
   $query['select'][] = 'example.myfavfield';
 
-  // Provide any join you may need to the joins array. Be sure to wrap the 
+  // Provide any join you may need to the joins array. Be sure to wrap the
   // table name in curly brackets.
   $query['joins'][] = 'LEFT JOIN {exampleprop} PROP ON PROP.example_id=EXAMPLE.example_id';
 
-  // The category should be a unique id for a group of items that will be 
+  // The category should be a unique id for a group of items that will be
   // concatenated together via an SQL 'OR'.  By default the $where_clases
-  // variable will come with categories of 'id', 'organism' and 'type'.  
+  // variable will come with categories of 'id', 'organism' and 'type'.
   // you can add your own unique category or alter the contents of the existing
   // categories.  Be sure to make sure the category doesn't already exist
   // in the $query['where_clauses']
-  $category = 'my_category'; 
-  
+  $category = 'my_category';
+
   // Provide any aditionall where clauses and their necessary arguments.
-  // Be sure to prefix the field with the table name.   Be sure that the 
-  // placeholder is unique across all categories (perhaps add a unique 
+  // Be sure to prefix the field with the table name.   Be sure that the
+  // placeholder is unique across all categories (perhaps add a unique
   // prefix/suffix).
   $query['where_clauses'][$category][] = 'example.myfavfield = :favvalue';
   $query['where_args'][$category][':favvalue'] = 'awesome-ness';
-  
+
   // Must return the updated query
   return $query;
 }

+ 23 - 16
tripal_core/api/tripal_core.chado_nodes.title_and_path.inc

@@ -576,7 +576,10 @@ function chado_get_node_url($node) {
  *   error is displayed.
  *
  * @param $node
- *   The node to set the URL for.
+ *   The node to set the URL for.  The node object must have at a
+ *   minimum the 'nid' and 'type' properties, as well as the
+ *   chado object (e.g. 'organism' for chado_organism node type, and
+ *   'feature' for chado_feature node type, etc.).
  *
  * @return
  *   The URL alias that was set.
@@ -663,9 +666,7 @@ function chado_update_existing_node_urls($content_type, $job_id = 0) {
 
   try {
     // Get the number of records we need to set URLs for.
-    $num_nodes = db_query(
-        'SELECT count(*) FROM {' . $content_type . '}'
-      )->fetchField();
+    $num_nodes = db_query('SELECT count(*) FROM {' . $content_type . '}')->fetchField();
 
     // Calculate the interval at which we will print an update on the screen.
     $num_set = 0;
@@ -673,8 +674,8 @@ function chado_update_existing_node_urls($content_type, $job_id = 0) {
 
     if ($num_nodes > 0) {
 
-      print "There are $num_nodes nodes to update URLs for. You will be \n"
-       . "updated on the progress every 100 nodes.\n\n";
+      print "There are $num_nodes nodes to update URLs for. You will be \n" .
+            "updated on the progress every 100 nodes.\n\n";
 
       // Get the list of nodes of this particular content type.
       $query = new EntityFieldQuery();
@@ -687,10 +688,16 @@ function chado_update_existing_node_urls($content_type, $job_id = 0) {
 
         foreach ($nids as $nid) {
 
-          // Load the current node.
-          // We do it this way instead of using noad_load_multiple to load them
-          // all at once to avoid overloading the memory.
-          $node = node_load($nid);
+          // Load the current node. Normally here we would use the node_load()
+          // function that is part of the Drupal API.  However, this seems
+          // to have memory leaks that have not yet been identified, so
+          // we'll create the object by hand:
+          $node = new stdClass();
+          $node->nid = $nid;
+          $node->type = $content_type;
+          $table = preg_replace('/chado_/', '', $content_type);
+          $id = chado_get_id_from_nid($table, $nid);
+          $node->$table = chado_generate_var($table, array($table . "_id" => $id));
 
           // Now set the URL for the current node.
           $alias = chado_set_node_url($node);
@@ -699,14 +706,14 @@ function chado_update_existing_node_urls($content_type, $job_id = 0) {
           if ($num_set % $num_per_interval == 0) {
             $percent = ($num_set / $num_nodes) * 100;
 
+            // Update the user on progress.
+            $percent = sprintf("%.2f", $percent);
+            print "Setting URLs (" . $percent . "%). Memory: " . number_format(memory_get_usage()) . " bytes.\r";
+
             // Update the tripal job.
             if ($job_id) {
               tripal_set_job_progress($job_id, intval($percent));
             }
-
-            // Update the user on progress.
-            $percent = sprintf("%.2f", $percent);
-            print "Setting URLs (" . $percent . "%). Memory: " . number_format(memory_get_usage()) . " bytes.\r";
           }
           $num_set++;
         }
@@ -736,7 +743,7 @@ function chado_update_existing_node_urls($content_type, $job_id = 0) {
 }
 
 /**
- * Generic "Set Node url" sub-form for setting the url of any chado node
+ * Generic "Set Node URL" sub-form for setting the url of any chado node
  *
  * @param $form
  *   The Drupal form array into which the property form elements will be added
@@ -1305,7 +1312,7 @@ function chado_get_token_value($token_info, $node) {
   $token = $token_info['token'];
   $table = $token_info['table'];
   $var = $node;
-  
+
   // Iterate through each portion of the location string. An example string
   // might be:  stock > type_id > name.
   $location = explode('>', $token_info['location']);

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

@@ -905,7 +905,7 @@ function chado_delete_record($table, $match, $options = NULL) {
  * Additional Options Include:
  *  - has_record
  *     Set this argument to 'TRUE' to have this function return a numeric
- *     value for the number of recrods rather than the array of records.  this
+ *     value for the number of records rather than the array of records.  this
  *     can be useful in 'if' statements to check the presence of particula records.
  *  - return_sql
  *     Set this to 'TRUE' to have this function return an array where the first
@@ -1349,7 +1349,7 @@ function chado_select_record($table, $columns, $values, $options = NULL) {
     }
     $sql = drupal_substr($sql, 0, -2);  // get rid of the trailing ', '
   }
-  
+
   // Limit the records returned
   if (array_key_exists('limit', $options) and is_numeric($options['limit'])) {
     $sql .= " LIMIT " . $options['limit'];

+ 51 - 0
tripal_core/api/tripal_core.chado_schema.api.inc

@@ -56,6 +56,57 @@ function chado_table_exists($table) {
   return TRUE;
 }
 
+/**
+ * A Chado-aware replacement for the db_index_exists() function.
+ *
+ * @param $table
+ *   The table to be altered.
+ * @param $name
+ *   The name of the index.
+ */
+function chado_index_exists($table, $name) {
+  global $databases;
+
+  $indexname = $table . '_' . $name . '_idx';
+
+  $default_db = $databases['default']['default']['database'];
+
+  $sql = "SELECT 1 as exists FROM pg_indexes WHERE indexname = :indexname";
+
+  $result = db_query($sql, array(':indexname' => $indexname));
+  $exists = $result->fetchObject();
+  return $exists->exists;
+}
+
+/**
+ * A Chado-aware wrapper for the db_add_index() function.
+ *
+ * @param $table
+ *   The table to be altered.
+ * @param $name
+ *   The name of the index.
+ * @param $fields
+ *   An array of field names.
+ */
+function chado_add_index($table, $name, $fields) {
+  $indexname = $table . '_' . $name . '_idx';
+
+  $query = 'CREATE INDEX "' . $indexname . '" ON {' . $table . '} ';
+  $query .= '(';
+  $temp = array();
+  foreach ($fields as $field) {
+    if (is_array($field)) {
+      $temp[] = 'substr(' . $field[0] . ', 1, ' . $field[1] . ')';
+    }
+    else {
+      $temp[] = '"' . $field . '"';
+    }
+  }
+  $query .= implode(', ', $temp);
+  $query .= ')';
+  return chado_query($query);
+}
+
 /**
  * Check that any given schema exists
  *

+ 30 - 24
tripal_core/api/tripal_core.custom_tables.api.inc

@@ -38,26 +38,26 @@ function chado_edit_custom_table($table_id, $table_name, $schema, $skip_if_exist
     $record->table_id = $table_id;
     $record->table_name = $table_name;
     $record->schema = serialize($schema);
-  
+
     // get the current custom table record
     $sql = "SELECT * FROM {tripal_custom_tables} WHERE table_id = :table_id";
     $results = db_query($sql, array(':table_id' => $table_id));
     $custom_table = $results->fetchObject();
-  
+
     // if this is a materialized view then don't allow editing with this function
     if ($custom_table->mview_id) {
       tripal_report_error('tripal_core', TRIPAL_ERROR, "Please use the tripal_edit_mview() function to edit this custom table as it is a materialized view.", array());
       drupal_set_message("This custom table is a materialized view. Please use the "  . l('Materialized View', 'admin/tripal/schema/mviews') . " interface to edit it.", 'error');
       return FALSE;
     }
-    
+
     // if the user changed the table name, we want to drop the old one and force
     // creation of the new one.
     if ($custom_table->table_name != $table_name) {
       chado_query("DROP TABLE %s", $custom_table->table_name);
       $skip_if_exists = 0; // we want to create the table
     }
-  
+
     // if skip creation is not set, then drop the table from chado if it exists
     if (!$skip_if_exists) {
       if (db_table_exists($custom_table->table_name)) {
@@ -65,7 +65,7 @@ function chado_edit_custom_table($table_id, $table_name, $schema, $skip_if_exist
         drupal_set_message(t("Custom Table " . $custom_table->table_name . " dropped"));
       }
     }
-  
+
     // update the custom table record and run the create custom table function
     drupal_write_record('tripal_custom_tables', $record, 'table_id');
     $success = chado_create_custom_table ($table_name, $schema, $skip_if_exists);
@@ -90,10 +90,10 @@ function chado_edit_custom_table($table_id, $table_name, $schema, $skip_if_exist
  * table. This way the function cannot be used to accidentally alter existing
  * non custom tables.  If $skip_if_exists is set then the table is simply
  * added to the tripal_custom_tables and no table is created in Chado.
- * 
- * If you are creating a materialized view do not use this function, but rather 
+ *
+ * If you are creating a materialized view do not use this function, but rather
  * use the tripal_add_mview(). A materialized view is also considered a custom table
- * and an entry for it will be added to both the tripal_mviews and 
+ * and an entry for it will be added to both the tripal_mviews and
  * tripal_custom_tables tables, but only if the tripal_add_mview() function is
  * used. The optional $mview_id parameters in this function is intended
  * for use by the tripal_add_mview() function when it calls this function
@@ -129,20 +129,20 @@ function chado_create_custom_table($table, $schema, $skip_if_exists = 1, $mview_
     $sql = "SELECT * FROM {tripal_custom_tables} WHERE table_name = :table_name";
     $results = db_query($sql, array(':table_name' => $table));
     $centry = $results->fetchObject();
-  
+
     // check to see if the table already exists in the chado schema
     $exists = chado_table_exists($table);
-  
+
     // if the table does not exist then create it
     if (!$exists) {
       $ret = db_create_table('chado.' . $table, $schema);
       $created = 1;
     }
-  
+
     // if the table exists in Chado and in our custom table and
     // skip creation is turned off then drop and re-create the table
     if ($exists and is_object($centry) and !$skip_if_exists) {
-  
+
       // drop the table we'll recreate it with the new schema
       chado_query('DROP TABLE {' . $table . '}');
       // remove any 'referring_tables' from the array as the db_create_table doesn't use that
@@ -153,7 +153,7 @@ function chado_create_custom_table($table, $schema, $skip_if_exists = 1, $mview_
       db_create_table('chado.' . $table, $new_schema);
       $recreated = 1;
     }
-  
+
     // add an entry in the tripal_custom_table
     $record = new stdClass();
     $record->table_name = $table;
@@ -161,17 +161,17 @@ function chado_create_custom_table($table, $schema, $skip_if_exists = 1, $mview_
     if ($mview_id) {
       $record->mview_id = $mview_id;
     }
-  
+
     // if an entry already exists then remove it
     if ($centry) {
       $sql = "DELETE FROM {tripal_custom_tables} WHERE table_name = :table_name";
       db_query($sql, array(':table_name' => $table));
     }
-    $success = drupal_write_record('tripal_custom_tables', $record); 
+    $success = drupal_write_record('tripal_custom_tables', $record);
 
     // now add any foreign key constraints
     if (($created or !$skip_if_exists) and array_key_exists('foreign keys', $schema)) {
-  
+
       // iterate through the foreign keys and add each one
       $fkeys = $schema['foreign keys'];
       foreach ($fkeys as $fktable => $fkdetails) {
@@ -192,7 +192,7 @@ function chado_create_custom_table($table, $schema, $skip_if_exists = 1, $mview_
     $transaction->rollback();
     watchdog_exception('tripal_core', $e);
     $error = _drupal_decode_exception($e);
-    drupal_set_message(t("Could not add custom table '%table_name': %message.", 
+    drupal_set_message(t("Could not add custom table '%table_name': %message.",
       array('%table_name' => $table, '%message' => $error['!message'])), 'error');
     return FALSE;
   }
@@ -209,25 +209,31 @@ function chado_create_custom_table($table, $schema, $skip_if_exists = 1, $mview_
 }
 
 /**
- * This function is used to validate a Drupal Schema API array prior to 
+ * This function is used to validate a Drupal Schema API array prior to
  * passing it ot the chado_create_custom_table_schema().  This function
  * can be used in a form validate function or whenver a schema is provided by
  * a user and needs validation.
- * 
+ *
  * @param $schema_array
  *   the Drupal Schema API compatible array
- *   
+ *
  * @return
  *   An empty string for success or a message string for failure
- * 
+ *
  * @ingroup tripal_custom_tables_api
  */
 function chado_validate_custom_table_schema($schema_array) {
 
+
   if (is_array($schema_array) and !array_key_exists('table', $schema_array)) {
     return "The schema array must have key named 'table'";
   }
-  
+
+  if (!ctype_lower($schema_array['table'])) {
+    return "Postgres will automatically change the table name to lower-case. To prevent unwanted side-effects, please rename the table with all lower-case characters.";
+  }
+
+
   // check index length
   if (array_key_exists('indexes', $schema_array)) {
     foreach ($schema_array['indexes'] as $index_name => $details) {
@@ -239,7 +245,7 @@ function chado_validate_custom_table_schema($schema_array) {
       }
     }
   }
-  
+
   // check unique key length
   if (array_key_exists('unique keys', $schema_array)) {
     foreach ($schema_array['unique keys'] as $index_name => $details) {
@@ -251,7 +257,7 @@ function chado_validate_custom_table_schema($schema_array) {
       }
     }
   }
-  
+
 }
 /**
  * Retrieve the custom table id given the name

+ 5 - 2
tripal_core/api/tripal_core.jobs.api.inc

@@ -83,8 +83,11 @@ function tripal_add_job($job_name, $modulename, $callback, $arguments, $uid, $pr
   $record->arguments = $args;
 
   if (drupal_write_record('tripal_jobs', $record)) {
-    $jobs_url = url("admin/tripal/tripal_jobs");
-    drupal_set_message(t("Job '%job_name' submitted.  Check the <a href='!jobs_url'>jobs page</a> for status", array('%job_name' => $job_name, '!jobs_url' => $jobs_url)));
+    drupal_set_message(t("Job '%job_name' submitted.", array('%job_name' => $job_name)));
+    if (user_access('administer tripal')) {
+      $jobs_url = url("admin/tripal/tripal_jobs");
+      drupal_set_message(t("Check the <a href='!jobs_url'>jobs page</a> for status.", array('!jobs_url' => $jobs_url)));
+    }
   }
   else {
     drupal_set_message(t("Failed to add job %job_name.", array('%job_name' => $job_name)), 'error');

+ 11 - 11
tripal_core/api/tripal_core.schema_v1.2.api.inc

@@ -73,7 +73,7 @@ function tripal_core_chado_schema_v1_2_acquisition() {
         'description' => '',
         'type' => 'datetime',
         'not null' => FALSE,
-        'default' => 'ow(',
+        'default' => 'now()',
       ),
       'name' => array(
         'description' => '',
@@ -384,7 +384,7 @@ function tripal_core_chado_schema_v1_2_analysis() {
         'description' => '',
         'type' => 'datetime',
         'not null' => TRUE,
-        'default' => 'ow(',
+        'default' => 'now()',
       ),
     ),
     'primary key' => array(
@@ -937,7 +937,7 @@ function tripal_core_chado_schema_v1_2_assay() {
         'description' => '',
         'type' => 'datetime',
         'not null' => FALSE,
-        'default' => 'ow(',
+        'default' => 'now()',
       ),
       'arrayidentifier' => array(
         'description' => '',
@@ -1738,13 +1738,13 @@ function tripal_core_chado_schema_v1_2_cell_line() {
         'description' => '',
         'type' => 'datetime',
         'not null' => TRUE,
-        'default' => 'ow(',
+        'default' => 'now()',
       ),
       'timelastmodified' => array(
         'description' => '',
         'type' => 'datetime',
         'not null' => TRUE,
-        'default' => 'ow(',
+        'default' => 'now()',
       ),
     ),
     'primary key' => array(
@@ -4889,13 +4889,13 @@ function tripal_core_chado_schema_v1_2_feature() {
         'description' => '',
         'type' => 'datetime',
         'not null' => TRUE,
-        'default' => 'ow(',
+        'default' => 'now()',
       ),
       'timelastmodified' => array(
         'description' => '',
         'type' => 'datetime',
         'not null' => TRUE,
-        'default' => 'ow(',
+        'default' => 'now()',
       ),
     ),
     'primary key' => array(
@@ -7136,13 +7136,13 @@ function tripal_core_chado_schema_v1_2_library() {
         'description' => '',
         'type' => 'datetime',
         'not null' => TRUE,
-        'default' => 'ow(',
+        'default' => 'now()',
       ),
       'timelastmodified' => array(
         'description' => '',
         'type' => 'datetime',
         'not null' => TRUE,
-        'default' => 'ow(',
+        'default' => 'now()',
       ),
     ),
     'primary key' => array(
@@ -11682,7 +11682,7 @@ function tripal_core_chado_schema_v1_2_quantification() {
         'description' => '',
         'type' => 'datetime',
         'not null' => FALSE,
-        'default' => 'ow(',
+        'default' => 'now()',
       ),
       'name' => array(
         'description' => '',
@@ -13881,7 +13881,7 @@ function tripal_core_chado_schema_v1_2_tableinfo() {
         'description' => '',
         'type' => 'date',
         'not null' => TRUE,
-        'default' => 'ow(',
+        'default' => 'now()',
       ),
     ),
     'primary key' => array(

+ 36 - 13
tripal_core/includes/tripal_core.chado_install.inc

@@ -32,31 +32,54 @@ function tripal_core_chado_load_form() {
         'Upgrade Chado v1.11 to v1.2' => t('Upgrade existing Chado v1.11 to v1.2 (no data is lost)'),
         'Install Chado v1.11' => t('New Install of Chado v1.11 (erases all existing Chado data if Chado already exists)')
      ),
-     '#description' => t('Select an action to perform'),
-     '#required' => TRUE
+     '#description' => t('Select an action to perform. If you want to install Chado all other Tripal modules must not be installed.'),
+     '#required' => TRUE,
   );
 
-  $form['description'] = array(
-    '#type' => 'item',
-    '#value' => t("<font color=\"red\">WARNING:</font> A new install of Chado v1.2 or v1.11 "
-      . "will install Chado within the Drupal database in a \"chado\" schema. If the \"chado\" schema already exists it will "
-      . "be overwritten and all data will be lost.  You may choose to update an existing Chado v1.11 if it was installed with a previous "
-      . "version of Tripal (e.g. v0.3b or v0.3.1). The update will not erase any data. "
-      . "If you are using chado in a database external to the "
-      . "Drupal database with a 'chado' entry in the 'settings.php' \$db_url argument "
-      . "then Chado will be installed but will not be used .  The external "
-      . "database specified in the settings.php file takes precedence."),
+  $form['warning'] = array(
+    '#markup' => "<div><font color=\"red\">WARNING:</font>" . t('A new install of
+      Chado will remove and recreate the Chado database if it already exists.') . '</div>',
   );
 
   $form['button'] = array(
     '#type' => 'submit',
     '#value' => t('Install/Upgrade Chado'),
-    '#weight' => 2,
   );
 
   return $form;
 }
 
+function tripal_core_chado_load_form_validate($form, &$form_state) {
+  // We do not want to allow re-installation of Chado if other
+  // Tripal modules are installed.  This is because the install files
+  // of those modules may add content to Chado and reinstalling Chado
+  // removes that content which may break the modules.
+
+  if ($form_state['values']['action_to_do'] == "Install Chado v1.2" or
+      $form_state['values']['action_to_do'] == "Install Chado v1.11") {
+
+    $modules = system_get_info('module');
+    $list = array();
+    foreach ($modules as $mname => $module) {
+      if (array_key_exists('dependencies', $module) and in_array('tripal_core', $module['dependencies'])) {
+        $list[] = $module['name'] . " ($mname)";
+      }
+    }
+    if (count($list) > 0) {
+      form_set_error("action_to_do", "Chado cannot be installed while other Tripal modules
+          are enabled.  You must fully uninstall the following modules if you
+          would like to install or re-install chado.<br>" .
+          implode("<br>", $list));
+    }
+  }
+  if ($form_state['values']['action_to_do'] == "Upgrade Chado v1.11 to v1.2") {
+    // Make sure we are already not at v1.2
+    $real_version = chado_get_version(TRUE);
+    if ($real_version == "1.2") {
+      form_set_error("action_to_do", "You are already at v1.2.  There is no need to upgrade.");
+    }
+  }
+}
 /**
  * Submit Load Chado Schema Form
  *

+ 65 - 52
tripal_core/includes/tripal_core.custom_tables.inc

@@ -57,7 +57,7 @@ function tripal_custom_table_admin_view() {
  * @ingroup tripal_custom_tables
  */
 function tripal_custom_table_new_page() {
- 
+
   $form = drupal_get_form('tripal_custom_tables_form');
   return drupal_render($form);
 }
@@ -140,7 +140,7 @@ function tripal_custom_tables_form($form, &$form_state = NULL, $table_id = NULL)
     $sql = "SELECT * FROM {tripal_custom_tables} WHERE table_id = :table_id ";
     $results = db_query($sql, array(':table_id' => $table_id));
     $custom_table = $results->fetchObject();
-    
+
     // if this is a materialized view then don't allow editing with this function
     if (property_exists($custom_table, 'mview_id') and $custom_table->mview_id) {
       drupal_set_message("This custom table is a materialized view. Please use the "  . l('Materialized View', 'admin/tripal/schema/mviews') . " interface to edit it.", 'error');
@@ -161,7 +161,7 @@ function tripal_custom_tables_form($form, &$form_state = NULL, $table_id = NULL)
       $default_schema = preg_replace('/=>\s+\n\s+array/', '=> array', $default_schema);
     }
   }
-  
+
   $form['return'] = array(
     '#type' => 'markup',
     '#markup' => "<p>" . l("Return to list of custom tables", "admin/tripal/schema/custom_tables") . "</p>",
@@ -178,49 +178,33 @@ function tripal_custom_tables_form($form, &$form_state = NULL, $table_id = NULL)
     '#value' => $table_id
   );
 
-  $form['instructions']= array(
+  $form['instructions'] = array(
+    '#type' => 'fieldset',
+    '#title' => 'Instructions',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['instructions']['text'] = array(
     '#type'          => 'item',
-    '#description'         => t('At times it is necessary to add a custom table to the Chado schema.
-       These are not offically sanctioned tables but may be necessary for local data requirements.
-       Avoid creating custom tables when possible as other GMOD tools may not recognize these tables
-       nor the data in them.  Linker tables or property tables are often a good candidate for
-       a custom table. For example a table to link stocks and libraries (e.g. library_stock). 
-       Try to model linker or propery tables after existing tables.  If the
-       table already exists it will not be modified.  To force dropping and recreation of the table
-       click the checkbox below.  Tables are defined usign the ' . l('Drupal Schema API', 'https://api.drupal.org/api/drupal/includes!database!schema.inc/group/schemaapi/7', array('attributes' => array('target' => '_blank')))
+    '#description'         => '<p>' . t('At times it is necessary to add a custom table
+       to the Chado schema. These are not offically sanctioned tables but may
+       be necessary for local data requirements. Avoid creating custom tables
+       when possible as other GMOD tools may not recognize these tables nor
+       the data in them.  Linker tables or property tables are often a good
+       candidate for a custom table. For example a table to link stocks and
+       libraries (e.g. library_stock). Try to model linker or propery tables
+       after existing tables.  If the table already exists it will not be
+       modified.  To force dropping and recreation of the table
+       click the checkbox below.  Tables are defined usign the ' .
+       l('Drupal Schema API', 'https://api.drupal.org/api/drupal/includes!database!schema.inc/group/schemaapi/7',
+         array('attributes' => array('target' => '_blank'))) . '</p>' .
+      '<p>Please note that table names should be all lower-case.</p>'
     ),
   );
 
-  $form['force_drop']= array(
-    '#type'          => 'checkbox',
-    '#title'         => t('Re-create table'),
-    '#description'   => t('Check this box if your table already exists and you would like to drop it and recreate it.'),
-    '#default_value' => $default_force_drop,
-  );
-  $form['schema']= array(
-    '#type'          => 'textarea',
-    '#title'         => t('Schema Array'),
-    '#description'   => t('Please enter the ' . l('Drupal Schema API', 'https://api.drupal.org/api/drupal/includes!database!schema.inc/group/schemaapi/7', array('attributes' => array('target' => '_blank'))) . ' compatible array that defines the table.'),
-    '#required'      => FALSE,
-    '#default_value' => $default_schema,
-    '#rows'          => 25,
-  );
-
-  if ($action == 'Edit') {
-    $value = 'Save';
-  }
-  if ($action == 'Add') {
-    $value = 'Add';
-  }
-  $form['submit'] = array(
-    '#type'         => 'submit',
-    '#value'        => t($value),
-    '#executes_submit_callback' => TRUE,
-  );
-
-  $form['example']= array(
-    '#type'          => 'item',
-    '#description'         => "<br>Example library_stock table: <pre>
+  $form['instructions']['example']= array(
+      '#type'          => 'item',
+      '#description'         => "Example library_stock table: <pre>
 array (
   'table' => 'library_stock',
   'fields' => array (
@@ -264,6 +248,35 @@ array (
     </pre>",
   );
 
+  $form['force_drop']= array(
+    '#type'          => 'checkbox',
+    '#title'         => t('Re-create table'),
+    '#description'   => t('Check this box if your table already exists and you would like to drop it and recreate it.'),
+    '#default_value' => $default_force_drop,
+  );
+  $form['schema']= array(
+    '#type'          => 'textarea',
+    '#title'         => t('Schema Array'),
+    '#description'   => t('Please enter the ' . l('Drupal Schema API', 'https://api.drupal.org/api/drupal/includes!database!schema.inc/group/schemaapi/7', array('attributes' => array('target' => '_blank'))) . ' compatible array that defines the table.'),
+    '#required'      => FALSE,
+    '#default_value' => $default_schema,
+    '#rows'          => 25,
+  );
+
+  if ($action == 'Edit') {
+    $value = 'Save';
+  }
+  if ($action == 'Add') {
+    $value = 'Add';
+  }
+  $form['submit'] = array(
+    '#type'         => 'submit',
+    '#value'        => t($value),
+    '#executes_submit_callback' => TRUE,
+  );
+
+
+
 
   return $form;
 }
@@ -301,13 +314,13 @@ function tripal_custom_tables_form_validate($form, &$form_state) {
       if (is_array($schema_array) and !array_key_exists('table', $schema_array)) {
         form_set_error('schema', t("The schema array must have key named 'table'"));
       }
-      
+
       // validate the contents of the array
       $error = chado_validate_custom_table_schema($schema_array);
       if ($error) {
         form_set_error('schema', $error);
       }
-      
+
       if ($action == 'Edit') {
         // see if the table name has changed. If so, then check to make sure
         // it doesn't already exists. We don't want to drop a table we didn't mean to
@@ -359,7 +372,7 @@ function tripal_custom_tables_form_submit($form, &$form_state) {
   else {
     drupal_set_message(t("No action performed."));
   }
-  
+
   drupal_goto("admin/tripal/schema/custom_tables");
 }
 
@@ -369,26 +382,26 @@ function tripal_custom_tables_form_submit($form, &$form_state) {
  * @ingroup tripal_custom_tables
  */
 function tripal_custom_tables_delete_form($form, &$form_state, $table_id) {
-  
+
   // get details about this table entry
   $sql = "SELECT * FROM {tripal_custom_tables} WHERE table_id = :table_id";
   $results = db_query($sql, array(':table_id' => $table_id));
   $entry = $results->fetchObject();
-  
+
   // if this is a materialized view then don't allow editing with this function
   if ($entry->mview_id) {
     drupal_set_message("This custom table is a materialized view. Please use the "  . l('Materialized View', 'admin/tripal/schema/mviews') . " interface to delete it.", 'error');
     drupal_goto("admin/tripal/schema/custom_tables");
     return array();
   }
-  
-  
+
+
   $form = array();
   $form['table_id'] = array(
     '#type' => 'value',
     '#value' => $table_id
   );
-  
+
   $form['sure'] = array(
     '#type' => 'markup',
     '#markup' => '<p>Are you sure you want to delete the "' . $entry->table_name . '" custom table?</p>'
@@ -406,14 +419,14 @@ function tripal_custom_tables_delete_form($form, &$form_state, $table_id) {
 
 /**
  * form submit hook for the tripal_custom_tables_delete_form form.
- * 
+ *
  * @param $form
  * @param $form_state
  */
 function tripal_custom_tables_delete_form_submit($form, &$form_state) {
   $action   = $form_state['clicked_button']['#value'];
   $table_id = $form_state['values']['table_id'];
-    
+
   if (strcmp($action, 'Delete') == 0) {
     chado_delete_custom_table($table_id);
   }

+ 15 - 15
tripal_example/README.txt

@@ -1,7 +1,7 @@
-This module is provided as a template for creating a custom Tripal Extension 
+This module is provided as a template for creating a custom Tripal Extension
 Module for Drupal 7 and Tripal 2.x.
 
-Drupal does provide quite a bit of documentation on its website at 
+Drupal does provide quite a bit of documentation on its website at
 http://www.drupal.org but the easiest way to learn to program a Drupal module
 is to purchase the following book:
 
@@ -12,7 +12,7 @@ But this quick link can help get you started:
   https://drupal.org/developing/modules/7
 
 Briefly, to create a Drupal module you must
- 
+
 1) Create a directory to house all of your module's files
 2) Create a .info inside of the directory which provides information about your
    module to Drupal
@@ -44,11 +44,11 @@ If you want to integrate with Drupal Views 3.x:
 
 Include Files
 -------------
-To limit the size of files, some functionality can be placed inside of 
+To limit the size of files, some functionality can be placed inside of
 "include" files. Include files are placed inside of an 'includes' directory.
 [module dir]/includes
 
-If your module creates a node type that uses data housed in Chado, you should 
+If your module creates a node type that uses data housed in Chado, you should
 place all of the Drupal hooks for nodes inside of an include named:
 [module dir]/includes/[module name].chado_node.inc
 
@@ -60,18 +60,18 @@ All other include files should be named in the following way:
 [module dir]/includes/[module name].[function].inc
 
 where [function] is a brief description of the functionality provided by the
-include file.  Please only use underscores inside of the [function] (no dashes
+include file. Please only use underscores inside of the [function] (no dashes
 or periods).
 
 
 Theme Files
 -------------
-Tripal primarily uses template files for displaying content from Chado. This 
+Tripal primarily uses template files for displaying content from Chado. This
 allows anyone to easily change the way data is displayed without needing to
-delve into the module's source code.  A template typically provides data for
+delve into the module's source code. A template typically provides data for
 a single data type (e.g. feature) or association (e.g. properties associated to
-features, or publications associated with featurmaps, etc.).  These template
-files and any JavaScript, CSS or images needed to suppport them are all
+features, or publications associated with featurmaps, etc.). These template
+files and any JavaScript, CSS or images needed to support them are all
 housed inside of a 'theme' directory with the following structure:
 [module dir]/theme
 [module dir]/theme/css       (for CSS files)
@@ -91,18 +91,18 @@ Template files are named in the following way
 [module dir]/theme/templates/[module name]_[function].tpl.php.
 
 Notice that templates have an underscore separating the [module name] from the
-[function].  Typically a period is used (as with include files) but for
-backwards compatibility the undescores are kept.  
+[function]. Typically a period is used (as with include files) but for
+backwards compatibility the underscores are kept.
 
 API Files
 ---------
-If your module will provide a set of functions that can be used as an 
-Application Programming Intervace (API), then those functions should be placed 
+If your module will provide a set of functions that can be used as an
+Application Programming Interface (API), then those functions should be placed
 in files housed in the 'api' directory:
 [module dir]/api
 
 When creating API functions try to organize them into groups of related function
-and separate them into files by function with the following nameing:
+and separate them into files by function with the following naming:
 [module dir]/api/[module name].[function].api.inc
 
 

+ 15 - 13
tripal_example/api/tripal_example.api.inc

@@ -2,7 +2,8 @@
 
 /**
  * @file
- * Provides an application programming interface (API) for working the example module
+ * Provides an application programming interface (API) for working the example
+ * module
  */
 
 /**
@@ -12,22 +13,23 @@
  * Provides an application programming interface (API) for working with features
  * @}
  */
- 
-// EXPLANATION: This file is used for housing any API function that your
-// module creates.  It is suggested you follow the naming style for Tripal 
-// API functions. Below are naming rules for Tripal API functions:
+
+// EXPLANATION: This file is used for housing any API function that your module
+// creates. It is suggested you follow the naming style for Tripal API
+// functions. Below are naming rules for Tripal API functions:
 //
 // 1) Prefix the function with 'chado_' for all insert, updates, delete or get
-//    function on a table in the chado schema.  Tripal should provide all of these 
-//    functions for tables that come with Chado.  But, you can use this prefix 
-//    for API functions on custom tables that your module may add.
+//    function on a table in the chado schema. Tripal should provide all of
+//    these functions for tables that come with Chado. But, you can use this
+//    prefix for API functions on custom tables that your module may add.
 // 2) For all other functions prefix the function with your module name. So
 //    for this example module the prefix would be 'tripal_example_'
 // 3) A 'verb' should follow the function prefix indicating the action that
 //    the function performs. Commonly used verbs are 'get', 'insert', 'update'
-//    'associate', 'execute', etc.  An exception is for functions that
-//    test state rather than perform an action (e.g. does something exist).  
-//    For functions that test state use 'does' instead of a verb 
-//    (e.g. tripal_example_does_pub_exist) 
-// 4) Follow the verb with a short predicate describing what is being acted upon.
+//    'associate', 'execute', etc. An exception is for functions that
+//    test state rather than perform an action (e.g. does something exist).
+//    For functions that test state use 'does' instead of a verb
+//    (e.g. tripal_example_does_pub_exist)
+// 4) Follow the verb with a short predicate describing what is being acted
+//    upon.
 //

+ 13 - 11
tripal_example/includes/tripal_example.admin.inc

@@ -18,10 +18,9 @@ function tripal_example_admin_examples_listing() {
   drupal_set_breadcrumb($breadcrumb);
 
 
-  // EXPLANATION:  Typically for all Tripal modules the home administrative
-  // page for the module contains a search form to help the adminstrator
-  // locate records.  The following example code adds a default View to
-  // the page
+  // EXPLANATION:  Typically for all Tripal modules the home administrative page
+  // for the module contains a search form to help the adminstrator locate
+  // records. The following example code adds a default View to the page
   /*
   // Add the view
   $view = views_embed_view('tripal_example_admin_examples','default');
@@ -55,19 +54,23 @@ function tripal_example_admin() {
     '#markup' => t('There are currently no settings to configure.')
   );
 
-  // If your module is using the Chado Node: Title & Path API to allow custom titles
-  // for your node type then you need to add the configuration form for this functionality.
+  // If your module is using the Chado Node: Title & Path API to allow custom
+  // titles for your node type then you need to add the configuration form for
+  // this functionality.
   $details = array(
-    'module' => 'tripal_example',       // the name of the MODULE implementing the content type
+      // the name of the MODULE implementing the content type
+    'module' => 'tripal_example',
       // An array of options to use under "Page Titles"
-      // the key should be the token and the value should be the human-readable option
+      // the key should be the token and the value should be the human-readable
+      // option
     'options' => array(
       '[example.name]' => 'Germplasm Name Only',
       '[example.uniquename]' => 'Germplasm Unique Name Only',
         // there should always be one options matching the unique constraint.
-        // If you have a more human-readable constraint, then that is preferrable.
+        // If you have a more human-readable constraint, then that is
+        // preferable.
         // See the tripal feature module for a good example of this.
-      '[example.example_id]' => 'Unique Contraint: The Chado ID for Examples'
+      '[example.example_id]' => 'Unique Constraint: The Chado ID for Examples'
     ),
     // the token indicating the unique constraint in the options array
     'unique_option' => '[example.example_id]'
@@ -88,4 +91,3 @@ function tripal_example_admin() {
 function tripal_example_admin_validate($form, &$form_state) {
 
 }
-

+ 276 - 241
tripal_example/includes/tripal_example.chado_node.inc

@@ -9,7 +9,7 @@
 /**
  *  Implementation of hook_node_info().
  *
- *  This hook provides information to drupal about any node types that are being
+ *  This hook provides information to Drupal about any node types that are being
  *  created by this module. If your module does not create any node types then
  *  this function is not required.
  *
@@ -30,22 +30,26 @@ function tripal_example_node_info() {
     'description' => t('A record from the fake chado example table'),
     'has_title'   => TRUE,
     'locked'      => TRUE,
-    // EXPLANATION: This section of the node type array specifies how Tripal will sync the node
-    // types with data in Chado. When Drupal creates a node it has no way of
-    // coordinating which node belongs to which record in Chado. Therefore,
-    // Tripal maintains tables in the Drupal schema that maps Drupal nodes
-    // to recrords in Chado.  Syncing is the process of creating Drupal nodes
-    // and linking them to the appropriate record.
+    // EXPLANATION: This section of the node type array specifies how Tripal
+    // will sync the node types with data in Chado. When Drupal creates a node
+    // it has no way of coordinating which node belongs to which record in
+    // Chado. Therefore, Tripal maintains tables in the Drupal schema that maps
+    // Drupal nodes to records in Chado. Syncing is the process of creating
+    // Drupal nodes and linking them to the appropriate record.
     'chado_node_api' => array(
-      'base_table' => 'example',       // the base table name (e.g. example, example, contact)
-      'hook_prefix' => 'chado_example',// the node type hook prefix
+      // the base table name (e.g. example, example, contact)
+      'base_table' => 'example',
+      // the node type hook prefix
+      'hook_prefix' => 'chado_example',
       'record_type_title' => array(
-        'singular' => t('Example'),    // how to refer to the record
-        'plural' => t('Examples')      // how to refer to the record in plurals
+        // how to refer to the record
+        'singular' => t('Example'),
+        // how to refer to the record in plurals
+        'plural' => t('Examples')
       ),
       'sync_filters' => array(
-        'type_id' => TRUE,             // if the record has a type_id set to TRUE
-        'organism_id' => TRUE          // if the record has an organism_id set to TRUE
+        'type_id' => TRUE,     // if the record has a type_id set to TRUE
+        'organism_id' => TRUE  // if the record has an organism_id set to TRUE
       ),
     )
   );
@@ -54,28 +58,26 @@ function tripal_example_node_info() {
 }
 
 /**
- * Implement hook_access().  This hook provides instructions to
- * drupal for which users can access the custom content types
- * created in the function above.  The available permissions
- * are set in the chado_example_permissions() hook in the
- * tripal_example.module file.  This hook is not needed
- * if no node types were defined in the hook_node_info() hook.
+ * Implement hook_access(). This hook provides instructions to Drupal for which
+ * users can access the custom content types created in the function above. The
+ * available permissions are set in the chado_example_permissions() hook in the
+ * tripal_example.module file. This hook is not needed if no node types were
+ * defined in the hook_node_info() hook.
  *
  * @return
- * This function should return null if it does not specificially
- * deny access. This allows for other mechanisms to to deny
- * or reject access. If the return value is TRUE then access
- * is granted regardless of any other rules that might be implemented
- * by other modules.
+ * This function should return null if it does not specifically deny access.
+ * This allows for other mechanisms to to deny or reject access. If the return
+ * value is TRUE then access is granted regardless of any other rules that might
+ * be implemented by other modules.
  */
 function chado_example_node_access($node, $op, $account) {
   $node_type = $node;
   if (is_object($node)) {
     $node_type = $node->type;
   }
-  // EXPLANATION:  in the tripal_example_permissions() function we
-  // created the permission types that are used here to check for
-  // access permissions to the 'chado_exmaple' node type.
+  // EXPLANATION:  in the tripal_example_permissions() function we created the
+  // permission types that are used here to check for access permissions to the
+  // 'chado_exmaple' node type.
   if($node_type == 'chado_example') {
     if ($op == 'create') {
       if (!user_access('create chado_example content', $account)) {
@@ -111,37 +113,38 @@ function chado_example_node_access($node, $op, $account) {
  */
 function chado_example_form($node, &$form_state) {
 
-  // EXPLANATION: This function should construct a form array that is used
-  // by Drupal to contruct a form for inserting or editing our new node type.
+  // EXPLANATION: This function should construct a form array that is used by
+  // Drupal to construct a form for inserting or editing our new node type.
   // See this page for information about the Form API:
   // https://api.drupal.org/api/drupal/includes!form.inc/group/form_api/7
   //
   // The code below is laid out in the following order
   // 1) Set default values
   // 2) Add form elements used by this node type
-  // 3) Use the Tripal API to add form elemetns for properties,
+  // 3) Use the Tripal API to add form elements for properties,
   //    dbxref's and relationships
   //
-  // For the example code below we assume that the fake 'example' table
-  // only has a uniquename, organism_id, type_id and example_id.
+  // For the example code below we assume that the fake 'example' table only has
+  // a uniquename, organism_id, type_id and example_id.
 
   $form = array();
 
   // Default values can come in the following ways:
   //
-  // 1) as elements of the $node object.  This occurs when editing an existing example
-  // 2) in the $form_state['values'] array which occurs on a failed validation or
-  //    ajax callbacks from non submit form elements
-  // 3) in the $form_state['input'[ array which occurs on ajax callbacks from submit
-  //    form elements and the form is being rebuilt
+  // 1) as elements of the $node object. This occurs when editing an existing
+  //    example
+  // 2) in the $form_state['values'] array which occurs on a failed validation
+  //    or ajax callbacks from non submit form elements
+  // 3) in the $form_state['input'[ array which occurs on ajax callbacks from
+  //    submit form elements and the form is being rebuilt
   //
   // set form field defaults
 
 
   // SET FORM DEFAULTS
   //---------------------------------------------
-  $example      = null;   // holds the example object record
-  $example_id   = null;   // when editing an example record we'll have an example_id
+  $example      = null; // holds the example object record
+  $example_id   = null; // when editing an example record we'll have an example_id
 
   // initialize the defaults for the form fields
   $uniquename   = '';
@@ -164,8 +167,8 @@ function chado_example_form($node, &$form_state) {
       '#value' => $example_id,
     );
   }
-  // if we are re constructing the form from a failed validation or ajax callback
-  // then use the $form_state['values'] values
+  // if we are re constructing the form from a failed validation or ajax
+  // callback then use the $form_state['values'] values
   if (array_key_exists('values', $form_state)) {
      $uniquename   = $form_state['values']['uniquename'];
      $example_type = $form_state['values']['example_type'];
@@ -188,12 +191,12 @@ function chado_example_form($node, &$form_state) {
     '#title' => t('Unique Name'),
     '#required' => TRUE,
     '#default_value' => $uniquename,
-    '#description' => t('Enter a unique name for this example.  This name must be unique.'),
+    '#description' => t('Enter a unique name for this example. This name must be unique.'),
     '#maxlength' => 255
   );
 
-  // for the type_id we want to use the default vocabulary so that this
-  // field can have autocomplete functionality
+  // for the type_id we want to use the default vocabulary so that this field
+  // can have auto-complete functionality
   $type_cv = tripal_get_default_cv('example', 'type_id');
   $cv_id = $type_cv->cv_id;
   $form['example_type'] = array(
@@ -226,43 +229,58 @@ function chado_example_form($node, &$form_state) {
 
   // PROPERTIES FORM
   //---------------------------------------------
-  // If there is a exampleprop table and you want to allow users to add/remove entries
-  // from it through your node form then add this section to your own node form
+  // If there is a exampleprop table and you want to allow users to add/remove
+  // entries from it through your node form then add this section to your own
+  // node form
   $prop_cv = tripal_get_default_cv('exampleprop', 'type_id');
   $cv_id = $prop_cv ? $prop_cv->cv_id : NULL;
   $details = array(
-    'property_table' => 'exampleprop',      // the name of the prop table
-    'chado_id' => $example_id,              // the value of example_id for this record
-    'cv_id' => $cv_id                       // the cv.cv_id of the cv governing exampleprop.type_id
+    // the name of the prop table
+    'property_table' => 'exampleprop',
+    // the value of example_id for this record
+    'chado_id' => $example_id,
+    // the cv.cv_id of the cv governing exampleprop.type_id
+    'cv_id' => $cv_id
   );
   // Adds the form elements to your current form
   chado_add_node_form_properties($form, $form_state, $details);
 
   // ADDITIONAL DBXREFS FORM
   //---------------------------------------------
-  // If there is a example_dbxref table and you want to allow users to add/remove entries
-  // from it through your node form then add this section to your own node form
+  // If there is a example_dbxref table and you want to allow users to
+  // add/remove entries from it through your node form then add this section to
+  // your own node form
   $details = array(
-    'linking_table' => 'example_dbxref',  // the name of the _dbxref table
-    'base_foreign_key' => 'example_id',   // the name of the key in your base chado table
-    'base_key_value' => $example_id       // the value of example_id for this record
+    // the name of the _dbxref table
+    'linking_table' => 'example_dbxref',
+    // the name of the key in your base chado table
+    'base_foreign_key' => 'example_id',
+    // the value of example_id for this record
+    'base_key_value' => $example_id
   );
   // Adds the form elements to your current form
   chado_add_node_form_dbxrefs($form, $form_state, $details);
 
   // RELATIONSHIPS FORM
   //---------------------------------------------
-  // If there is a example_relationship table and you want to allow users to add/remove entries
-  // from it through your node form then add this section to your own node form
+  // If there is a example_relationship table and you want to allow users to
+  // add/remove entries from it through your node form then add this section to
+  // your own node form
   $rels_cv = tripal_get_default_cv('example_relationship', 'type_id');
   $cv_id = $rels_cv ? $rels_cv->cv_id : NULL;
   $details = array(
-    'relationship_table' => 'example_relationship', // the name of the _relationship table
-    'base_table' => 'example',                      // the name of your chado base table
-    'base_foreign_key' => 'example_id',             // the name of the key in your base chado table
-    'base_key_value' => $example_id,                // the value of example_id for this record
-    'nodetype' => 'example',                        // the human-readable name of your node type
-    'cv_id' => $cv_id                               // the cv.cv_id of the cv governing example_relationship.type_id
+    // the name of the _relationship table
+    'relationship_table' => 'example_relationship',
+    // the name of your chado base table
+    'base_table' => 'example',
+    // the name of the key in your base chado table
+    'base_foreign_key' => 'example_id',
+    // the value of example_id for this record
+    'base_key_value' => $example_id,
+    // the human-readable name of your node type
+    'nodetype' => 'example',
+    // the cv.cv_id of the cv governing example_relationship.type_id
+    'cv_id' => $cv_id
   );
   // Adds the form elements to your current form
   chado_add_node_form_relationships($form, $form_state, $details);
@@ -274,14 +292,14 @@ function chado_example_form($node, &$form_state) {
 /**
  * Implementation of hook_validate
  *
- * This function validates a form prior to insert or update. If an error
- * is detected, it sets the error using form_set_error() which takes the
- * user back to the form to make corrections.
+ * This function validates a form prior to insert or update. If an error is
+ * detected, it sets the error using form_set_error() which takes the user back
+ * to the form to make corrections.
  *
  * This validation is being used for three activities:
- *   CASE A: Update a node that exists in both drupal and chado
- *   CASE B: Synchronizing a node from chado to drupal
- *   CASE C: Inserting a new node that exists in niether drupal nor chado
+ *   CASE A: Update a node that exists in both Drupal and Chado
+ *   CASE B: Synchronizing a node from Chado to Drupal
+ *   CASE C: Inserting a new node that exists in neither Drupal nor Chado
  *
  * @param $node
  *
@@ -294,19 +312,19 @@ function chado_example_validate($node, $form, &$form_state) {
   // Since this validate can be called on AJAX and Deletion of the node
   // we need to make this check to ensure queries are not executed
   // without the proper values.
-  if($node->op != 'Save') {
+  if(property_exists($node, "op") and $node->op != 'Save') {
     return;
   }
 
-  // we are syncing if we do not have a node ID but we do have a example_id. We don't
-  // need to validate during syncing so just skip it.
-  if (is_null($node->nid) and property_exists($node, 'example_id') and $node->example_id != 0) {
+  // we are syncing if we do not have a node ID but we do have a example_id. We
+  // don't need to validate during syncing so just skip it.
+  if (!property_exists($node, 'nid') and property_exists($node, 'example_id') and $node->example_id != 0) {
     return;
   }
 
   // be sure to always trim text fields
-  $node->uniquename   = trim($node->uniquename);
-  $node->description  = trim($node->description);
+  $node->uniquename   = property_exists($node, 'uniquename') ? trim($node->uniquename) : '';
+  $node->description  = property_exists($node, 'description') ? trim($node->description) : '';
 
   // Validating for an update. If the 'nid' property is present in the node then
   // this is an update and validation can be different for updates
@@ -322,8 +340,8 @@ function chado_example_validate($node, $form, &$form_state) {
       form_set_error('feature_type', t("The feature type is not a valid name from the Sequence Ontology."));
     }
 
-    // TODO: also we should check that the unique constraint is not invalidated by
-    // changing either the type_id, organism_id or uniquename.
+    // TODO: also we should check that the unique constraint is not invalidated
+    // by changing either the type_id, organism_id or uniquename.
   }
   // Validating for an insert
   else {
@@ -342,14 +360,14 @@ function chado_example_validate($node, $form, &$form_state) {
 }
 
 /**
- *  Implementation of hook_insert(). This function is called after the
- *  node is inserted into the database. We need it so that we can insert
- *  appropriate fields as provided by the user into the database. And so that
- *  we can link the new Drupal node to the data in Chado via the chado_example
- *  linking table. We can get to this function also during "syncing".
- *  With syncing, however, the data already exists in Chado and we do not want
- *  to try to re-add it. But we do need to add an entry to the chado_example table
- *  to link the Drupal node with the data in the 'example' table of Chado.
+ *  Implementation of hook_insert(). This function is called after the node is
+ * inserted into the database. We need it so that we can insert appropriate
+ * fields as provided by the user into the database. And so that we can link the
+ * new Drupal node to the data in Chado via the chado_example linking table. We
+ * can get to this function also during "syncing".
+ * With syncing, however, the data already exists in Chado and we do not want
+ * to try to re-add it. But we do need to add an entry to the chado_example
+ * table to link the Drupal node with the data in the 'example' table of Chado.
  *
  *  This function is not required if the hook_node_info() does not define
  *  any custom node types.
@@ -357,22 +375,25 @@ function chado_example_validate($node, $form, &$form_state) {
  * @ingroup tripal_example
  */
 function chado_example_insert($node) {
-  // be sure to always trim text fields
-  $node->uniquename   = trim($node->uniquename);
-  $node->description  = trim($node->description);
 
-  // get the example type record
-  $type_cv = tripal_get_default_cv('example', 'type_id');
-  $type = tripal_get_cvterm(array(
-    'name' => $node->example_type,
-    'cv_id' => $type_cv->cv_id,
-  ));
+  $example_id = '';
 
   // if there is an example_id in the $node object then this must be a sync so
-  // we can skip adding the example as it is already there, although
-  // we do need to proceed with the rest of the insert
+  // we can skip adding the example as it is already there, although we do need
+  // to proceed with insertion into the chado/drupal linking table.
   if (!property_exists($node, 'example_id')) {
 
+    // be sure to always trim text fields
+    $node->uniquename   = trim($node->uniquename);
+    $node->description  = trim($node->description);
+
+    // get the example type record
+    $type_cv = tripal_get_default_cv('example', 'type_id');
+    $type = tripal_get_cvterm(array(
+        'name' => $node->example_type,
+        'cv_id' => $type_cv->cv_id,
+    ));
+
     // perform the insert using the chado_insert_record function();
     $values = array(
       'uniquename' => $node->uniquename,
@@ -391,39 +412,51 @@ function chado_example_insert($node) {
     // get the example_id for linking Drupal node with Chado data
     $example_id = $example['example_id'];
 
-    // Only add to other chado tables if the base record was inserted properly
+    // Only add to other Chado tables if the base record was inserted properly
     if ($example_id > 0) {
 
-      // If you implemented the properties form in chado_example_form then you need to
-      // handle inserting these properties into your chado prop table.
+      // If you implemented the properties form in chado_example_form then you
+      // need to handle inserting these properties into your Chado prop table.
       $details = array(
-        'property_table'   => 'exampleprop',   // the name of the prop table
-        'base_table'       => 'example',       // the name of your chado base table
-        'foreignkey_name'  => 'example_id',    // the name of the key in your base table
-        'foreignkey_value' => $example_id      // the value of the example_id key
+        // the name of the prop table
+        'property_table'   => 'exampleprop',
+        // the name of your Chado base table
+        'base_table'       => 'example',
+        // the name of the key in your base table
+        'foreignkey_name'  => 'example_id',
+        // the value of the example_id key
+        'foreignkey_value' => $example_id
       );
       chado_update_node_form_properties($node, $details);
 
-      // If you implemented the dbxrefs form in chado_example_form then you need to
-      // handle inserting these database references into your chado _dbxref table.
+      // If you implemented the dbxrefs form in chado_example_form then you need
+      // to handle inserting these database references into your Chado _dbxref
+      // table.
       $details = array(
-        'linking_table'    => 'example_dbxref', // the name of your _dbxref table
-        'foreignkey_name'  => 'example_id',     // the name of the key in your base table
-        'foreignkey_value' => $example_id       // the value of the example_id key
+        // the name of your _dbxref table
+        'linking_table'    => 'example_dbxref',
+        // the name of the key in your base table
+        'foreignkey_name'  => 'example_id',
+        // the value of the example_id key
+        'foreignkey_value' => $example_id
       );
       chado_update_node_form_dbxrefs($node, $details);
 
-      // If you implemented the relationships form in chado_example_form then you need to
-      // handle inserting these relationships into your chado _relationship table.
+      // If you implemented the relationships form in chado_example_form then
+      // you need to handle inserting these relationships into your Chado
+      // _relationship table.
       $details = array(
-        'relationship_table' => 'example_relationship',  // name of the _relationship table
-        'foreignkey_value' => $example_id                // value of the example_id key
+        // name of the _relationship table
+        'relationship_table' => 'example_relationship',
+        // value of the example_id key
+        'foreignkey_value' => $example_id
       );
       chado_update_node_form_relationships($node, $details);
     }
   }
   else {
-    // the node has an example_id so get it for linking Drupal node with Chado data
+    // the node has an example_id so get it for linking Drupal node with Chado
+    // data
     $example_id = $node->example_id;
   }
 
@@ -440,12 +473,11 @@ function chado_example_insert($node) {
 }
 
 /**
- * Implementation of hook_update().  This function runs after the
- * node has been inserted into the Drupal schema and allows us to
- * update the record in Chado.
+ * Implementation of hook_update(). This function runs after the node has been
+ * inserted into the Drupal schema and allows us to update the record in Chado.
  *
- *  This function is not required if the hook_node_info() does not define
- *  any custom node types.
+ * This function is not required if the hook_node_info() does not define any
+ * custom node types.
  *
  * @ingroup tripal_example
  */
@@ -470,41 +502,44 @@ function chado_example_update($node) {
       array('%values' => print_r($values, TRUE)));
   }
 
-  // If you implemented the properties form in chado_example_form then you need to
-  // handle updating these properties into your chado prop table.
+  // If you implemented the properties form in chado_example_form then you need
+  // to handle updating these properties into your Chado prop table.
   $details = array(
-    'property_table' => 'exampleprop',   // the name of the prop table
-    'base_table' => 'example',           // the name of your chado base table
-    'foreignkey_name' => 'example_id',   // the name of the key in your base table
-    'foreignkey_value' => $example_id    // the value of the example_id key
+    'property_table' => 'exampleprop', // the name of the prop table
+    'base_table' => 'example',         // the name of your Chado base table
+    'foreignkey_name' => 'example_id', // the name of the key in your base table
+    'foreignkey_value' => $example_id  // the value of the example_id key
   );
   chado_update_node_form_properties($node, $details);
 
   // If you implemented the dbxrefs form in chado_example_form then you need to
-  // handle updating these database references into your chado _dbxref table.
+  // handle updating these database references into your Chado _dbxref table.
   $details = array(
-    'linking_table' => 'example_dbxref',   // the name of your _dbxref table
-    'foreignkey_name' => 'example_id',     // the name of the key in your base table
-    'foreignkey_value' => $example_id      // the value of the example_id key
+    'linking_table' => 'example_dbxref', // the name of your _dbxref table
+    'foreignkey_name' => 'example_id',   // the name of the key in your base table
+    'foreignkey_value' => $example_id    // the value of the example_id key
   );
   chado_update_node_form_dbxrefs($node, $details);
 
-  // If you implemented the relationships form in chado_example_form then you need to
-  // handle updating these relationships into your chado _relationship table.
+  // If you implemented the relationships form in chado_example_form then you
+  // need to handle updating these relationships into your Chado _relationship
+  // table.
   $details = array(
-    'relationship_table' => 'example_relationship',  // name of the _relationship table
-    'foreignkey_value' => $example_id                // value of the example_id key
+    // name of the _relationship table
+    'relationship_table' => 'example_relationship',
+    // value of the example_id key
+    'foreignkey_value' => $example_id
   );
   chado_update_node_form_relationships($node, $details);
 
 }
 /**
- * Implementation of hook_delete().  This function runs after the
- * node has been deleted from the Drupal schema and allows us to
- * delete the corresponding recrod in Chado.
+ * Implementation of hook_delete(). This function runs after the node has been
+ * deleted from the Drupal schema and allows us to delete the corresponding
+ * record in Chado.
  *
- * This function is not required if the hook_node_info() does not define
- * any custom node types.
+ * This function is not required if the hook_node_info() does not define any
+ * custom node types.
  *
  * @ingroup tripal_example
  */
@@ -513,18 +548,18 @@ function chado_example_delete($node) {
   // get the example id from the node
   $example_id  = chado_get_id_from_nid('example', $node->nid);
 
-  // if we don't have a example id for this node then this isn't a node of
-  // type chado_example or the entry in the chado_example table was lost.
+  // if we don't have a example id for this node then this isn't a node of type
+  // chado_example or the entry in the chado_example table was lost.
   if (!$example_id) {
     return;
   }
 
   // remove the entry in the chado_exapmle table linking the deleted
-  // Drupal node with the data in chado
+  // Drupal node with the data in Chado
   $sql_del = "DELETE FROM {chado_example} WHERE nid = :nid AND vid = :vid";
   db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
 
-  // Remove data from example tables of chado database.  This will
+  // Remove data from example tables of Chado database. This will
   // cause a cascade delete and remove all data in referencing tables
   // for this example
   chado_query("DELETE FROM {example} WHERE example_id = :example_id", array(':example_id' => $example_id));
@@ -535,25 +570,25 @@ function chado_example_delete($node) {
 }
 
 /**
- * Implementation of hook_load().  This function is necessary to load
- * into the $node object the fields of the table form Chado. For example
- * for the example table, the chado_example_load() function adds in
- * a example object which contains all of the fields and sub objects
- * for data in tables with foreign key relationships.
+ * Implementation of hook_load(). This function is necessary to load into the
+ * $node object the fields of the table form Chado. For example for the example
+ * table, the chado_example_load() function adds in a example object which
+ * contains all of the fields and sub objects for data in tables with foreign
+ * key relationships.
  *
- * This function is not required if the hook_node_info() does not define
- * any custom node types.
+ * This function is not required if the hook_node_info() does not define any
+ * custom node types.
  *
  * @ingroup tripal_example
  */
 function chado_example_load($nodes) {
 
   // EXPLANATION: when displaying or node or accessing the node in a template
-  // we need the data from Chado.  This fucntion finds the record in Chado that
+  // we need the data from Chado. This function finds the record in Chado that
   // this node belongs to and adds the record.
 
-  // there may be multiple nodes that get passed in so we have to iterate through
-  // them all
+  // there may be multiple nodes that get passed in so we have to iterate
+  // through them all
   foreach ($nodes as $nid => $node) {
     // find the example and add in the details
     $example_id = chado_get_id_from_nid('example', $nid);
@@ -568,20 +603,21 @@ function chado_example_load($nodes) {
     $values = array('example_id' => $example_id);
     $example = chado_generate_var('example', $values);
 
-    // for fields in the table that are of type 'text' you may want to include those
-    // by default, the chado_generate_var does not include text fields as
-    // they may be very large and including a large text field can slow the page load.
+    // for fields in the table that are of type 'text' you may want to include
+    // those by default, the chado_generate_var does not include text fields as
+    // they may be very large and including a large text field can slow the page
+    // load.
     // If you know a text field will never be large and it is important for the
     // other functions that will see the node to have access to a field you can
-    // include it here using the chado_expand_var() function.  In most
-    // cases it is probably best to let the end-user decide if text fields should
-    // be included by using this function in the templates.
+    // include it here using the chado_expand_var() function. In most
+    // cases it is probably best to let the end-user decide if text fields
+    // should be included by using this function in the templates.
     $example = chado_expand_var($example, 'field', 'example.description');
 
 
-    // If your module is using the Chado Node: Title & Path API to allow custom titles
-    // for your node type. Every time you want the title of the node, you need to use the
-    // following API function:
+    // If your module is using the Chado Node: Title & Path API to allow custom
+    // titles for your node type. Every time you want the title of the node, you
+    // need to use the following API function:
     $node->title = chado_get_node_title($node);
 
     // add the new example object to this node.
@@ -598,24 +634,24 @@ function chado_example_load($nodes) {
  */
 function tripal_example_node_presave($node) {
 
-  // EXPLANATION: This node is useful for
-  // making changes to the node prior to it being saved to the database.
+  // EXPLANATION: This node is useful for making changes to the node prior to it
+  // being saved to the database.
   // One useful case for this is to set the title of a node using values
   // supplied by the user.
   //
-  // This function is not required. You probably won't need it if you
-  //  don't define a custom node type in the hook_node_info() function. But
-  // it is node type agnostic, so you can use this function to change the
-  // contents of any node regardless of it's type.
+  // This function is not required. You probably won't need it if you don't
+  // define a custom node type in the hook_node_info() function. But it is node
+  // type agnostic, so you can use this function to change the contents of any
+  // node regardless of it's type.
 
   // set the node title
   switch ($node->type) {
-    // This step is for setting the title for the Drupal node.  This title
-    // is permanent and thus is created to be unique.  Title changes provided
-    // by tokens are generated on the fly dynamically, but the node title
-    // seen in the content listing needs to be set here. Do not call
-    // the chado_get_node_title() function here to set the title as the node
-    // object isn't properly filled out and the function will fail.
+    // This step is for setting the title for the Drupal node. This title is
+    // permanent and thus is created to be unique. Title changes provided by
+    // tokens are generated on the fly dynamically, but the node title seen in
+    // the content listing needs to be set here. Do not call the
+    // chado_get_node_title() function here to set the title as the node object
+    // isn't properly filled out and the function will fail.
     case 'chado_example':
       // for a form submission the 'uniquename' field will be set,
       // for a sync, we must pull from the example object
@@ -639,24 +675,23 @@ function tripal_example_node_presave($node) {
  */
 function tripal_example_node_insert($node) {
 
-  // EXPLANATION: This function is used
-  // after any a node is inserted into the database.  It is different
-  // from the hook_insert() function above in that it is called after
-  // any node is saved, regardlesss of it's type. This function is useful
-  // for making changes to the database after a node is inserted.
-  // An example comes from the tripal_feature module where the URL alias
-  // of a node cannot be set in the hook_insert() function. Therefore
-  // the tripal_feature module uses this function to set the url path
-  // of a newly inserted example node.
+  // EXPLANATION: This function is used after any a node is inserted into the
+  // database. It is different from the hook_insert() function above in that it
+  // is called after any node is saved, regardless of it's type. This function
+  // is useful for making changes to the database after a node is inserted.
+  // An example comes from the tripal_feature module where the URL alias of a
+  // node cannot be set in the hook_insert() function. Therefore the
+  // tripal_feature module uses this function to set the URL path of a newly
+  // inserted example node.
   //
-  // This function is not required. You probably won't need it if you
-  // don't define a custom node type in the hook_node_info() function. But
-  // it is node type agnostic, so you can use this function to do any
-  // activity after insert of any node.
-
-  // the Example code below will set the URL path after inserting.  We do it
-  // here because we do not know the example_id in the presave and cannot do
-  // it in the hook_insert()
+  // This function is not required. You probably won't need it if you don't
+  // define a custom node type in the hook_node_info() function. But it is node
+  // type agnostic, so you can use this function to do any activity after insert
+  // of any node.
+
+  // the Example code below will set the URL path after inserting. We do it here
+  // because we do not know the example_id in the pre-save and cannot do it in
+  // the hook_insert()
   switch ($node->type) {
     case 'chado_example':
 
@@ -668,17 +703,17 @@ function tripal_example_node_insert($node) {
       $example = chado_generate_var('example', $values);
       $node->example = $example;
 
-      // If your module is using the 'Chado Node: Title & Path API' to allow custom titles
-      // for your node type. Every time you want the title of the node, you need to use the
-      // following API function:
+      // If your module is using the 'Chado Node: Title & Path API' to allow
+      // custom titles for your node type. Every time you want the title of the
+      // node, you need to use the following API function:
       $example->title = chado_get_node_title($node);
 
       // set the URL for this example page
-      // see the code in the tripal_feature/includes/tripal_feature.chado_node.inc file
-      // in the function tripal_feature_node_insert for an example of how that
-      // module sets the URL.  It uses a configuration file to allow the user
-      // to dynmically build a URL schema and then uses that schema to generate
-      // a URL string.
+      // see the code in the tripal_feature/includes/tripal_feature.chado_node.inc
+      // file in the function tripal_feature_node_insert for an example of how
+      // that module sets the URL. It uses a configuration file to allow the
+      // user to dynamically build a URL schema and then uses that schema to
+      // generate a URL string.
       break;
   }
 }
@@ -691,35 +726,34 @@ function tripal_example_node_insert($node) {
  */
 function tripal_example_node_update($node) {
 
-  // EXPLANATION: This function is used
-  // after any a node is updated in the database.  It is different
-  // from the hook_update() function above in that it is called after
-  // any node is updated, regardlesss of it's type.
-  // An example comes from the tripal_feature module where the URL alias
-  // of a node cannot be set in the hook_update() function. Therefore
-  // the tripal_feature module uses this function to reset the url path
-  // of an updated feature node.
+  // EXPLANATION: This function is used after any a node is updated in the
+  // database. It is different from the hook_update() function above in that it
+  // is called after any node is updated, regardless of it's type.
+  // An example comes from the tripal_feature module where the URL alias of a
+  // node cannot be set in the hook_update() function. Therefore the
+  // tripal_feature module uses this function to reset the URL path of an
+  // updated feature node.
   //
-  // This function is not required. You probably won't need it if you
-  // don't define a custom node type in the hook_node_info() function. But
-  // it is node type agnostic, so you can use this function to do any
-  // activity after insert of a node.
+  // This function is not required. You probably won't need it if you don't
+  // define a custom node type in the hook_node_info() function. But it is node
+  // type agnostic, so you can use this function to do any activity after insert
+  // of a node.
 
   // add items to other nodes, build index and search results
   switch ($node->type) {
     case 'chado_example':
 
-      // If your module is using the Chado Node: Title & Path API to allow custom titles
-      // for your node type. Every time you want the title of the node, you need to use the
-      // following API function:
+      // If your module is using the Chado Node: Title & Path API to allow
+      // custom titles for your node type. Every time you want the title of the
+      // node, you need to use the following API function:
       $example->title = chado_get_node_title($node);
 
       // set the URL for this example page
-      // see the code in the tripal_feature/includes/tripal_feature.chado_node.inc file
-      // in the function tripal_feature_node_insert for an example of how that
-      // module sets the URL.  It uses a configuration file to allow the user
-      // to dynmically build a URL schema and then uses that schema to generate
-      // a URL string.
+      // see the code in the tripal_feature/includes/tripal_feature.chado_node.inc
+      // file in the function tripal_feature_node_insert for an example of how
+      // that module sets the URL. It uses a configuration file to allow the
+      // user to dynamically build a URL schema and then uses that schema to
+      // generate a URL string.
       break;
   }
 }
@@ -730,11 +764,11 @@ function tripal_example_node_update($node) {
  */
 function tripal_example_node_view($node, $view_mode, $langcode) {
 
-  // EXPLANATION: This function defines the content "blocks" that appear
-  // when thhe node is displayed. It is node type agnostic so we can add
-  // content to any node type.  So, we use this function to add the content
-  // from all of our theme templates onto our new node type. We will also
-  // use this function to add content to other node types.
+  // EXPLANATION: This function defines the content "blocks" that appear when
+  // the node is displayed. It is node type agnostic so we can add content to
+  // any node type. So, we use this function to add the content from all of our
+  // theme templates onto our new node type. We will also use this function to
+  // add content to other node types.
 
   switch ($node->type) {
     case 'chado_example':
@@ -742,24 +776,25 @@ function tripal_example_node_view($node, $view_mode, $langcode) {
       // supports full page view and teaser view.
       if ($view_mode == 'full') {
 
-        // If you want to use the default Tripal node template then you need to tell
-        // tripal to generate the Table of Contents. This is done by setting the following
-        // to TRUE. If your content type follows the chado_<base table> convention
-        // then this is the default. In this case if you don't want to use the default
-        // template then you need to set the following to FALSE.
+        // If you want to use the default Tripal node template then you need to
+        // tell Tripal to generate the Table of Contents. This is done by
+        // setting the following to TRUE. If your content type follows the
+        // chado_<base table> convention then this is the default. In this case
+        // if you don't want to use the default template then you need to set
+        // the following to FALSE.
         $node->content['#tripal_generic_node_template'] = TRUE;
 
-        // There is always a base template.  This is the template that
-        // is first shown when the example node type is first displayed.
-        // if you are using the default Tripal node template, then you should
+        // There is always a base template. This is the template that is first
+        // shown when the example node type is first displayed.
+        // If you are using the default Tripal node template, then you should
         // also set two additional items in each array:  tripal_toc_id and
-        // tripal_toc_title.  The tripal_tock_id should be a single unqiue
+        // tripal_toc_title. The tripal_tock_id should be a single unique
         // world that is used to reference the template. This ID is used for
-        // constructing URLs for the content.  The tripal_toc_title contains
+        // constructing URLs for the content. The tripal_toc_title contains
         // the title that should appear in the table of contents for this
-        // content.  You should only set the '#weight' element for the
-        // base template (or Overview) to ensure that it appears at the top of
-        // the list. Otherwise items are sorted alphabetically.
+        // content. You should only set the '#weight' element for the base
+        // template (or Overview) to ensure that it appears at the top of the
+        // list. Otherwise items are sorted alphabetically.
         $node->content['tripal_example_base'] = array(
           '#theme' => 'tripal_example_base',
           '#node' => $node,
@@ -788,11 +823,11 @@ function tripal_example_node_view($node, $view_mode, $langcode) {
           '#tripal_toc_title' => 'Relationships',
         );
 
-        // Note: if you create a template that you do not want a user to
-        // know where it is (discourage editing of it), you can add the following
-        // key:  '#tripal_template_show' => FALSE. If this key/value is set
-        // the the administrator message that Tripal provides indicating
-        // where the template is housed will not be shown.
+        // Note: if you create a template that you do not want a user to know
+        // where it is (discourage editing of it), you can add the following
+        // key:  '#tripal_template_show' => FALSE. If this key/value is set the
+        // administrator message that Tripal provides indicating where the
+        // template is housed will not be shown.
       }
       // set the content for the teaser view
       if ($view_mode == 'teaser') {
@@ -803,8 +838,8 @@ function tripal_example_node_view($node, $view_mode, $langcode) {
         );
       }
       break;
-    // you can add custom content to any node type by adding
-    // content to the node in the same way as above.
+    // you can add custom content to any node type by adding content to the node
+    // in the same way as above.
     case 'chado_organism':
       if ($view_mode == 'full') {
         $node->content['tripal_organism_examples'] = array(

+ 12 - 12
tripal_example/theme/templates/tripal_example_base.tpl.php

@@ -2,18 +2,18 @@
 $example  = $variables['node']->example;  ?>
 
 <div class="tripal_example-data-block-desc tripal-data-block-desc"></div> <?php
- 
-// the $headers array is an array of fields to use as the colum headers. 
-// additional documentation can be found here 
+
+// the $headers array is an array of fields to use as the column headers.
+// additional documentation can be found here
 // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
 // This table for the analysis has a vertical header (down the first column)
 // so we do not provide headers here, but specify them in the $rows array below.
 $headers = array();
 
 // the $rows array contains an array of rows where each row is an array
-// of values for each column of the table in that row.  Additional documentation
+// of values for each column of the table in that row. Additional documentation
 // can be found here:
-// https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7 
+// https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
 $rows = array();
 
 // Unique Name row
@@ -36,7 +36,7 @@ $rows[] = array(
 $organism = $example->organism_id->genus ." " . $example->organism_id->species ." (" . $example->organism_id->common_name .")";
 if (property_exists($example->organism_id, 'nid')) {
   $organism = l("<i>" . $example->organism_id->genus . " " . $example->organism_id->species . "</i> (" . $example->organism_id->common_name .")", "node/".$example->organism_id->nid, array('html' => TRUE));
-} 
+}
 $rows[] = array(
   array(
     'data' => 'Organism',
@@ -46,7 +46,7 @@ $rows[] = array(
 );
 
 // allow site admins to see the example ID
-if (user_access('view ids')) { 
+if (user_access('view ids')) {
   // Feature ID
   $rows[] = array(
     array(
@@ -62,9 +62,9 @@ if (user_access('view ids')) {
 }
 
 
-// the $table array contains the headers and rows array as well as other
-// options for controlling the display of the table.  Additional
-// documentation can be found here:
+// the $table array contains the headers and rows array as well as other options
+// for controlling the display of the table. Additional documentation can be
+// found here:
 // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
 $table = array(
   'header' => $headers,
@@ -79,7 +79,7 @@ $table = array(
   'empty' => '',
 );
 
-// once we have our table array structure defined, we call Drupal's theme_table()
-// function to generate the table.
+// once we have our table array structure defined, we call Drupal's
+// theme_table() function to generate the table.
 print theme_table($table); ?>
 <div style="text-align: justify"><?php print $example->description ?></div>

+ 16 - 15
tripal_example/theme/templates/tripal_example_properties.tpl.php

@@ -11,24 +11,25 @@ $exampleprops = $example->exampleprop;
 $properties = array();
 
 if (count($properties)) { ?>
-  <div class="tripal_example-data-block-desc tripal-data-block-desc">Additional details for this example include:</div> <?php 
+  <div class="tripal_example-data-block-desc tripal-data-block-desc">Additional details for this example include:</div> <?php
 
-  // the $headers array is an array of fields to use as the colum headers.
+  // the $headers array is an array of fields to use as the column headers.
   // additional documentation can be found here
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $headers = array('Property Name', 'Value');
-  
+
   // the $rows array contains an array of rows where each row is an array
-  // of values for each column of the table in that row.  Additional documentation
-  // can be found here:
+  // of values for each column of the table in that row. Additional
+  // documentation can be found here:
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $rows = array();
-  
+
   $keywords = array();
   foreach ($properties as $property) {
-    // each keyword is stored as a seperate properties. We want to show them
-    // only in a single field not as a bunc of individual properties, so when we see one, 
-    // save it in an array for later and down't add it yet to the table yet.
+    // each keyword is stored as a separate properties. We want to show them
+    // only in a single field not as a bunch of individual properties, so when
+    // we see one, save it in an array for later and don't add it yet to the
+    // table yet.
     if ($property->type_id->name == 'Keywords') {
       $keywords[] = $property->value;
       continue;
@@ -44,11 +45,11 @@ if (count($properties)) { ?>
       'Keywords',
       implode(', ', $keywords),
     );
-  } 
+  }
 
   // the $table array contains the headers and rows array as well as other
-  // options for controlling the display of the table.  Additional
-  // documentation can be found here:
+  // options for controlling the display of the table. Additional documentation
+  // can be found here:
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $table = array(
     'header' => $headers,
@@ -62,8 +63,8 @@ if (count($properties)) { ?>
     'colgroups' => array(),
     'empty' => '',
   );
-  
-  // once we have our table array structure defined, we call Drupal's theme_table()
-  // function to generate the table.
+
+  // once we have our table array structure defined, we call Drupal's
+  // theme_table() function to generate the table.
   print theme_table($table);
 }

+ 14 - 13
tripal_example/theme/templates/tripal_example_references.tpl.php

@@ -1,36 +1,37 @@
 <?php
 $example = $variables['node']->example;
 
-// expand the example object to include the records from the example_dbxref table
+// expand the example object to include the records from the example_dbxref
+// table
 $options = array('return_array' => 1);
 $example = chado_expand_var($example, 'table', 'example_dbxref', $options);
 $example_dbxrefs = $example->example_dbxref;
 
 $references = array();
 if (count($example_dbxrefs) > 0 ) {
-  foreach ($example_dbxrefs as $example_dbxref) {    
+  foreach ($example_dbxrefs as $example_dbxref) {
     $references[] = $example_dbxref->dbxref_id;
   }
 }
 
 if(count($references) > 0){ ?>
-  <div class="tripal_example-data-block-desc tripal-data-block-desc">This example is also available in the following databases:</div><?php 
-  
+  <div class="tripal_example-data-block-desc tripal-data-block-desc">This example is also available in the following databases:</div><?php
+
   // the $headers array is an array of fields to use as the colum headers.
   // additional documentation can be found here
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $headers = array('Database', 'Accession');
-  
+
   // the $rows array contains an array of rows where each row is an array
-  // of values for each column of the table in that row.  Additional documentation
-  // can be found here:
+  // of values for each column of the table in that row. Additional
+  // documentation can be found here:
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $rows = array();
-  
+
   foreach ($references as $dbxref){
     $database = $dbxref->db_id->name . ': ' . $dbxref->db_id->description;
     if ($dbxref->db_id->url) {
-      $database = l($dbxref->db_id->name, $dbxref->db_id->url, array('attributes' => array('target' => '_blank'))) . ': ' . $dbxref->db_id->description; 
+      $database = l($dbxref->db_id->name, $dbxref->db_id->url, array('attributes' => array('target' => '_blank'))) . ': ' . $dbxref->db_id->description;
     }
     $accession = $dbxref->db_id->name . ':' . $dbxref->accession;
     if ($dbxref->db_id->urlprefix) {
@@ -39,15 +40,15 @@ if(count($references) > 0){ ?>
     if (property_exists($dbxref, 'is_primary')) {
       $accession .= " <i>(primary cross-reference)</i>";
     }
-    
+
     $rows[] = array(
       $database,
       $accession
     );
   }
   // the $table array contains the headers and rows array as well as other
-  // options for controlling the display of the table.  Additional
-  // documentation can be found here:
+  // options for controlling the display of the table. Additional documentation
+  // can be found here:
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $table = array(
     'header' => $headers,
@@ -61,7 +62,7 @@ if(count($references) > 0){ ?>
     'colgroups' => array(),
     'empty' => '',
   );
-  
+
   // once we have our table array structure defined, we call Drupal's theme_table()
   // function to generate the table.
   print theme_table($table);

+ 43 - 42
tripal_example/theme/templates/tripal_example_relationships.tpl.php

@@ -1,20 +1,21 @@
 <?php
 /* Typically in a Tripal template, the data needed is retrieved using a call to
- * chado_expand_var function.  For example, to retrieve all 
- * of the example relationships for this node, the following function call would be made:
- * 
+ * chado_expand_var function. For example, to retrieve all of the example
+ * relationships for this node, the following function call would be made:
+ *
  *   $example = chado_expand_var($example,'table','example_relationship');
- * 
- * However, this function call can be extremely slow when there are numerous relationships.
- * This is because the chado_expand_var function is recursive and expands 
- * all data following the foreign key relationships tree.  Therefore, to speed retrieval
- * of data, a special variable is provided to this template:
- * 
+ *
+ * However, this function call can be extremely slow when there are numerous
+ * relationships. This is because the chado_expand_var function is recursive and
+ * expands all data following the foreign key relationships tree. Therefore, to
+ * speed retrieval of data, a special variable is provided to this template:
+ *
  *   $example->all_relationships;
- *   
- * This variable is an array with two sub arrays with the keys 'object' and 'subject'.  The array with
- * key 'object' contains relationships where the example is the object, and the array with
- * the key 'subject' contains relationships where the example is the subject
+ *
+ * This variable is an array with two sub arrays with the keys 'object' and
+ * 'subject'. The array with key 'object' contains relationships where the
+ * example is the object, and the array with the key 'subject' contains
+ * relationships where the example is the subject.
  */
 $example = $variables['node']->example;
 
@@ -24,30 +25,30 @@ $subject_rels = $all_relationships['subject'];
 
 if (count($object_rels) > 0 or count($subject_rels) > 0) { ?>
   <div class="tripal_example-data-block-desc tripal-data-block-desc"></div> <?php
-  
-  // first add in the subject relationships.  
+
+  // first add in the subject relationships.
   foreach ($subject_rels as $rel_type => $rels){
     foreach ($rels as $obj_type => $objects){ ?>
       <p>This <?php print $example->type_id->name;?> is <?php print $rel_type ?> the following <b><?php print $obj_type ?></b> example(s): <?php
-       
+
       // the $headers array is an array of fields to use as the colum headers.
       // additional documentation can be found here
       // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
       $headers = array('Publication');
-      
+
       // the $rows array contains an array of rows where each row is an array
-      // of values for each column of the table in that row.  Additional documentation
-      // can be found here:
+      // of values for each column of the table in that row. Additional
+      // documentation can be found here:
       // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
       $rows = array();
-      
+
       foreach ($objects as $object){
         // link the example to it's node
         $title = $object->record->object_id->title;
         if (property_exists($object->record, 'nid')) {
           $title = l($title, "node/" . $object->record->nid, array('attributes' => array('target' => "_blank")));
         }
-        
+
         // get the citation
         $values = array(
           'example_id' => $object->record->object_id->example_id,
@@ -57,13 +58,13 @@ if (count($object_rels) > 0 or count($subject_rels) > 0) { ?>
         );
         $citation = chado_generate_var('exampleprop', $values);
         $citation = chado_expand_var($citation, 'field', 'exampleprop.value');
-        
+
         $rows[] = array(
           $title . '<br>' . htmlspecialchars($citation->value),
-        ); 
-       } 
+        );
+       }
        // the $table array contains the headers and rows array as well as other
-       // options for controlling the display of the table.  Additional
+       // options for controlling the display of the table. Additional
        // documentation can be found here:
        // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
        $table = array(
@@ -78,37 +79,37 @@ if (count($object_rels) > 0 or count($subject_rels) > 0) { ?>
          'colgroups' => array(),
          'empty' => '',
        );
-       
-       // once we have our table array structure defined, we call Drupal's theme_table()
-       // function to generate the table.
+
+       // once we have our table array structure defined, we call Drupal's
+       // theme_table() function to generate the table.
        print theme_table($table); ?>
        </p>
        <br><?php
      }
   }
-  
-  // second add in the object relationships.  
+
+  // second add in the object relationships.
   foreach ($object_rels as $rel_type => $rels){
     foreach ($rels as $subject_type => $subjects){?>
-      <p>The following <b><?php print $subjects[0]->record->subject_id->type_id->name ?></b> example(s) are <?php print $rel_type ?> this <?php print $example->type_id->name;?>: <?php 
+      <p>The following <b><?php print $subjects[0]->record->subject_id->type_id->name ?></b> example(s) are <?php print $rel_type ?> this <?php print $example->type_id->name;?>: <?php
       // the $headers array is an array of fields to use as the colum headers.
       // additional documentation can be found here
       // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
       $headers = array('Publication');
-      
+
       // the $rows array contains an array of rows where each row is an array
-      // of values for each column of the table in that row.  Additional documentation
-      // can be found here:
+      // of values for each column of the table in that row. Additional
+      // documentation can be found here:
       // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
       $rows = array();
-      
+
       foreach ($subjects as $subject){
         // link the example to it's node
         $title = $subject->record->subject_id->title;
         if (property_exists($subject->record, 'nid')) {
           $title = l($title, "node/" . $subject->record->nid, array('attributes' => array('target' => "_blank")));
         }
-        
+
         // get the citation
         $values = array(
           'example_id' => $subject->record->subject_id->example_id,
@@ -118,13 +119,13 @@ if (count($object_rels) > 0 or count($subject_rels) > 0) { ?>
         );
         $citation = chado_generate_var('exampleprop', $values);
         $citation = chado_expand_var($citation, 'field', 'exampleprop.value');
-        
+
         $rows[] = array(
           $title . '<br>' . htmlspecialchars($citation->value),
         );
-       } 
+       }
        // the $table array contains the headers and rows array as well as other
-       // options for controlling the display of the table.  Additional
+       // options for controlling the display of the table. Additional
        // documentation can be found here:
        // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
        $table = array(
@@ -139,9 +140,9 @@ if (count($object_rels) > 0 or count($subject_rels) > 0) { ?>
          'colgroups' => array(),
          'empty' => '',
        );
-       
-       // once we have our table array structure defined, we call Drupal's theme_table()
-       // function to generate the table.
+
+       // once we have our table array structure defined, we call Drupal's
+       // theme_table() function to generate the table.
        print theme_table($table); ?>
        </p>
        <br><?php

+ 20 - 19
tripal_example/theme/tripal_example.theme.inc

@@ -2,40 +2,41 @@
 
 /**
  * @file
- * 
- * This file should contain all Drupal hooks for theming content.  For templates 
+ *
+ * This file should contain all Drupal hooks for theming content. For templates
  * that need specific the hook_preprocess functions should be included here
  *
  */
 
 /**
  * implementation of hook_preprocess_HOOK()
- * 
- * Used to alter or add to theme variables.  The variables are passed into
- * templates when prossing.  This function organizes the relationships
+ *
+ * Used to alter or add to theme variables. The variables are passed into
+ * templates when processing. This function organizes the relationships
  * into more simple structures for parsing in the template file.
  *
  * @ingroup tripal_example
  */
 function tripal_example_preprocess_tripal_example_relationships(&$variables) {
-  // EXPLANATION:  If you have implmented a new chado node type and the record
+  // EXPLANATION:  If you have implemented a new Chado node type and the record
   // that belongs to the node has a corresponding xxxx_relationship table
   // this this function can be used to provide relationships to the template
-  // in a format that is easier to parse.  This is one example where specific SQL
-  // statements can improve performance over Tripal API calls.  SQL is not 
+  // in a format that is easier to parse. This is one example where specific SQL
+  // statements can improve performance over Tripal API calls. SQL is not
   // recommended inside of template files, but rather the Tripal API calls only.
   // Therefore, this function queries the relationships and then organizes them
-  // into arrays that are easier and faster to parse.  You should be able to
-  // copy the content of this function 
-  // and adjust as necessary to change table names if your record has relationships.
+  // into arrays that are easier and faster to parse. You should be able to
+  // copy the content of this function and adjust as necessary to change table
+  // names if your record has relationships.
 
   $example = $variables['node']->example;
-  
+
    // expand the example object to include the example relationships.
   $options = array(
     'return_array' => 1,
-    // we don't want to fully recurse we only need information about the
-    // relationship type and the object and subject examples (including example type)
+    // we don't want to fully recurs we only need information about the
+    // relationship type and the object and subject examples (including example
+    // type)
     'include_fk' => array(
       'type_id' => 1,
       'object_id' => array(
@@ -52,7 +53,7 @@ function tripal_example_preprocess_tripal_example_relationships(&$variables) {
   $srelationships = $example->example_relationship->subject_id;
   $orelationships = $example->example_relationship->object_id;
 
-  // combine both object and subject relationshisp into a single array
+  // combine both object and subject relationships into a single array
   $relationships = array();
   $relationships['object'] = array();
   $relationships['subject'] = array();
@@ -62,11 +63,11 @@ function tripal_example_preprocess_tripal_example_relationships(&$variables) {
     foreach ($orelationships as $relationship) {
       $rel = new stdClass();
       $rel->record = $relationship;
-       
+
       // get the relationship and child types
       $rel_type = t(preg_replace('/_/', " ", $relationship->type_id->name));
       $child_type = $relationship->subject_id->type_id->name;
-       
+
       // get the node id of the subject
       $sql = "SELECT nid FROM {chado_example} WHERE example_id = :example_id";
       $n = db_query($sql, array(':example_id' => $relationship->subject_id->example_id))->fetchObject();
@@ -91,14 +92,14 @@ function tripal_example_preprocess_tripal_example_relationships(&$variables) {
       $rel->record = $relationship;
       $rel_type = t(preg_replace('/_/', " ", $relationship->type_id->name));
       $parent_type = $relationship->object_id->type_id->name;
-       
+
       // get the node id of the subject
       $sql = "SELECT nid FROM {chado_example} WHERE example_id = :example_id";
       $n = db_query($sql, array(':example_id' => $relationship->object_id->example_id))->fetchObject();
       if ($n) {
         $rel->record->nid = $n->nid;
       }
-       
+
       if (!array_key_exists($rel_type, $relationships['subject'])) {
         $relationships['subject'][$rel_type] = array();
       }

+ 9 - 9
tripal_example/tripal_example.info

@@ -1,6 +1,6 @@
 ;
 ; Provide details about your module in this file. Instruction for setup of this
-; file can be found here:  https:;drupal.org/node/542202
+; file can be found here: https://drupal.org/node/542202
 ;
 name = Tripal Example
 description = An example module that can be used as a template for anyone wanting to create a custom extension module for Tripal.
@@ -17,30 +17,30 @@ project = tripal_example
 
 ;
 ; In order for this module to appear in the 'Tripal Extensions' section when
-; viewing the module administrative page, the package must be set to 
+; viewing the module administrative page, the package must be set to
 ; 'Tripal Extensions'
-; 
+;
 package = Tripal Extensions
 
 ;
 ; Follow these instructions when specifying the version:
-; https:;drupal.org/node/1015226
-; 
+; https://drupal.org/node/1015226
+;
 version = 7.x-2.0-rc1
 
 ;
-; Stylesheets containing CSS that should always be available for the
-; module should be specified here.  
+; Style-sheets containing CSS that should always be available for the
+; module should be specified here.
 ;
 stylesheets[all][] = theme/css/tripal_example.css
 
 ;
 ; Javascript files that should always be available for the
-; module should be specified here.  
+; module should be specified here.
 ;
 scripts[]          = theme/js/tripal_example.js
 
-; 
+;
 ; Add additional dependencies for other modules using the module project name.
 ; These modules must be enabled before this module can be enabled
 ;

+ 67 - 68
tripal_example/tripal_example.install

@@ -13,12 +13,12 @@
  */
 function tripal_example_disable() {
 
-  // EXPLANATION: If you are using Drupal Views you want to ensure
-  // that any default views that your module provides are disabled
-  // when the module is disabled.  Default views are specified in the
-  // [module name].views.default.inc file.  The following code will disable
-  // these views.  If your module does not create any default views you
-  // can remove the following code.
+  // EXPLANATION: If you are using Drupal Views you want to ensure that any
+  // default views that your module provides are disabled when the module is
+  // disabled. Default views are specified in the
+  // [module name].views.default.inc file. The following code will disable these
+  // views. If your module does not create any default views you can remove the
+  // following code.
 
   // Disable all default views provided by this module
   require_once("tripal_example.views_default.inc");
@@ -33,8 +33,8 @@ function tripal_example_disable() {
  * Implements hook_requirements().
  *
  * Performs check to see if all required dependencies are met. Drupal will
- * automatically check for module dependencies but here you can check for
- * other requirements.
+ * automatically check for module dependencies but here you can check for other
+ * requirements.
  *
  * @ingroup tripal_example
  */
@@ -44,9 +44,9 @@ function tripal_example_requirements($phase) {
   $requirements = array();
   if ($phase == 'install') {
     // EXPLANATION: It is essential that Chado be installed for almost all
-    // Tripal modules. Therefore, the following code checks to ensure Chado
-    // is installed and available.  If your module does not require that
-    // Chado be installed, you can remove the following check.
+    // Tripal modules. Therefore, the following code checks to ensure Chado is
+    // installed and available. If your module does not require that Chado be
+    // installed, you can remove the following check.
 
     // make sure chado is installed
     if (!$GLOBALS["chado_is_installed"]) {
@@ -71,17 +71,16 @@ function tripal_example_install() {
 
   // EXPLANATION: If your module will making data publicly available for
   // download or use by the site you can create the directory using the
-  // tripal_create_files_dir() function.  This will create a directory
-  // in the public access directory which will typcially be in
+  // tripal_create_files_dir() function. This will create a directory in the
+  // public access directory which will typically be in
   // sites/default/files/tripal/[module name]/
 
   // create the module's data directory
   tripal_create_files_dir('tripal_example');
 
-  // EXPLANATION: Here is a good place to add any materialized views,
-  // controlled vocabularies CV, databases or CV terms needed by your module.
-  // To keep this module code short, create functions to do each of those
-  // tasks
+  // EXPLANATION: Here is a good place to add any materialized views, controlled
+  // vocabularies CV, databases or CV terms needed by your module.
+  // To keep this module code short, create functions to do each of those tasks
 
   // add any materialized view
   tripal_example_add_mviews();
@@ -91,11 +90,11 @@ function tripal_example_install() {
 
   // add any controlled vocabularies used by the example module. You may need
   // to add a vocabulary if you to set it as default (see next lines of code).
-  // For example, the Sequence Ontology (SO) is used by the feature module as the
-  // default vocabulary for the feature type_id field.  But, that vocabulary
-  // does not yet exist in Chado until after the SO is loaded using the
-  // Tripal OBO loader.  But, we can add it here as a placeholder so that we can
-  // then set it as a default vocabulary (see below).
+  // For example, the Sequence Ontology (SO) is used by the feature module as
+  // the default vocabulary for the feature type_id field. But, that vocabulary
+  // does not yet exist in Chado until after the SO is loaded using the Tripal
+  // OBO loader. But, we can add it here as a place-holder so that we can then
+  // set it as a default vocabulary (see below).
   tripal_example_add_cvs();
 
 
@@ -103,12 +102,12 @@ function tripal_example_install() {
   tripal_example_add_cvterms();
 
   // EXPLANATION: Many tables in Chado have a 'type_id' column which allows for
-  // association of controlled vocabulries to describe the record.   Chado
-  // places no restrictions on which vocabularies can be used, but Tripal can
-  // be instructed to provide a default vocabulary for any given field. For
-  // example, the feature.type_id column will typically use the Sequence Ontology
-  // In that case, we can use the tripal_set_default_cv() function to specify
-  // the Sequence Ontology (sequence) as the default vocabulary.
+  // association of controlled vocabularies to describe the record. Chado places
+  // no restrictions on which vocabularies can be used, but Tripal can be
+  // instructed to provide a default vocabulary for any given field. For
+  // example, the feature.type_id column will typically use the Sequence
+  // Ontology. In that case, we can use the tripal_set_default_cv() function to
+  // specify the Sequence Ontology (sequence) as the default vocabulary.
   tripal_set_default_cv('example', 'type_id', 'example_type');
   tripal_set_default_cv('exampleprop', 'type_id', 'example_property');
   tripal_set_default_cv('example_relationship', 'type_id', 'example_relationship');
@@ -133,9 +132,9 @@ function tripal_example_uninstall() {
 /**
  * Implementation of hook_schema().
  *
- * Provides a list of tables to be created inside of the Drupal schema
- * (the 'public' schema by default). It uses the Drupal Schema API
- * array structure to define the table, its indexes and constraints.
+ * Provides a list of tables to be created inside of the Drupal schema (the
+ * 'public' schema by default). It uses the Drupal Schema API array structure to
+ * define the table, its indexes and constraints.
  *
  * Schema API documentation is here:
  * https://api.drupal.org/api/drupal/includes%21database%21schema.inc/group/schemaapi/7
@@ -145,12 +144,11 @@ function tripal_example_uninstall() {
 function tripal_example_schema() {
 
   // EXPLANATION: If your module creates a node type for data in the Chado
-  // database then you probably need to link Drupal nodes with a respective
-  // ID in the Chado table.  The following is an example array for a table
-  // that will link the 'chado_example' node type (created by this example
-  // module) with a record in the fake Chado example table.  This table
-  // will link the 'nid' of the node with the 'example_id' of the eample
-  // record.
+  // database then you probably need to link Drupal nodes with a respective ID
+  // in the Chado table. The following is an example array for a table that will
+  // link the 'chado_example' node type (created by this example module) with a
+  // record in the fake Chado example table. This table will link the 'nid' of
+  // the node with the 'example_id' of the example record.
   $schema['chado_example'] = array(
     'fields' => array(
       'vid' => array(
@@ -190,16 +188,17 @@ function tripal_example_schema() {
 };
 
 /**
- * Creates a materialized view that stores the type & number of examples per organism
+ * Creates a materialized view that stores the type & number of examples per
+ * organism.
  *
  * @ingroup tripal_example
  */
 function tripal_example_add_mviews() {
 
-  // EXPLANATION: use the tripal_add_mview() function to add a materialized
-  // view needed by your module.  If you have more than one materialized view
-  // it is best to create a single function for each one and call each
-  // function here. Otherwise this function can become quite long.
+  // EXPLANATION: use the tripal_add_mview() function to add a materialized view
+  // needed by your module. If you have more than one materialized view it is
+  // best to create a single function for each one and call each function here.
+  // Otherwise this function can become quite long.
 
 }
 /**
@@ -208,9 +207,9 @@ function tripal_example_add_mviews() {
  * @ingroup tripal_example
  */
 function tripal_example_add_dbs() {
-  // EXPLANATION: use the tripal_insert_db() function to add any
-  // external databases needed by your module.  If the database already
-  // exists then the function will gracefully return.
+  // EXPLANATION: use the tripal_insert_db() function to add any external
+  // databases needed by your module. If the database already exists then the
+  // function will gracefully return.
 
   tripal_insert_db(array(
     'name' => 'example_db',
@@ -224,10 +223,10 @@ function tripal_example_add_dbs() {
  */
 function tripal_example_add_cvs() {
 
-  // EXPLANATION: use the tripal_insert_cv() function to add any
-  // controlled vocabularies needed by your module.  If the vocabulary already
-  // exists then the function will gracefully return.  Chado convensions
-  // use a singluar name for CV names (not plural)/
+  // EXPLANATION: use the tripal_insert_cv() function to add any controlled
+  // vocabularies needed by your module. If the vocabulary already exists then
+  // the function will gracefully return. Chado conventions use a singular name
+  // for CV names (not plural).
 
   tripal_insert_cv(
     'example_property',
@@ -253,15 +252,15 @@ function tripal_example_add_cvs() {
  */
 function tripal_example_add_cvterms() {
 
-  // EXPLANATION:  for our test module to work we need to add some terms to our example_type
-  // controlled vocabulary.  Ideally we should have a full OBO file for loading
-  // but sometimes we just have a small list that won't really change so
-  // we can add those terms here.
+  // EXPLANATION: for our test module to work we need to add some terms to our
+  // example_type controlled vocabulary. Ideally we should have a full OBO file
+  // for loading but sometimes we just have a small list that won't really
+  // change so we can add those terms here.
   tripal_insert_cvterm(array(
     'id'         => 'test',         // the term accession
     'name'       => 'Test type',    // the human readable term name
     'cv_name'    => 'example_type', // the CV name this term belongs to.
-    'definition' => 'A test type for the example modlue.',
+    'definition' => 'A test type for the example module.',
     'db_name'    => 'example_db',   // the database in which the term is found.
   ));
 }
@@ -281,7 +280,7 @@ function tripal_example_add_custom_tables() {
   //   3) example_relationship (for storing relationships about examples)
   //   4) example_dbxref (for storing cross-references about an example)
   //
-  // To make the code easier to read, each table is created by a separte
+  // To make the code easier to read, each table is created by a separate
   // function called here:
 
   tripal_example_add_example_table();
@@ -289,6 +288,7 @@ function tripal_example_add_custom_tables() {
   tripal_example_add_example_relationship_table();
   tripal_example_add_example_dbxref_table();
 }
+
 /**
  * Adds the 'example' custom table to Chado.
  *
@@ -353,10 +353,9 @@ function tripal_example_add_example_table() {
         ),
       ),
     ),
-    // EXPLANATION: the 'referring_tables' array is the list of tables
-    // that have a foreign key relationships with this table. This
-    // information is required for the Tripal API to be able to expand
-    // tables in templates.
+    // EXPLANATION: the 'referring_tables' array is the list of tables that have
+    // a foreign key relationships with this table. This information is required
+    // for the Tripal API to be able to expand tables in templates.
     'referring_tables' => array(
       0 => 'example_relationship',
       1 => 'exampleprop',
@@ -584,8 +583,8 @@ function tripal_example_update_7200() {
   // https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_update_N/7
   //
   // It is best not to use Tripal API calls inside of this function because an
-  // upgarde from Drupal 6 to Drupal 7 requires that all modules be disabled
-  // which means the Tripal API is not available.  This is an unfortunate
+  // upgrade from Drupal 6 to Drupal 7 requires that all modules be disabled
+  // which means the Tripal API is not available. This is an unfortunate
   // requirement, but will prevent errors during a major upgrade.
 
   // it is good to wrap any database changes inside of a try catch block:
@@ -599,17 +598,17 @@ function tripal_example_update_7200() {
 }
 
 /**
- * Implementation of hook_update_dependencies().  It specifies a list of
- * other modules whose updates must be run prior to this one.
+ * Implementation of hook_update_dependencies(). It specifies a list of other
+ * modules whose updates must be run prior to this one.
  */
 function tripal_example_update_dependencies() {
   $dependencies = array();
 
-  // EXPLANATION: here we can specify which modules must be updated prior
-  // to applying the updates in this module.  This is useful because it
-  // prevents updates from being executed out of order.  The following
-  // example code shows that the 'tripal_example' module update number 7200
-  // must be executed after the 'tripal_cv' module's 7200 update.
+  // EXPLANATION: here we can specify which modules must be updated prior to
+  // applying the updates in this module. This is useful because it prevents
+  // updates from being executed out of order. The following example code shows
+  // that the 'tripal_example' module update number 7200 must be executed after
+  // the 'tripal_cv' module's 7200 update.
   $dependencies['tripal_example'][7200] = array(
     'tripal_cv' => 7200
   );

+ 119 - 121
tripal_example/tripal_example.module

@@ -2,14 +2,14 @@
 
 /**
  * @file
- * This file contains all Drupal hooks for the module other than any
- * node hooks and block hooks. Those go in the [module name].chado_node.inc file
- * and [module_name].blocks.inc respectively
+ * This file contains all Drupal hooks for the module other than any node hooks
+ * and block hooks. Those go in the [module name].chado_node.inc file and
+ * [module_name].blocks.inc respectively
  *
  */
 
-// EXPLANATION: include any files needed for this module.  That includes any 
-// API file, the theme file, or include files.
+// EXPLANATION: include any files needed for this module. That includes any API
+// file, the theme file, or include files.
 require('api/tripal_example.api.inc');
 require('theme/tripal_example.theme.inc');
 require('includes/tripal_example.admin.inc');
@@ -18,21 +18,20 @@ require('includes/tripal_example.chado_node.inc');
 
 /**
  * Implementation of hook_permissions()
- * 
+ *
  * Set the permission types that this module uses.
- * 
+ *
  * @ingroup tripal_example
  */
 function tripal_example_permission() {
-  
-  // EXPLANATION:  here we want to setup any of the permission types
-  // that this module needs.  Our exmample module creates a new
-  // chado node type called 'chado_example'.  Therefore, we need 
-  // permissions to view, edit, delete, create our new node type.  Additionally,
-  // we want to add a permission that allows for administration of this 
-  // module.  These permissions will appear in the 'People' -> 'Permissions'
-  // configuration page and allow the site admin to specify which user roles
-  // are allowed to perform specific actions.
+
+  // EXPLANATION:  here we want to setup any of the permission types that this
+  // module needs. Our example module creates a new chado node type called
+  // 'chado_example'. Therefore, we need permissions to view, edit, delete,
+  // create our new node type. Additionally, we want to add a permission that
+  // allows for administration of this module. These permissions will appear in
+  // the 'People' -> 'Permissions' configuration page and allow the site admin
+  // to specify which user roles are allowed to perform specific actions.
   return array(
     'access chado_example content' => array(
       'title' => t('View Examples'),
@@ -59,32 +58,32 @@ function tripal_example_permission() {
 
 /**
  * Implements hook_menu()
- * 
+ *
  * Specifies menu items and URLs used by this module.
  *
  * @ingroup tripal_example
  */
 function tripal_example_menu() {
   $items = array();
-  
-  // EXPLANATION:  the $items array should be popluated to contain a list of 
-  // menu items or URL callbacks that our module needs.  
-  // all Tripal Extension modules shoudl provide at least these menu items:
+
+  // EXPLANATION:  the $items array should be populated to contain a list of
+  // menu items or URL callbacks that our module needs.
+  // all Tripal Extension modules should provide at least these menu items:
   //  * A menu item for an administrative home page
   //  * A menu item for 'Help' documentation
   //  * A menu item for a module configuration page
   //
   // Additionally, if your module defines a custom node type that is linked
   // to a record in Chado:
-  //  * A menu item for syncing drupal nodes with Chado records.   
-  //    
-  
+  //  * A menu item for syncing drupal nodes with Chado records.
+  //
+
   // EXPLANATION:  all extension modules should have an administrative menu item
-  // with the path set to 'admin/tripal/extension/[module name]'.  This will
-  // place the menu item in the 'Tripal' -> 'Extesion Modules' page.  Because this
-  // is an administrative menu item we must be sure to set the 'access arguments'
-  // to be 'administer tripal example' which is a permission type we created
-  // in the tripal_example_permissions() function above.
+  // with the path set to 'admin/tripal/extension/[module name]'. This will
+  // place the menu item in the 'Tripal' -> 'Extension Modules' page. Because
+  // this is an administrative menu item we must be sure to set the
+  // 'access arguments' to be 'administer tripal example' which is a permission
+  // type we created in the tripal_example_permissions() function above.
   $items['admin/tripal/extension/tripal_example'] = array(
     'title' => 'Examples',
     'description' => 'Example module for help with development of new extension modules.',
@@ -93,14 +92,14 @@ function tripal_example_menu() {
     'type' => MENU_NORMAL_ITEM,
   );
 
-  // EXPLANATION: all extension modules should provide help documentation to 
+  // EXPLANATION: all extension modules should provide help documentation to
   // describe the functionality of the module and any installation or setup
-  // tasks that may be required.  The menu 'type' is MENU_LOCAL_TASK so that
-  // the link appears in a tab on the extension module's administrative page.
-  // here the 'page callback' specifies that we are using Drupal's theme 
+  // tasks that may be required. The menu 'type' is MENU_LOCAL_TASK so that the
+  // link appears in a tab on the extension module's administrative page.
+  // Here the 'page callback' specifies that we are using Drupal's theme
   // function and the 'page_arguments' indicate the name of the template file
-  // Thus, all help documentation should be provided in the 
-  // [module name]/theme/tripal_example_help.tpl.php file. 
+  // Thus, all help documentation should be provided in the
+  // [module name]/theme/tripal_example_help.tpl.php file.
   $items['admin/tripal/extension/tripal_example/help'] = array(
     'title' => 'Help',
     'description' => 'Basic Description of Tripal Library Module Functionality',
@@ -111,14 +110,14 @@ function tripal_example_menu() {
     'weight' => 10
   );
 
-  // EXPLANATION: all extension modules should provide a configuration page. 
+  // EXPLANATION: all extension modules should provide a configuration page.
   // Even if your module does not need configuration the menu item and page
   // should be created. This helps users recognize that the module is installed
-  // and working.  The configuration page can simply state that no 
-  // configuration settings are available.  Typically a form is provided for the 
-  // module's configuration settings. Therefore the 'page callback' uses the
+  // and working. The configuration page can simply state that no configuration
+  // settings are available. Typically a form is provided for the module's
+  // configuration settings. Therefore the 'page callback' uses the
   // drupal_get_form() function and the 'page argument' indicates the form
-  // to call is named 'tripal_eample_admin'.  The function that describes
+  // to call is named 'tripal_eample_admin'. The function that describes
   // to form is in the includes/tripal_example.admin.inc file.
   $items['admin/tripal/extension/tripal_example/configuration'] = array(
     'title' => 'Settings',
@@ -129,10 +128,10 @@ function tripal_example_menu() {
     'type' => MENU_LOCAL_TASK,
     'weight' => 5
   );
-  
+
   // EXPLANATION: If your module defines a new chado node type and that node
   // type directly links to a record in Chado, then you can use the Tripal API
-  // to quickly provide syncing functionality.  See the API documentation here
+  // to quickly provide syncing functionality. See the API documentation here
   // for more information on how that is setup:
   // http://api.tripal.info/api/tripal/tripal_core%21api%21tripal_core.chado_nodes.api.inc/function/chado_node_sync_form/2.x
   $items['admin/tripal/extension/tripal_example/sync'] = array(
@@ -144,15 +143,15 @@ function tripal_example_menu() {
     'type' => MENU_LOCAL_TASK,
     'weight' => 2
   );
-  
+
   // EXPLANATION: If your module defines a new node type that uses the default
-  // table of contents (left-side bar of content panes on a page). Then a 
-  // 'TOC' link will automatically appear on the node page to allow for 
-  // customization of the TOC.  However those customizations are only node
-  // specific.  To provide a tab in the module's administrative pages add the
-  // following menu item. This menu will provide a form similar to the one
-  // found on the node that allows the user to set global TOC settings for the
-  // content type.  Be sure to always use a menu path of the form:
+  // table of contents (left-side bar of content panes on a page). Then a 'TOC'
+  // link will automatically appear on the node page to allow for customization
+  // of the TOC. However those customizations are only node specific. To provide
+  // a tab in the module's administrative pages add the following menu item.
+  // This menu will provide a form similar to the one found on the node that
+  // allows the user to set global TOC settings for the content type. Be sure to
+  // always use a menu path of the form:
   //   admin/tripal/chado/[module name]/[content type name]_toc
   // this allows for a module to support TOC management when there are multiple
   // content types provided by the module, as the content type is specified
@@ -168,16 +167,16 @@ function tripal_example_menu() {
     'file path' => drupal_get_path('module', 'tripal_core'),
     'weight' => 3
   );
-  
+
   return $items;
 }
 
 /**
  * Implements hook_views_api()
- * 
- * This hook tells drupal that there is views support for
- * for this module which then automatically includes the tripal_db.views.inc 
- * where all the views integration code is found.
+ *
+ * This hook tells Drupal that there is views support for this module which then
+ * automatically includes the tripal_db.views.inc where all the views
+ * integration code is found.
  *
  * @ingroup tripal_example
  */
@@ -189,35 +188,34 @@ function tripal_example_views_api() {
 
 
 /**
- *  We need to let drupal know about our theme functions and their arguments.
- *  We create theme functions to allow users of the module to customize the
- *  look and feel of the output generated in this module
+ * We need to let Drupal know about our theme functions and their arguments.
+ * We create theme functions to allow users of the module to customize the look
+ * and feel of the output generated in this module.
  *
  * @ingroup tripal_example
  */
 function tripal_example_theme($existing, $type, $theme, $path) {
   $core_path = drupal_get_path('module', 'tripal_core');
 
-  // EXPLANATION: this function defines all of the functions and templates
-  // that this module needs to provide content.  These details are provided
-  // in the form of an array the indicates which functions or templates
-  // provide content.  Please see the Drupal theming guide for an in-depth
-  // description for how theming works in Drupal:
+  // EXPLANATION: this function defines all of the functions and templates that
+  // this module needs to provide content. These details are provided in the
+  // form of an array the indicates which functions or templates provide
+  // content. Please see the Drupal theming guide for an in-depth description
+  // for how theming works in Drupal:
   // https://drupal.org/documentation/theme
-  
+
   $items = array(
-    
-    // EXPLANATION:  If this module defines a new node type that displays
-    // Chado data then we should use Tripal's default node template.  This
-    // template ensures that all content provided by Tripal and Tripal 
-    // extension modules has the same look and feel.  It is designed to be
-    // generic such that it won't intefer with the look-and-feel of the default
-    // theme.  This generic template will organize the node into a table
-    // of contents found on the left-side of the page and place the content
-    // in the center of the page.  User's will cycle through content on the 
-    // page by clicking the links in the table of contents. If you do not want
-    // to use the default Tripal template you can change this array to your
-    // liking.
+
+    // EXPLANATION:  If this module defines a new node type that displays Chado
+    // data then we should use Tripal's default node template. This template
+    // ensures that all content provided by Tripal and Tripal extension modules
+    // has the same look and feel. It is designed to be generic such that it
+    // won't interfere with the look-and-feel of the default theme. This generic
+    // template will organize the node into a table of contents found on the
+    // left-side of the page and place the content in the center of the page.
+    // User's will cycle through content on the page by clicking the links in
+    // the table of contents. If you do not want to use the default Tripal
+    // template you can change this array to your liking.
     'node__chado_example' => array(
       'template' => 'node--chado-generic',
       'render element' => 'node',
@@ -230,12 +228,12 @@ function tripal_example_theme($existing, $type, $theme, $path) {
     // correspond directly to a file with the extension '.tpl.php'. For example
     // the 'tripal_example_base' template will have a corresponding
     // tripal_example_base.tpl.php file where the display code is housed.
-    // The only required templates are the 'base',  'help' and 'teaseer' templates.
-    // The base template provides the basic information about the record in 
-    // in Chado.  The 'help' template provides the adminstrative help documenation,
-    // and the teaser provides a brief summary of the record that can be used
-    // as short description of the record in aggregated lists.
-    
+    // The only required templates are the 'base',  'help' and 'teaser'
+    // templates. The base template provides the basic information about the
+    // record in Chado. The 'help' template provides the administrative help
+    // documentation, and the teaser provides a brief summary of the record that
+    // can be used as short description of the record in aggregated lists.
+
     // the base template
     'tripal_example_base' => array(
       'variables' => array('node' => NULL),
@@ -254,13 +252,14 @@ function tripal_example_theme($existing, $type, $theme, $path) {
       'template' => 'tripal_example_teaser',
       'path' => "$path/theme/templates",
     ),
-    
-    
-    // EXPLANATION: Typically, a different template is created for each subset of data.
-    // for example, most Chado tables have a 'XXXXprop', 'XXXX_cvterm',
+
+
+    // EXPLANATION: Typically, a different template is created for each subset
+    // of data.
+    // For example, most Chado tables have a 'XXXXprop', 'XXXX_cvterm',
     // 'XXXX_dbxref', 'XXXX_synonyms', 'XXXX_relationships' tables. Therefore,
     // a template is created to display data from each of these tables.
-    
+
     'tripal_example_properties' => array(
       'variables' => array('node' => NULL),
       'template' => 'tripal_example_properties',
@@ -279,11 +278,11 @@ function tripal_example_theme($existing, $type, $theme, $path) {
 
     // EXPLANATION: sometimes a module may want to add content to another
     // modules' node types. For example, the feature module does this by
-    // adding a 'feature summary' data to an organism.  To add data to another
-    // module's node, the templates belong to this module and are 
-    // specified in the same way as above.  However, the naming of the 
-    // template is changed to include the name of the module that supplies
-    // the node type followed by our record name: 
+    // adding a 'feature summary' data to an organism. To add data to another
+    // module's node, the templates belong to this module and are specified in
+    // the same way as above. However, the naming of the template is changed to
+    // include the name of the module that supplies the node type followed by
+    // our record name:
 
     // tripal_organism templates
     'tripal_organism_examples' => array(
@@ -292,25 +291,24 @@ function tripal_example_theme($existing, $type, $theme, $path) {
       'path' => "$path/theme/templates",
     ),
   );
-  
+
   return $items;
 }
 
 /**
  * Implements hook_help()
- * 
+ *
  * Adds a help page to the module list
  */
 function tripal_example_help ($path, $arg) {
-  
-  // EXPLANATION: in the tripal_example_menu() function above we created 
-  // a menu item for the help documentation.  The menu item specified 
-  // a function that should be called when the menu item is clicked.  This 
-  // is that function.  But, rather than place HTML code in this function
-  // we want to have our help documentation in a template file.  We 
-  // specified in the tripal_example_theme() function that we have a template
-  // file so now we want to use get the contents of that template file and
-  // return it.
+
+  // EXPLANATION: in the tripal_example_menu() function above we created a menu
+  // item for the help documentation. The menu item specified a function that
+  // should be called when the menu item is clicked. This is that function. But,
+  // rather than place HTML code in this function we want to have our help
+  // documentation in a template file. We specified in the
+  // tripal_example_theme() function that we have a template file so now we want
+  // to use get the contents of that template file and return it.
   if ($path == 'admin/help#tripal_example') {
     return theme('tripal_example_help', array());
   }
@@ -324,38 +322,38 @@ function tripal_example_help ($path, $arg) {
  */
 function tripal_example_cron() {
 
-  // EXPLANATION: here we can add any code that needs to be executed when
-  // the Drupal cron is run.
+  // EXPLANATION: here we can add any code that needs to be executed when the
+  // Drupal cron is run.
 }
 
 
 /**
  * Implementation of hook_form_alter()
- * 
+ *
  * Allows a module to alter any form prior to it being rendered. For more
  * details about Drupal's Form API see this page:
- * 
+ *
  * https://api.drupal.org/api/drupal/includes!form.inc/group/form_api/7
  *
  */
 function tripal_example_form_alter(&$form, &$form_state, $form_id) {
-  
+
   if ($form_id == "chado_example_node_form") {
-    
-    // EXPLANATION:  The hook_form_alter() Drupal hook is used to alter
-    // a form before it is displayed.  This allows any module to provide new
-    // form elements or change the form that another module creates.  We do
-    // not need to alter a form created by another module, but we do want to
-    // alter the form for our new node type.  For example, all node types
-    // will automatically have a 'Preview' button.  For inserting or updating
-    // data for Chado we don't really need a Preview button and it complicates
-    // the form.  So, we use the following code to disable the Preview button.
-    // if you want to keep the preview button then remove this code.
-    // turn of preview button for insert/updates
+
+    // EXPLANATION:  The hook_form_alter() Drupal hook is used to alter a form
+    // before it is displayed. This allows any module to provide new form
+    // elements or change the form that another module creates. We do not need
+    // to alter a form created by another module, but we do want to alter the
+    // form for our new node type. For example, all node types will
+    // automatically have a 'Preview' button. For inserting or updating data
+    // for Chado we don't really need a Preview button and it complicates the
+    // form. So, we use the following code to disable the Preview button. If
+    // you want to keep the preview button then remove this code. turn of
+    // preview button for insert/updates
     $form['actions']['preview']['#access'] = FALSE;
-    
+
     // EXPLANATION: Drupal always adds a 'body' field to all node types.
-    // Our node type doens't use the 'body' field so we remove it from the form.
+    // Our node type doesn't use the 'body' field so we remove it from the form.
     unset($form['body']);
   }
 }

+ 2 - 2
tripal_example/tripal_example.views.inc

@@ -1,8 +1,8 @@
 <?php
 /**
  *  @file
- *  This file contains the basic functions for views integration of
- *  chado/tripal example tables
+ *  This file contains the basic functions for views integration of chado/tripal
+ *  example tables
  */
 
 // EXPLANATION: see another tripal module (e.g. tripal_feature) for example

+ 9 - 9
tripal_example/tripal_example.views_default.inc

@@ -11,15 +11,15 @@
 */
 function tripal_example_views_default_views() {
   $views = array();
-  
-  // EXPLANATION:  use this function to programmatically define any default
-  // Drupal views that your module will provide automatically.  Typically
-  // there are two default views: 1) one for the administrator to quickly
-  // find data managed by your module, or 2) one for users to be able to
-  // search for public data.  
+
+  // EXPLANATION: use this function to programmatically define any default
+  // Drupal views that your module will provide automatically. Typically there
+  // are two default views: 1) one for the administrator to quickly find data
+  // managed by your module, or 2) one for users to be able to search for public
+  // data.
   //
-  // See another Tripal module such as tripal_feature for an example 
-  // of how to setup a default views.
-  
+  // See another Tripal module such as tripal_feature for an example of how to
+  // setup a default views.
+
   return $views;
 }

+ 31 - 29
tripal_feature/includes/tripal_feature.chado_node.inc

@@ -260,25 +260,26 @@ function chado_feature_form($node, &$form_state) {
  */
 function chado_feature_validate($node, $form, &$form_state) {
 
+
   // We only want to validate when the node is saved.
   // Since this validate can be called on AJAX and Deletion of the node
   // we need to make this check to ensure queries are not executed
   // without the proper values.
-  if(!isset($node->op) OR $node->op != 'Save') {
+  if(property_exists($node, "op") and $node->op != 'Save') {
     return;
   }
 
   // we are syncing if we do not have a node ID but we do have a feature_id. We don't
   // need to validate during syncing so just skip it.
-  if (is_null($node->nid) and property_exists($node, 'feature_id') and $node->feature_id != 0) {
+  if (!property_exists($node, 'nid') and property_exists($node, 'feature_id') and $node->feature_id != 0) {
     return;
   }
 
   // remove surrounding white-space on submitted values
-  $node->uniquename   = trim($node->uniquename);
-  $node->fname        = trim($node->fname);
-  $node->feature_type = trim($node->feature_type);
-  $node->residues     = trim($node->residues);
+  $node->uniquename   = property_exists($node, 'uniquename') ? trim($node->uniquename) : '';
+  $node->fname        = property_exists($node, 'fname') ? trim($node->fname) : '';
+  $node->feature_type = property_exists($node, 'feature_type') ? trim($node->feature_type) : '';
+  $node->residues     = property_exists($node, 'residues') ? trim($node->residues) : '';
 
   // Validating for an update
   if (property_exists($node, 'nid')) {
@@ -338,6 +339,7 @@ function chado_feature_validate($node, $form, &$form_state) {
         CVT.name      = :cvtname
     ";
     $args = array(':name' => $node->uniquename, ':organism_id' => $node->organism_id, ':cvtname' => $node->feature_type);
+
     $result = chado_query($sql, $args)->fetchObject();
     if ($result) {
       form_set_error('uniquename', t("Feature insert cannot proceed. The feature name '$node->uniquename' already exists for this organism. Please provide a unique name for this feature."));
@@ -412,33 +414,33 @@ function chado_feature_node_access($node, $op, $account) {
  */
 function chado_feature_insert($node) {
 
-  $node->uniquename   = trim($node->uniquename);
-  $node->fname        = trim($node->fname);
-  $node->feature_type = trim($node->feature_type);
-  $node->residues     = trim($node->residues);
-
-  // remove spaces, newlines from residues
-  $residues = preg_replace("/[\n\r\s]/", "", $node->residues);
-  $obsolete = 'FALSE';
-  if ($node->is_obsolete) {
-    $obsolete = 'TRUE';
-  }
-
-  // get the feature type id
-  $values = array(
-    'cv_id' => array(
-      'name' => 'sequence'
-    ),
-    'name' => $node->feature_type
-  );
-  $type = chado_select_record('cvterm', array('cvterm_id'), $values);
-
   $feature_id = '';
 
   // if there is a feature_id in the $node object then this must be a sync so
   // we can skip adding the feature as it is already there, although
-  // we do need to proceed with the rest of the insert
+  // we do need to proceed with insertion into the chado/drupal linking table.
   if (!property_exists($node, 'feature_id')) {
+    $node->uniquename   = trim($node->uniquename);
+    $node->fname        = trim($node->fname);
+    $node->feature_type = trim($node->feature_type);
+    $node->residues     = trim($node->residues);
+
+    // remove spaces, newlines from residues
+    $residues = preg_replace("/[\n\r\s]/", "", $node->residues);
+    $obsolete = 'FALSE';
+    if ($node->is_obsolete) {
+      $obsolete = 'TRUE';
+    }
+
+    // get the feature type id
+    $values = array(
+        'cv_id' => array(
+            'name' => 'sequence'
+        ),
+        'name' => $node->feature_type
+    );
+    $type = chado_select_record('cvterm', array('cvterm_id'), $values);
+
     $values = array(
       'organism_id' => $node->organism_id,
       'name' => $node->fname,
@@ -959,4 +961,4 @@ function chado_feature_chado_node_default_title_format() {
  */
 function chado_feature_chado_node_default_url_format() {
   return '/feature/[feature.organism_id>organism.genus]/[feature.organism_id>organism.species]/[feature.type_id>cvterm.name]/[feature.uniquename]';
-}
+}

+ 7 - 9
tripal_feature/includes/tripal_feature.gff_loader.inc

@@ -477,6 +477,7 @@ function tripal_feature_load_gff3($gff_file, $organism_id, $analysis_id,
       // check to see if we have FASTA section, if so then set the variable
       // to start parsing
       if (preg_match('/^##FASTA/i', $line)) {
+        print "Parsing FASTA portion...\n";
         if ($remove) {
           // we're done because this is a delete operation so break out of the loop.
           break;
@@ -498,7 +499,7 @@ function tripal_feature_load_gff3($gff_file, $organism_id, $analysis_id,
           $result = chado_query($sel_cvterm_sql, $query);
           $cvterm = $result->fetchObject();
           if (!$cvterm) {
-            tripal_report_error('tripal_feature', TRIPAL_ERROR, 
+            tripal_report_error('tripal_feature', TRIPAL_ERROR,
              'cannot find feature type \'%landmark_type\' on line %line_num of the GFF file',
               array('%landmark_type' => $landmark_type, '%line_num' => $line_num));
             return '';
@@ -672,11 +673,6 @@ function tripal_feature_load_gff3($gff_file, $organism_id, $analysis_id,
           }
         }
       }
-
-      if ($skip_line) {
-        continue;
-      }
-
       // if neither name nor uniquename are provided then generate one
       if (!$attr_uniquename and !$attr_name) {
         // check if an alternate ID field is suggested, if so, then use
@@ -703,14 +699,16 @@ function tripal_feature_load_gff3($gff_file, $organism_id, $analysis_id,
       }
 
       // if a name is not specified then use the unique name as the name
-      if (strcmp($attr_name, '')==0) {
+      if (strcmp($attr_name, '') == 0) {
         $attr_name = $attr_uniquename;
       }
 
-      // if an ID attribute is not specified then use the attribute name plus the date
+      // if an ID attribute is not specified then we must generate a
+      // unique ID. Do this by combining the attribute name with the date
+      // and line number.
       if (!$attr_uniquename) {
         $date = getdate();
-        $attr_uniquename = $attr_name . '-' . $date[0];
+        $attr_uniquename = $attr_name . '-' . $date[0] . '-' . $line_num;
       }
 
       // make sure the landmark sequence exists in the database.  If the user

+ 9 - 7
tripal_featuremap/includes/tripal_featuremap.chado_node.inc

@@ -159,19 +159,19 @@ function chado_featuremap_validate($node, $form, &$form_state) {
   // Since this validate can be called on AJAX and Deletion of the node
   // we need to make this check to ensure queries are not executed
   // without the proper values.
-  if($node->op != 'Save') {
+  if(property_exists($node, "op") and $node->op != 'Save') {
     return;
   }
 
   // we are syncing if we do not have a node ID but we do have a featuremap_id. We don't
   // need to validate during syncing so just skip it.
-  if (is_null($node->nid) and property_exists($node, 'featuremap_id') and $node->featuremap_id != 0) {
+  if (!property_exists($node, 'nid') and property_exists($node, 'featuremap_id') and $node->featuremap_id != 0) {
     return;
   }
 
   // trim white space from text fields
-  $node->fmapname       = trim($node->fmapname);
-  $node->description    = trim($node->description);
+  $node->fmapname = property_exists($node, 'fmapname') ? trim($node->fmapname) : '';
+  $node->description = property_exists($node, 'description') ? trim($node->description) : '';
 
   $featuremap = 0;
   // check to make sure the unique name on the map is unique
@@ -261,14 +261,16 @@ function chado_featuremap_node_access($node, $op, $account) {
  */
 function chado_featuremap_insert($node) {
 
-  $node->fmapname       = trim($node->fmapname);
-  $node->description    = trim($node->description);
+  $featuremap_id = '';
 
   // if there is an featuremap_id in the $node object then this must be a sync so
   // we can skip adding the featuremap as it is already there, although
-  // we do need to proceed with the rest of the insert
+  // we do need to proceed with insertion into the chado/drupal linking table.
   if (!property_exists($node, 'featuremap_id')) {
 
+    $node->fmapname       = trim($node->fmapname);
+    $node->description    = trim($node->description);
+
     $values = array(
       'name'        => $node->fmapname,
       'description' => $node->description,

+ 11 - 9
tripal_library/includes/tripal_library.chado_node.inc

@@ -222,20 +222,20 @@ function chado_library_validate($node, $form, &$form_state) {
   // Since this validate can be called on AJAX and Deletion of the node
   // we need to make this check to ensure queries are not executed
   // without the proper values.
-  if($node->op != 'Save') {
+  if(property_exists($node, "op") and $node->op != 'Save') {
     return;
   }
 
   // we are syncing if we do not have a node ID but we do have a featuremap_id. We don't
   // need to validate during syncing so just skip it.
-  if (is_null($node->nid) and property_exists($node, 'library_id') and $node->library_id != 0) {
+  if (!property_exists($node, 'nid') and property_exists($node, 'library_id') and $node->library_id != 0) {
     return;
   }
 
   // trim white space from text fields
-  $node->libraryname = trim($node->libraryname);
-  $node->uniquename  = trim($node->uniquename);
-  $node->description = trim($node->description);
+  $node->libraryname = property_exists($node, 'libraryname') ? trim($node->libraryname) : '';
+  $node->uniquename  = property_exists($node, 'uniquename') ? trim($node->uniquename) : '';
+  $node->description = property_exists($node, 'description') ? trim($node->description) : '';
 
   $lib = 0;
   // check to make sure the unique name on the library is unique
@@ -268,14 +268,16 @@ function chado_library_validate($node, $form, &$form_state) {
  */
 function chado_library_insert($node) {
 
-  $node->libraryname = trim($node->libraryname);
-  $node->uniquename  = trim($node->uniquename);
-  $node->description = trim($node->description);
+  $library_id = '';
 
   // if there is an library_id in the $node object then this must be a sync so
   // we can skip adding the library as it is already there, although
-  // we do need to proceed with the rest of the insert
+  // we do need to proceed with insertion into the chado/drupal linking table.
   if (!property_exists($node, 'library_id')) {
+    $node->libraryname = trim($node->libraryname);
+    $node->uniquename  = trim($node->uniquename);
+    $node->description = trim($node->description);
+
     $values = array(
       'name' => $node->libraryname,
       'uniquename' => $node->uniquename,

+ 20 - 15
tripal_organism/includes/tripal_organism.chado_node.inc

@@ -220,22 +220,22 @@ function chado_organism_validate($node, $form, &$form_state) {
   // Since this validate can be called on AJAX and Deletion of the node
   // we need to make this check to ensure queries are not executed
   // without the proper values.
-  if($node->op != 'Save') {
+  if(property_exists($node, "op") and $node->op != 'Save') {
     return;
   }
 
   // we are syncing if we do not have a node ID but we do have a organism_id. We don't
   // need to validate during syncing so just skip it.
-  if (is_null($node->nid) and property_exists($node, 'organism_id') and $node->organism_id != 0) {
+  if (!property_exists($node, 'nid') and property_exists($node, 'organism_id') and $node->organism_id != 0) {
     return;
   }
 
   // remove any white space around values
-  $node->genus        = trim($node->genus);
-  $node->species      = trim($node->species);
-  $node->abbreviation = trim($node->abbreviation);
-  $node->common_name  = trim($node->common_name);
-  $node->description  = trim($node->description);
+  $node->genus        = property_exists($node, 'genus') ? trim($node->genus) : '';
+  $node->species      = property_exists($node, 'species') ? trim($node->species) : '';
+  $node->abbreviation = property_exists($node, 'abbreviation') ? trim($node->abbreviation) : '';
+  $node->common_name  = property_exists($node, 'common_name') ? trim($node->common_name) : '';
+  $node->description  = property_exists($node, 'description') ? trim($node->description) : '';
 
   // Validating for an update
   if (property_exists($node, 'organism_id')) {
@@ -284,17 +284,20 @@ function chado_organism_validate($node, $form, &$form_state) {
  * @ingroup tripal_organism
  */
 function chado_organism_insert($node) {
-  // remove any white space around values
-  $node->genus        = trim($node->genus);
-  $node->species      = trim($node->species);
-  $node->abbreviation = trim($node->abbreviation);
-  $node->common_name  = trim($node->common_name);
-  $node->description  = trim($node->description);
+
+  $organism_id = '';
 
   // if there is an organism_id in the $node object then this must be a sync so
   // we can skip adding the organism as it is already there, although
-  // we do need to proceed with the rest of the insert
+  // we do need to proceed with insertion into the chado/drupal linking table.
   if (!property_exists($node, 'organism_id')) {
+    // remove any white space around values
+    $node->genus        = trim($node->genus);
+    $node->species      = trim($node->species);
+    $node->abbreviation = trim($node->abbreviation);
+    $node->common_name  = trim($node->common_name);
+    $node->description  = trim($node->description);
+
     $values = array(
       'genus'        => $node->genus,
       'species'      => $node->species,
@@ -383,7 +386,9 @@ function chado_organism_update($node) {
     'comment' => $node->description
   );
   $org_status = chado_update_record('organism', $match, $values);
-  chado_organism_add_image($node);
+  if ( $node->organism_image != '' ) {
+    chado_organism_add_image($node);
+  }
 
   // * Properties Form *
   $details = array(

+ 9 - 7
tripal_project/includes/tripal_project.chado_node.inc

@@ -200,19 +200,19 @@ function chado_project_validate($node, $form, &$form_state) {
   // Since this validate can be called on AJAX and Deletion of the node
   // we need to make this check to ensure queries are not executed
   // without the proper values.
-  if($node->op != 'Save') {
+  if(property_exists($node, "op") and $node->op != 'Save') {
     return;
   }
 
   // we are syncing if we do not have a node ID but we do have a project_id. We don't
   // need to validate during syncing so just skip it.
-  if (is_null($node->nid) and property_exists($node, 'project_id') and $node->project_id != 0) {
+  if (!property_exists($node, 'nid') and property_exists($node, 'project_id') and $node->project_id != 0) {
     return;
   }
 
   // trim white space from text fields
-  $node->title = trim($node->title);
-  $node->description = trim($node->description);
+  $node->title = property_exists($node, 'title') ? trim($node->title) : '';
+  $node->description = property_exists($node, 'description') ? trim($node->description) : '';
 
   $project = 0;
   // check to make sure the name on the project is unique
@@ -240,13 +240,15 @@ function chado_project_validate($node, $form, &$form_state) {
  */
 function chado_project_insert($node) {
 
-  $node->title = trim($node->title);
-  $node->description = trim($node->description);
+  $project_id = '';
 
   // if there is an project_id in the $node object then this must be a sync so
   // we can skip adding the project as it is already there, although
-  // we do need to proceed with the rest of the insert
+  // we do need to proceed with insertion into the chado/drupal linking table.
   if (!property_exists($node, 'project_id')) {
+    $node->title = trim($node->title);
+    $node->description = trim($node->description);
+
     $values = array(
       'name' => $node->title,
       'description' => '',

+ 19 - 18
tripal_pub/includes/tripal_pub.chado_node.inc

@@ -337,22 +337,22 @@ function chado_pub_validate($node, $form, &$form_state) {
   // Since this validate can be called on AJAX and Deletion of the node
   // we need to make this check to ensure queries are not executed
   // without the proper values.
-  if($node->op != 'Save') {
+  if(property_exists($node, "op") and $node->op != 'Save') {
     return;
   }
 
   // we are syncing if we do not have a node ID but we do have a pub_id. We don't
   // need to validate during syncing so just skip it.
-  if (is_null($node->nid) and property_exists($node, 'pub_id') and $node->pub_id != 0) {
+  if (!property_exists($node, 'nid') and property_exists($node, 'pub_id') and $node->pub_id != 0) {
     return;
   }
 
   // get the submitted values
-  $title        = trim($node->pubtitle);
-  $pyear        = trim($node->pyear);
-  $uniquename   = trim($node->uniquename);
-  $is_obsolete  = $node->is_obsolete;
-  $type_id      = $node->type_id;
+  $title        = property_exists($node, 'pubtitle') ? trim($node->pubtitle) : '';
+  $pyear        = property_exists($node, 'pyear') ? trim($node->pyear) : '';
+  $uniquename   = property_exists($node, 'uniquename') ? trim($node->uniquename) : '';
+  $is_obsolete  = property_exists($node, 'is_obsolete') ? trim($node->is_obsolete) : 0;
+  $type_id      = property_exists($node, 'type_id') ? trim($node->type_id) : '';
 
   $pub = array();
 
@@ -573,21 +573,23 @@ function chado_pub_node_access($node, $op, $account) {
  */
 function chado_pub_insert($node) {
 
-  $node->pubtitle     = trim($node->pubtitle);
-  $node->pyear        = trim($node->pyear);
-  $node->uniquename   = trim($node->uniquename);
-  $is_obsolete  = $node->is_obsolete;
-  $type_id      = $node->type_id;
-
-  // we need an array suitable for the tripal_pub_create_citation() function
-  // to automatically generate a citation if a uniquename doesn't already exist
-  $pub_arr = array();
+  $pub_id = '';
 
   // if there is an pub_id in the $node object then this must be a sync so
   // we can skip adding the pub as it is already there, although
-  // we do need to proceed with the rest of the insert
+  // we do need to proceed with insertion into the chado/drupal linking table.
   if (!property_exists($node, 'pub_id')) {
 
+    $node->pubtitle     = trim($node->pubtitle);
+    $node->pyear        = trim($node->pyear);
+    $node->uniquename   = trim($node->uniquename);
+    $is_obsolete  = $node->is_obsolete;
+    $type_id      = $node->type_id;
+
+    // we need an array suitable for the tripal_pub_create_citation() function
+    // to automatically generate a citation if a uniquename doesn't already exist
+    $pub_arr = array();
+
     $properties = array(); // stores all of the properties we need to add
     $cross_refs = array(); // stores any cross references for this publication
 
@@ -1164,7 +1166,6 @@ function tripal_pub_node_insert($node) {
  * @ingroup tripal_pub
  */
 function tripal_pub_node_load($nodes, $types) {
-
   if (count(array_intersect(array('chado_pub'), $types))) {
     foreach ($nodes as $nid => $node) {
       if ($node->type == 'chado_pub' and !property_exists($node, 'path')) {

+ 13 - 12
tripal_stock/includes/tripal_stock.chado_node.inc

@@ -323,22 +323,22 @@ function chado_stock_validate(&$node, $form, &$form_state) {
   // Since this validate can be called on AJAX and Deletion of the node
   // we need to make this check to ensure queries are not executed
   // without the proper values.
-  if(!isset($node->op) OR $node->op != 'Save') {
+  if(property_exists($node, "op") and $node->op != 'Save') {
     return;
   }
 
   // we are syncing if we do not have a node ID but we do have a stock_id. We don't
   // need to validate during syncing so just skip it.
-  if (is_null($node->nid) and property_exists($node, 'stock_id') and $node->stock_id != 0) {
+  if (!property_exists($node, 'nid') and property_exists($node, 'stock_id') and $node->stock_id != 0) {
     return;
   }
 
   // remove surrounding whitespace
-  $node->uniquename = trim($node->uniquename);
-  $node->sname = trim($node->sname);
-  $node->stock_description = trim($node->stock_description);
-  $node->accession = trim($node->accession);
-  $node->db_description = trim($node->db_description);
+  $node->uniquename = property_exists($node, 'uniquename') ? trim($node->uniquename) : '';
+  $node->sname = property_exists($node, 'sname') ? trim($node->sname) : '';
+  $node->stock_description = property_exists($node, 'stock_description') ? trim($node->stock_description) : '';
+  $node->accession = property_exists($node, 'accession') ? trim($node->accession) : '';
+  $node->db_description = property_exists($node, 'db_description') ? trim($node->db_description) : '';
 
   $int_in_chado_sql = "SELECT count(*) as count FROM {:table} WHERE :column = :value";
   $string_in_chado_sql = "SELECT count(*) as count FROM {:table} WHERE :column = :value";
@@ -441,17 +441,18 @@ function chado_stock_validate(&$node, $form, &$form_state) {
  */
 function chado_stock_insert($node) {
 
-  $node->uniquename   = trim($node->uniquename);
-  $node->sname        = trim($node->sname);
-  $node->accession    = trim($node->accession);
 
   $stock_id = '';
 
   // if there is an stock_id in the $node object then this must be a sync so
   // we can skip adding the stock to chado as it is already there, although
-  // we do need to proceed with the rest of the insert
+  // we do need to proceed with insertion into the chado/drupal linking table.
   if (!property_exists($node, 'stock_id')) {
 
+    $node->uniquename   = trim($node->uniquename);
+    $node->sname        = trim($node->sname);
+    $node->accession    = trim($node->accession);
+
     // before we can add the stock, we must add the dbxref if one has been
     // provided by the user.
     $dbxref = NULL;
@@ -913,4 +914,4 @@ function chado_stock_chado_node_default_title_format() {
  */
 function chado_stock_chado_node_default_url_format() {
   return '/stock/[stock.organism_id>organism.genus]/[stock.organism_id>organism.species]/[stock.type_id>cvterm.name]/[stock.uniquename]';
-}
+}