Browse Source

API: Discussed changes including moving functions between APIs and highlighting some functionality

Lacey Sanderson 11 years ago
parent
commit
7708d7db5e

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

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

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

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

+ 0 - 279
tripal_core/api/tripal_core.chado_nodes.properties.api.inc

@@ -97,285 +97,6 @@
  * @ingroup tripal_chado_node_api
  */
 
-/**
- * Retrieve a property for a given base table record
- *
- * @param $basetable
- *   The base table for which the property should be retrieved. Thus to retrieve a property
- *   for a feature the basetable=feature and property is retrieved from featureprop
- * @param $record_id
- *   The foriegn key field of the base table. This should be in integer.
- * @param $property
- *   The cvterm name describing the type of properties to be retrieved
- * @param $cv_name
- *   The name of the cv that the above cvterm is part of
- *
- * @return
- *   An array in the same format as that generated by the function
- *   chado_generate_var().  If only one record is returned it
- *   is a single object.  If more than one record is returned then it is an array
- *   of objects
- *
- * @ingroup tripal_chado_node_api
- */
-function chado_get_property($basetable, $record_id, $property, $cv_name, $property_id = FALSE) {
-  // get the foreign key for this property table
-  $table_desc = chado_get_schema($basetable . 'prop');
-  $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
-
-  // construct the array of values to be selected
-  $values = array(
-    $fkcol => $record_id,
-    'type_id' => array(
-      'cv_id' => array(
-        'name' => $cv_name,
-      ),
-      'name' => $property,
-      'is_obsolete' => 0
-    ),
-  );
-  // if we have the unique property_id make sure to add that to the values
-  if ($property_id) {
-    $property_pkey = $table_desc['primary key'][0];
-    $values[$property_pkey] = $property_id;
-  }
-  $results = chado_generate_var($basetable . 'prop', $values);
-  if ($results) {
-    $results = chado_expand_var($results, 'field', $basetable . 'prop.value');
-  }
-
-  return $results;
-}
-
-/**
- * Insert a property for a given base table.  By default if the property already
- * exists a new property is added with the next available rank.  If
- * $update_if_present argument is specified then the record will be updated if it
- * exists rather than adding a new property.
- *
- * @param $basetable
- *   The base table for which the property should be inserted. Thus to insert a property
- *   for a feature the basetable=feature and property is inserted into featureprop
- * @param $record_id
- *   The foriegn key value of the base table. This should be in integer.
- * @param $property
- *   The cvterm name describing the type of properties to be inserted
- * @param $cv_name
- *   The name of the cv that the above cvterm is part of
- * @param $value
- *   The value of the property to be inserted (can be empty)
- * @param $update_if_present
- *   A boolean indicating whether an existing record should be updated. If the
- *   property already exists and this value is not specified or is zero then
- *   a new property will be added with the next largest rank.
- *
- * @return
- *   Return True on Insert/Update and False otherwise
- *
- * @ingroup tripal_chado_node_api
- */
-function chado_insert_property($basetable, $record_id, $property,
-$cv_name, $value, $update_if_present = 0) {
-
-  // first see if the property already exists, if the user want's to update
-  // then we can do that, but otherwise we want to increment the rank and
-  // insert
-  $props = chado_get_property($basetable, $record_id, $property, $cv_name);
-  if (!is_array($props) and $props) {
-    $props = array($props);
-  }
-
-  $rank = 0;
-  if (count($props) > 0) {
-    if ($update_if_present) {
-      return chado_update_property($basetable, $record_id, $property, $cv_name, $value);
-    }
-    else {
-      // iterate through the properties returned and check to see if the
-      // property with this value already exists if not, get the largest rank
-      // and insert the same property but with this new value
-      foreach ($props as $p) {
-        if ($p->rank > $rank) {
-          $rank = $p->rank;
-        }
-        if (strcmp($p->value, $value) == 0) {
-          return TRUE;
-        }
-      }
-      // now add 1 to the rank
-      $rank++;
-    }
-  }
-
-  // make sure the cvterm exists.  Otherwise we'll get an error with
-  // prepared statements not matching
-  $values = array(
-    'cv_id' => array(
-      'name' => $cv_name,
-    ),
-    'name' => $property,
-  );
-
-  $options = array();
-  $term = chado_select_record('cvterm', array('cvterm_id'), $values, $options);
-  if (!$term or count($term) == 0) {
-    tripal_report_error('tripal_core', TRIPAL_ERROR, "Cannot find property '%prop_name' in vocabulary '%cvname'.",
-    array('%prop_name' => $property, '%cvname' => $cv_name));
-    return FALSE;
-  }
-
-  // get the foreign key for this property table
-  $table_desc = chado_get_schema($basetable . 'prop');
-  $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
-
-  // construct the array of values to be inserted
-  $values = array(
-    $fkcol => $record_id,
-    'type_id' => array(
-      'cv_id' => array(
-        'name' => $cv_name,
-      ),
-      'name' => $property,
-    ),
-    'value' => $value,
-    'rank' => $rank,
-  );
-
-  $options = array();
-  $result = chado_insert_record($basetable . 'prop', $values, $options);
-  return $result;
-}
-
-/**
- * Update a property for a given base table record and property name.  This
- * function should be used only if one record of the property will be present.
- * If the property name can have multiple entries (with increasing rank) then
- * use the function named chado_update_propertyID
- *
- * @param $basetable
- *   The base table for which the property should be updated. The property table
- *   is constructed using  a combination of the base table name and the suffix
- *   'prop' (e.g. basetable = feature then property tabie is featureprop).
- * @param $record_id
- *   The foreign key of the basetable to update a property for. This should be in integer.
- *   For example, if the basetable is 'feature' then the $record_id should be the feature_id
- * @param $property
- *   The cvterm name of property to be updated
- * @param $cv_name
- *   The name of the cv that the above cvterm is part of
- * @param $value
- *   The value of the property to be inserted (can be empty)
- * @param $insert_if_missing
- *   A boolean indicating whether a record should be inserted if one doesn't exist to update
- *
- * Note: The property to be updated is select via the unique combination of $record_id and
- * $property and then it is updated with the supplied value
- *
- * @return
- *   Return True on Update/Insert and False otherwise
- *
- * @ingroup tripal_chado_node_api
- */
-function chado_update_property($basetable, $record_id, $property,
-$cv_name, $value, $insert_if_missing = FALSE, $property_id = FALSE) {
-
-  // first see if the property is missing (we can't update a missing property
-  $prop = chado_get_property($basetable, $record_id, $property, $cv_name, $property_id);
-  if (count($prop)==0) {
-    if ($insert_if_missing) {
-      return chado_insert_property($basetable, $record_id, $property, $cv_name, $value);
-    }
-    else {
-      return FALSE;
-    }
-  }
-
-  // get the foreign key for this property table
-  $table_desc = chado_get_schema($basetable . 'prop');
-  $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
-
-  // construct the array that will match the exact record to update
-  $match = array(
-    $fkcol => $record_id,
-    'type_id' => array(
-      'cv_id' => array(
-        'name' => $cv_name,
-      ),
-      'name' => $property,
-    ),
-  );
-  // If we have the unique property_id, make sure to use it in the match to ensure
-  // we get the exact record. Doesn't rely on there only being one property of that type
-  if ($property_id) {
-    $property_pkey = $table_desc['primary key'][0];
-    $match = array(
-      $property_pkey => $property_id
-    );
-  }
-
-  // construct the array of values to be updated
-  $values = array(
-    'value' => $value,
-  );
-  // If we have the unique property_id then we can also update the type
-  // thus add it to the values to be updated
-  if ($property_id) {
-    $values['type_id'] = array(
-      'cv_id' => array(
-        'name' => $cv_name,
-      ),
-      'name' => $property,
-    );
-  }
-
-  return chado_update_record($basetable . 'prop', $match, $values);
-}
-
-/**
- * Deletes a property for a given base table record using the property name
- *
- * @param $basetable
- *   The base table for which the property should be deleted. Thus to deleted a property
- *   for a feature the basetable=feature and property is deleted from featureprop
- * @param $record_id
- *   The primary key of the basetable to delete a property for. This should be in integer.
- * @param $property
- *   The cvterm name describing the type of property to be deleted
- * @param $cv_name
- *   The name of the cv that the above cvterm is part of
- *
- * Note: The property to be deleted is select via the unique combination of $record_id and $property
- *
- * @return
- *   Return True on Delete and False otherwise
- *
- * @ingroup tripal_chado_node_api
- */
-function chado_delete_property($basetable, $record_id, $property, $cv_name) {
-
-  // get the foreign key for this property table
-  $table_desc = chado_get_schema($basetable . 'prop');
-  $fkcol = key($table_desc['foreign keys'][$basetable]['columns']);
-
-  // construct the array that will match the exact record to update
-  $match = array(
-    $fkcol => $record_id,
-    'type_id' => array(
-      'cv_id' => array(
-        'name' => $cv_name,
-      ),
-      'name' => $property,
-    ),
-  );
-
-  return chado_delete_record($basetable . 'prop', $match);
-}
-
-/**
- * @section
- * Properties Form to be added to node forms
- */
-
 /**
  * Provides a form for adding to BASEprop table
  *

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

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

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

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

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

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

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

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

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

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

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

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

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

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

+ 1 - 30
tripal_core/tripal_core.module

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