Forráskód Böngészése

Renamed branch from 7.x-1.x to 7.x-2.x. Also merged bug fixes from 6.x-1.x

spficklin 11 éve
szülő
commit
8a898014b8
41 módosított fájl, 2175 hozzáadás és 617 törlés
  1. 3 14
      README.txt
  2. 1 1
      docs/tripal_doxygen.config
  3. 16 8
      tripal_analysis/api/tripal_analysis.api.inc
  4. 47 31
      tripal_analysis/includes/tripal_analysis.form.inc
  5. 184 164
      tripal_analysis/tripal_analysis.module
  6. 0 68
      tripal_bulk_loader/includes/tripal_bulk_loader.admin.inc
  7. 0 0
      tripal_bulk_loader/includes/tripal_bulk_loader.admin.templates.inc
  8. 0 0
      tripal_bulk_loader/includes/tripal_bulk_loader.constants.inc
  9. 0 0
      tripal_bulk_loader/includes/tripal_bulk_loader.loader.inc
  10. 26 0
      tripal_bulk_loader/theme/tripal_bulk_loader_admin.tpl.php
  11. 47 22
      tripal_bulk_loader/tripal_bulk_loader.module
  12. 1 1
      tripal_contact/includes/tripal_contact.form.inc
  13. 23 8
      tripal_contact/tripal_contact.install
  14. 6 2
      tripal_contact/tripal_contact.module
  15. 1 1
      tripal_core/api/tripal_core_chado.api.inc
  16. 34 1
      tripal_cv/api/tripal_cv.api.inc
  17. 1 1
      tripal_cv/includes/trees.inc
  18. 561 0
      tripal_cv/includes/tripal_cv_admin.inc
  19. 0 32
      tripal_feature/includes/tripal_feature.admin.inc
  20. 37 103
      tripal_feature/tripal_feature.module
  21. 7 1
      tripal_featuremap/includes/tripal_featuremap.form.inc
  22. 3 3
      tripal_featuremap/tripal_featuremap.install
  23. 20 2
      tripal_featuremap/tripal_featuremap.module
  24. 7 6
      tripal_library/includes/tripal_library.admin.inc
  25. 20 1
      tripal_library/tripal_library.module
  26. 21 3
      tripal_organism/tripal_organism.module
  27. 16 12
      tripal_project/tripal_project.module
  28. 320 21
      tripal_pub/api/tripal_pub.api.inc
  29. 14 1
      tripal_pub/files/tpub.obo
  30. 43 21
      tripal_pub/includes/importers/AGL.inc
  31. 41 19
      tripal_pub/includes/importers/PMID.inc
  32. 82 0
      tripal_pub/includes/pub_citation.inc
  33. 28 7
      tripal_pub/includes/pub_form.inc
  34. 48 25
      tripal_pub/includes/pub_importers.inc
  35. 50 1
      tripal_pub/includes/tripal_pub.admin.inc
  36. 22 21
      tripal_pub/tripal_pub.install
  37. 51 3
      tripal_pub/tripal_pub.module
  38. 372 0
      tripal_pub/tripal_pub.views.inc
  39. 18 9
      tripal_stock/tripal_stock.module
  40. 1 1
      tripal_views/api/tripal_views.api.inc
  41. 3 3
      tripal_views/includes/tripal_views_integration.inc

+ 3 - 14
README.txt

@@ -40,19 +40,8 @@ Highly Recommended Modules
 
 Installation
 --------------
-1. Enable/Install the Tripal Core Module
-2. Install a Chado database
-     - Either allow Tripal to add a chado database in a separate 
-       schema to your Drupal database (recommended) by navigating to 
-       Administer -> Tripal Management -> Install Chado 
-       (admin/tripal/chado_1_11_install) and click "Install Chado" OR
-     - Edit the settings.php file to connect to an external chado 
-       database
-3. Enable/Install any other Tripal modules that are applicable to 
-   your site.
-4. Check the module page for each enabled Tripal module for further 
-   module-specific instructions and a list of features and quick 
-   links (Administer -> Tripal Managment -> [Module Name]
+Please follow the online tutorial for installation instructions:
+http://www.gmod.org/wiki/Tripal_Tutorial_v1.1
 
 
 Customization
@@ -66,7 +55,7 @@ accessing any and all data within the Chado database.
 
 Future Work
 --------------
-Currently, Tripal only supports visualization of a subset of the 
+Currently, Tripal only supports a large subset of the 
 current Chado schema, but further development is underway. Meanwhile, 
 others can use the Tripal API to develop their own extensions. Those 
 extensions can in turn be made available for anyone to use. These 

+ 1 - 1
docs/tripal_doxygen.config

@@ -31,7 +31,7 @@ PROJECT_NAME           = Tripal
 # This could be handy for archiving the generated documentation or
 # if some version control system is used.
 
-PROJECT_NUMBER         = "v1.0 (6.x-1.0)"
+PROJECT_NUMBER         = "v1.1 (6.x-1.1)"
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer

+ 16 - 8
tripal_analysis/api/tripal_analysis.api.inc

@@ -44,14 +44,16 @@ function tripal_analysis_unregister_child($modulename) {
  *    The analysis_id of the properties you would like to retrieve
  * @param $property
  *    The cvterm name of the properties to retrieve
+ * @param $cvname
+ *   The name of the vocabulary to which the term belongs. Defaults to 'tripal'.
  *
  * @return
  *    An analysis chado variable with the specified properties expanded
  *
  * @ingroup tripal_analysis_api
  */
-function tripal_analysis_get_property($analysis_id, $property) {
-  return tripal_core_get_property('analysis', $analysis_id, $property, 'tripal');
+function tripal_analysis_get_property($analysis_id, $property, $cvname = 'tripal') {
+  return tripal_core_get_property('analysis', $analysis_id, $property, $cvname);
 }
 
 /**
@@ -65,14 +67,16 @@ function tripal_analysis_get_property($analysis_id, $property) {
  *   The value of the property to insert
  * @param $update_if_present
  *   A boolean indicated whether to update the record if it's already present
+ * @param $cvname
+ *   The name of the vocabulary to which the term belongs. Defaults to 'tripal'.
  *
  * @return
  *   True of success, False otherwise
  *
  * @ingroup tripal_analysis_api
  */
-function tripal_analysis_insert_property($analysis_id, $property, $value, $update_if_present = 0) {
-    return tripal_core_insert_property('analysis', $analysis_id, $property, 'analysis_property', $value, $update_if_present);
+function tripal_analysis_insert_property($analysis_id, $property, $value, $update_if_present = 0, $cvname = 'tripal') {
+    return tripal_core_insert_property('analysis', $analysis_id, $property, $cvname, $value, $update_if_present);
 }
 
 /**
@@ -86,6 +90,8 @@ function tripal_analysis_insert_property($analysis_id, $property, $value, $updat
  *   The value of the property to update
  * @param $insert_if_missing
  *   A boolean indicated whether to insert the record if it's absent
+ * @param $cvname
+ *   The name of the vocabulary to which the term belongs. Defaults to 'tripal'.
  *
  * Note: The property will be identified using the unique combination of the $analysis_id and $property
  * and then it will be updated with the supplied value
@@ -95,8 +101,8 @@ function tripal_analysis_insert_property($analysis_id, $property, $value, $updat
  *
  * @ingroup tripal_analysis_api
  */
-function tripal_analysis_update_property($analysis_id, $property, $value, $insert_if_missing = 0) {
-  return tripal_core_update_property('analysis', $analysis_id, $property, 'tripal', $value, $insert_if_missing);
+function tripal_analysis_update_property($analysis_id, $property, $value, $insert_if_missing = 0, $cvname = 'tripal') {
+  return tripal_core_update_property('analysis', $analysis_id, $property, $cvname, $value, $insert_if_missing);
 }
 
 /**
@@ -106,6 +112,8 @@ function tripal_analysis_update_property($analysis_id, $property, $value, $inser
  *   The analysis_id of the property to delete
  * @param $property
  *   The cvterm name of the property to delete
+ * @param $cvname
+ *   The name of the vocabulary to which the term belongs. Defaults to 'tripal'.
  *
  * Note: The property will be identified using the unique combination of the $analysis_id and $property
  * and then it will be deleted
@@ -115,8 +123,8 @@ function tripal_analysis_update_property($analysis_id, $property, $value, $inser
  *
  * @ingroup tripal_analysis_api
  */
-function tripal_analysis_delete_property($analysis_id, $property) {
-  return tripal_core_delete_property('analysis', $analysis_id, $property, 'tripal');
+function tripal_analysis_delete_property($analysis_id, $property, $cvname = 'tripal') {
+  return tripal_core_delete_property('analysis', $analysis_id, $property, $cvname);
 }
 
 /**

+ 47 - 31
tripal_analysis/includes/tripal_analysis.form.inc

@@ -5,7 +5,7 @@
  *
  * @ingroup tripal_analysis
  */
-function chado_analysis_form(&$node, $form_state) {
+function chado_analysis_form(&$node, $form_state = NULL) {
   tripal_core_ahah_init_form();
   $form = array();
 
@@ -181,6 +181,25 @@ function chado_analysis_form(&$node, $form_state) {
   	$properties_select[$prop->cvterm_id] = $prop->name;
   	$properties_list[$prop->cvterm_id] = $prop;
   }
+  
+  $form['properties'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Analysis Details'),
+    '#description' => t('You may add additional 
+      properties by
+      selecting a property type from the dropdown and adding text.  You may add 
+      as many properties as desired by clicking the plus button on the right.  To 
+      remove a property, click the minus button.  If a property is not available
+      you may add it by ' . l('adding the term', 'admin/tripal/tripal_cv/cvterm/add') . '
+      to the <b>analysis_property</b> vocabulary within the <b>tripal</b> database'),
+  );
+  $form['properties']['table'] = array(
+    '#type' => 'markup',
+    '#value' =>  '',
+    '#prefix' => '<div id="tripal-analysis-edit-properties-table">',
+    '#suffix' => '</div>',
+  );
+  
   // add in the properties from the analysisprop table
   $num_properties += chado_analysis_node_form_add_analysisprop_table_props($form, $form_state, $analysis_id, $d_properties, $d_removed);
   
@@ -300,7 +319,7 @@ function tripal_analysis_validate($node, &$form) {
 function chado_analysis_node_form_add_new_empty_props(&$form, $properties_select) {
 
   // add one more blank set of property fields
-  $form['properties']['new']["new_id"] = array(
+  $form['properties']['table']['new']["new_id"] = array(
     '#type'          => 'select',
     '#options'       => $properties_select,
     '#ahah' => array(
@@ -310,14 +329,14 @@ function chado_analysis_node_form_add_new_empty_props(&$form, $properties_select
       'method'  => 'replace',          
   ),
   );
-  $form['properties']['new']["new_value"] = array(
+  $form['properties']['table']['new']["new_value"] = array(
     '#type'          => 'textarea',
     '#default_value' => '',
     '#cols'          => 5,
     '#rows'          => $rows,
     '#description'   => '<div id="tripal-analysis-new_value-desc"></div>'
     );
-    $form['properties']['new']["add"] = array(
+    $form['properties']['table']['new']["add"] = array(
     '#type'         => 'image_button',      
     '#value'        => t('Add'),
     '#src'          => drupal_get_path('theme', 'tripal') . '/images/add.png',
@@ -371,11 +390,11 @@ function chado_analysis_node_form_add_new_props(&$form, $form_state, &$d_propert
 
 
         // add the new fields
-        $form['properties']['new'][$new_id][$rank]["new_id-$new_id-$rank"] = array(
+        $form['properties']['table']['new'][$new_id][$rank]["new_id-$new_id-$rank"] = array(
           '#type'          => 'item',
           '#value'         => $cvterm[0]->name
         );
-        $form['properties']['new'][$new_id][$rank]["new_value-$new_id-$rank"] = array(
+        $form['properties']['table']['new'][$new_id][$rank]["new_value-$new_id-$rank"] = array(
           '#type'          => 'textarea',
           '#default_value' => $value,
           '#cols'          => 50,
@@ -383,7 +402,7 @@ function chado_analysis_node_form_add_new_props(&$form, $form_state, &$d_propert
           '#description'   => $cvterm->definition,
         );
 
-        $form['properties']['new'][$new_id][$rank]["remove-$new_id-$rank"] = array(
+        $form['properties']['table']['new'][$new_id][$rank]["remove-$new_id-$rank"] = array(
           '#type'         => 'image_button',
           '#value'        => t('Remove'),
           '#src'          => drupal_get_path('theme', 'tripal') . '/images/minus.png',
@@ -422,11 +441,11 @@ function chado_analysis_node_form_add_new_props(&$form, $form_state, &$d_propert
     $rows = 1;
 
     // add the new fields
-    $form['properties']['new'][$new_id][$rank]["new_id-$new_id-$rank"] = array(
+    $form['properties']['table']['new'][$new_id][$rank]["new_id-$new_id-$rank"] = array(
       '#type'          => 'item',
       '#value'         => $cvterm[0]->name
     );
-    $form['properties']['new'][$new_id][$rank]["new_value-$new_id-$rank"] = array(
+    $form['properties']['table']['new'][$new_id][$rank]["new_value-$new_id-$rank"] = array(
       '#type'          => 'textarea',
       '#default_value' => $new_value,
       '#cols'          => 50,
@@ -434,7 +453,7 @@ function chado_analysis_node_form_add_new_props(&$form, $form_state, &$d_propert
       '#description'   => $cvterm->definition,
     );
 
-    $form['properties']['new'][$new_id][$rank]["remove-$new_id-$rank"] = array(
+    $form['properties']['table']['new'][$new_id][$rank]["remove-$new_id-$rank"] = array(
       '#type'         => 'image_button',
       '#value'        => t('Remove'),
       '#src'          => drupal_get_path('theme', 'tripal') . '/images/minus.png',
@@ -467,7 +486,8 @@ function chado_analysis_node_form_add_analysisprop_table_props(&$form, $form_sta
     SELECT CVT.cvterm_id, CVT.name, CVT.definition, PP.value, PP.rank
     FROM {analysisprop} PP
       INNER JOIN {cvterm} CVT on CVT.cvterm_id = PP.type_id
-    WHERE PP.analysis_id = %d
+      INNER JOIN {cv} CV on CVT.cv_id = CV.cv_id
+    WHERE PP.analysis_id = %d and CV.name = 'analysis_property'
     ORDER BY CVT.name, PP.rank
   ";
   $analysis_props = chado_query($sql, $analysis_id);
@@ -492,11 +512,11 @@ function chado_analysis_node_form_add_analysisprop_table_props(&$form, $form_sta
     $d_properties[$type_id][$rank]['definition']  = $prop->definition;
     $num_properties++;
 
-    $form['properties'][$type_id][$rank]["prop_id-$type_id-$rank"] = array(
+    $form['properties']['table'][$type_id][$rank]["prop_id-$type_id-$rank"] = array(
       '#type'          => 'item',
       '#value'         => $prop->name,
     );
-    $form['properties'][$type_id][$rank]["prop_value-$type_id-$rank"] = array(
+    $form['properties']['table'][$type_id][$rank]["prop_value-$type_id-$rank"] = array(
       '#type'          => 'textarea',
       '#default_value' => $prop->value,
       '#cols'          => 50,
@@ -504,7 +524,7 @@ function chado_analysis_node_form_add_analysisprop_table_props(&$form, $form_sta
       '#description'   => $prop->definition,
     );
 
-    $form['properties'][$type_id][$rank]["remove-$type_id-$rank"] = array(
+    $form['properties']['table'][$type_id][$rank]["remove-$type_id-$rank"] = array(
       '#type'         => 'image_button',
       '#value'        => t('Remove'),
       '#src'          => drupal_get_path('theme', 'tripal') . '/images/minus.png',
@@ -529,8 +549,8 @@ function tripal_analysis_theme_node_form_properties($form) {
 
     // first add in the properties derived from the analysisprop table
     // the array tree for these properties looks like this:
-    // $form['properties'][$type_id][$rank]["prop_id-$type_id-$rank"]
-    foreach ($form['properties'] as $type_id => $elements) {
+    // $form['properties']['table'][$type_id][$rank]["prop_id-$type_id-$rank"]
+    foreach ($form['properties']['table'] as $type_id => $elements) {
       // there are other fields in the properties array so we only
       // want the numeric ones those are our type_id
       if (is_numeric($type_id)) {
@@ -548,8 +568,8 @@ function tripal_analysis_theme_node_form_properties($form) {
 
     // second, add in any new properties added by the user through AHAH callbacks
     // the array tree for these properties looks like this:
-    // $form['properties']['new'][$type_id][$rank]["new_id-$new_id-$rank"]
-    foreach ($form['properties']['new'] as $type_id => $elements) {
+    // $form['properties']['table']['new'][$type_id][$rank]["new_id-$new_id-$rank"]
+    foreach ($form['properties']['table']['new'] as $type_id => $elements) {
       if (is_numeric($type_id)) {
         foreach ($elements as $rank => $element) {
           if (is_numeric($rank)) {
@@ -565,14 +585,14 @@ function tripal_analysis_theme_node_form_properties($form) {
 
     // finally add in a set of blank field for adding a new property
     $rows[] = array(
-    drupal_render($form['properties']['new']['new_id']),
-    drupal_render($form['properties']['new']['new_value']),
-    drupal_render($form['properties']['new']['add']),
+    drupal_render($form['properties']['table']['new']['new_id']),
+    drupal_render($form['properties']['table']['new']['new_value']),
+    drupal_render($form['properties']['table']['new']['add']),
     );
   }
 
   $headers = array('Property Type','Value', '');
-  return theme('table', $headers, $rows, array('id'=> "tripal-analysis-edit-properties-table"));
+  return theme('table', $headers, $rows);
 }
 
 /*
@@ -593,11 +613,11 @@ function tripal_analysis_property_add() {
 
   // return the updated JSON
   drupal_json(
-  array(
+    array(
       'status'   => $status, 
       'data'     => $data,
       'settings' => $settings,
-  )
+    )
   );
 }
 /*
@@ -651,17 +671,13 @@ function tripal_analysis_property_get_description() {
 function theme_chado_analysis_node_form($form) {
 
   $properties_table = tripal_analysis_theme_node_form_properties($form);
-
-  $markup  = drupal_render($form['analysis_id']);
-  $markup .= drupal_render($form['title']);
-  $markup .= drupal_render($form['type_id']);
-  $markup .= drupal_render($form['description']);
-  $markup .= "<b>Include Additional Details</b><br>You may add additional properties to this analysis by scrolling to the bottom of this table, selecting a property type from the dropdown and adding text.  You may add as many properties as desired by clicking the plus button on the right.  To remove a property, click the minus button";
   $markup .= $properties_table;
 
-  $form['properties'] = array(
+  $form['properties']['table'] = array(
     '#type' => 'markup',
     '#value' =>  $markup,
+    '#prefix' => '<div id="tripal-analysis-edit-properties-table">',
+    '#suffix' => '</div>',
   );
   $form['buttons']['#weight'] = 50;
   return drupal_render($form);

+ 184 - 164
tripal_analysis/tripal_analysis.module

@@ -139,28 +139,28 @@ function chado_analysis_insert($node) {
   
   // If the analysis doesn't exist then let's create it in chado.
   if (!$analysis) {
-      // insert and then get the newly inserted analysis record
-      $values = array(
-          'name' => $node->analysisname,
-          'description' => $node->description,
-          'program' => $node->program,
-          'programversion' => $node->programversion,
-          'algorithm' => $node->algorithm,
-          'sourcename' => $node->sourcename,
-          'sourceversion' => $node->sourceversion,
-          'sourceuri' => $node->sourceuri,
-          'timeexecuted' => $timestamp
-      );
-      if (tripal_core_chado_insert('analysis', $values)) {
-        $analysis = tripal_core_chado_select('analysis', array('*'), $values);
-        $analysis_id = $analysis[0]->analysis_id;
-      }
+    // insert and then get the newly inserted analysis record
+    $values = array(
+      'name' => $node->analysisname,
+      'description' => $node->description,
+      'program' => $node->program,
+      'programversion' => $node->programversion,
+      'algorithm' => $node->algorithm,
+      'sourcename' => $node->sourcename,
+      'sourceversion' => $node->sourceversion,
+      'sourceuri' => $node->sourceuri,
+      'timeexecuted' => $timestamp
+    );
+    if (tripal_core_chado_insert('analysis', $values)) {
+      $analysis = tripal_core_chado_select('analysis', array('*'), $values);
+      $analysis_id = $analysis[0]->analysis_id;
+    }
   }
 
   // Make sure the entry for this analysis doesn't already exist in the
   // chado_analysis table if it doesn't exist then we want to add it.
   $node_check_sql = "SELECT * FROM {chado_analysis} ".
-                     "WHERE analysis_id = %d";
+                    "WHERE analysis_id = %d";
   $node_check = db_fetch_object(db_query($node_check_sql, $analysis_id));
   if (!$node_check) {
     // next add the item to the drupal table
@@ -184,16 +184,16 @@ function chado_analysis_insert($node) {
     drupal_write_record('node_revisions', $record, 'nid');
   }
 
-   // add the analysis to the node object for
-   // use by other analysis modules that may be using this function
-    $node->analysis = $analysis;
-    $node->analysis_id = $analysis_id; // we need to set this for children
+  // add the analysis to the node object for
+  // use by other analysis modules that may be using this function
+  $node->analysis = $analysis;
+  $node->analysis_id = $analysis_id; // we need to set this for children
     
-    // now add the properties
-    $properties = array(); // stores all of the properties we need to add    
-    // get the list of properties for easy lookup (without doing lots of database queries
-    $properties_list = array();
-    $sql = "
+  // now add the properties
+  $properties = array(); // stores all of the properties we need to add    
+  // get the list of properties for easy lookup (without doing lots of database queries
+  $properties_list = array();
+  $sql = "
       SELECT DISTINCT CVT.cvterm_id, CVT.name, CVT.definition
       FROM  {cvterm} CVT
         INNER JOIN {cv} ON CVT.cv_id = CV.cv_id
@@ -201,40 +201,40 @@ function chado_analysis_insert($node) {
         CV.name = 'analysis_property' AND
         NOT CVT.is_obsolete = 1
       ORDER BY CVT.name ASC
-    ";
-    $prop_types = chado_query($sql);
-    while ($prop = db_fetch_object($prop_types)) {
-    	$properties_list[$prop->cvterm_id] = $prop->name;
-    }
+  ";
+  $prop_types = chado_query($sql);
+  while ($prop = db_fetch_object($prop_types)) {
+    $properties_list[$prop->cvterm_id] = $prop->name;
+  }
     
-    // get the properties that should be added. Properties are in one of two forms:
-    //  1) prop_value-[type id]-[index]
-    //  2) new_value-[type id]-[index]
-    //  3) new_id, new_value
-
-    foreach ($node as $name => $value) {
-    	if (preg_match('/^new_value-(\d+)-(\d+)/', $name, $matches)) {
-    		$type_id = $matches[1];
-    		$index = $matches[2];
-    		$name = $properties_list[$type_id];
-    		$properties[$name][$index] = trim($value);
-    	}
-    }
+  // get the properties that should be added. Properties are in one of two forms:
+  //  1) prop_value-[type id]-[index]
+  //  2) new_value-[type id]-[index]
+  //  3) new_id, new_value
+
+  foreach ($node as $name => $value) {
+    if (preg_match('/^new_value-(\d+)-(\d+)/', $name, $matches)) {
+        $type_id = $matches[1];
+        $index = $matches[2];
+        $name = $properties_list[$type_id];
+        $properties[$name][$index] = trim($value);
+      }
+  }
     if ($node->new_id and $node->new_value) {
-    	$type_id = $node->new_id;
-    	$name = $properties_list[$type_id];
-    	$index = count($properties[$name]);
-    	$properties[$name][$index] = trim($node->new_value);
+      $type_id = $node->new_id;
+      $name = $properties_list[$type_id];
+      $index = count($properties[$name]);
+      $properties[$name][$index] = trim($node->new_value);
     }
     // now add in the properties
     foreach ($properties as $property => $elements) {
       foreach ($elements as $rank => $value) {
-    	  $status = tripal_analysis_insert_property($analysis_id, $property, $value, FALSE);
+        $status = tripal_analysis_insert_property($analysis_id, $property, $value, FALSE, 'analysis_property');
         if (!$status) {
             drupal_set_message("Error cannot add property: $property", "error");
             watchdog('t_analysis', "Error cannot add property: %prop",
               array('%property' => $property), WATCHDOG_ERROR);
-    		}
+        }
       }
     }
 }
@@ -283,113 +283,113 @@ function chado_analysis_delete($node) {
  * @ingroup tripal_analysis
  */
 function chado_analysis_update($node) {
-	global $user;
-	if ($node->revision) {
-		// TODO -- decide what to do about revisions
-	}
-	// Create a timestamp so we can insert it into the chado database
-	$time = $node->timeexecuted;
-	$month = $time['month'];
-	$day = $time['day'];
-	$year = $time['year'];
-	$timestamp = $month . '/' . $day . '/' . $year;
-
-	// get the analysis_id for this node:
-	$sql = "SELECT analysis_id ".
-			"FROM {chado_analysis} ".
-			"WHERE nid = %d";
-	$analysis_id = db_fetch_object(db_query($sql, $node->nid))->analysis_id;
-
-	$sql = "UPDATE {analysis} ".
-			"SET name = '%s', ".
-			"    description = '%s', ".
-			"    program = '%s', ".
-			"    programversion = '%s', ".
-			"    algorithm = '%s', ".
-			"    sourcename = '%s', ".
-			"    sourceversion = '%s', ".
-			"    sourceuri = '%s', ".
-			"    timeexecuted = '%s' ".
-			"WHERE analysis_id = %d ";
-
-	chado_query($sql, $node->analysisname, $node->description, $node->program,
-	$node->programversion, $node->algorithm, $node->sourcename,
-	$node->sourceversion, $node->sourceuri, $timestamp, $analysis_id);
-
-	// Create a title for the analysis node using the unique keys so when the
-	// node is saved, it will have a title
-	$record = new stdClass();
-	// If the analysis has a name, use it as the node title. If not, construct
-	// the title using program, programversion, and sourcename
-	if ($node->analysisname) {
-		$record->title = $node->analysisname;
-	}
-	else {
-		//Construct node title as "program (version)
-		$record->title = "$node->program ($node->programversion)";
-	}
-
-	$record->nid = $node->nid;
-	drupal_write_record('node', $record, 'nid');
-	drupal_write_record('node_revisions', $record, 'nid');
-
-	// now update the properties
-	$properties = array(); // stores all of the properties we need to add
-	// get the list of properties for easy lookup (without doing lots of database queries
-	$properties_list = array();
-	$sql = "
-			SELECT DISTINCT CVT.cvterm_id, CVT.name, CVT.definition
-			FROM  {cvterm} CVT
-			INNER JOIN {cv} ON CVT.cv_id = CV.cv_id
-			WHERE
-			CV.name = 'analysis_property' AND
-			NOT CVT.is_obsolete = 1
-			ORDER BY CVT.name ASC
-			";
-	$prop_types = chado_query($sql);
-	while ($prop = db_fetch_object($prop_types)) {
-		$properties_list[$prop->cvterm_id] = $prop->name;
-	}
-
-	// get the properties that should be added. Properties are in one of three forms:
-	//  1) prop_value-[type id]-[index]
-	//  2) new_value-[type id]-[index]
-	//  3) new_id, new_value
-	//  dpm($node);
-	foreach ($node as $key => $value) {
-		if (preg_match('/^prop_value-(\d+)-(\d+)/', $key, $matches)) {
-			$type_id = $matches[1];
-			$index = $matches[2];
-			$name = $properties_list[$type_id];
-			$properties[$name][$index] = trim($value);
-		}
-		if (preg_match('/^new_value-(\d+)-(\d+)/', $key, $matches)) {
-			$type_id = $matches[1];
-			$index = $matches[2];
-			$name = $properties_list[$type_id];
-			$properties[$name][$index] = trim($value);
-		}
-	}
-	if ($node->new_id and $node->new_value) {
-		$type_id = $node->new_id;
-		$name = $properties_list[$type_id];
-		$index = count($properties[$name]);
-		$properties[$name][$index] = trim($node->new_value);
-	}
-
-	// now add in the properties by first removing any the analysis
-	// already has and adding the ones we have
-	tripal_core_chado_delete('analysisprop', array('analysis_id' => $analysis_id));
-	foreach ($properties as $property => $elements) {
-		foreach ($elements as $rank => $value) {
-			$status = tripal_analysis_insert_property($analysis_id, $property, $value, FALSE);
-			if (!$status) {
-				drupal_set_message("Error cannot add property: '$property'", "error");
-				watchdog('t_analysis', "Error cannot add property: '%prop'",
-				array('%prop' => $property), WATCHDOG_ERROR);
-			}
-		}
-	}
+  global $user;
+  if ($node->revision) {
+    // TODO -- decide what to do about revisions
+  }
+  // Create a timestamp so we can insert it into the chado database
+  $time = $node->timeexecuted;
+  $month = $time['month'];
+  $day = $time['day'];
+  $year = $time['year'];
+  $timestamp = $month . '/' . $day . '/' . $year;
+
+  // get the analysis_id for this node:
+  $sql = "SELECT analysis_id ".
+      "FROM {chado_analysis} ".
+      "WHERE nid = %d";
+  $analysis_id = db_fetch_object(db_query($sql, $node->nid))->analysis_id;
+
+  $sql = "UPDATE {analysis} ".
+      "SET name = '%s', ".
+      "    description = '%s', ".
+      "    program = '%s', ".
+      "    programversion = '%s', ".
+      "    algorithm = '%s', ".
+      "    sourcename = '%s', ".
+      "    sourceversion = '%s', ".
+      "    sourceuri = '%s', ".
+      "    timeexecuted = '%s' ".
+      "WHERE analysis_id = %d ";
+
+  chado_query($sql, $node->analysisname, $node->description, $node->program,
+  $node->programversion, $node->algorithm, $node->sourcename,
+  $node->sourceversion, $node->sourceuri, $timestamp, $analysis_id);
+
+  // Create a title for the analysis node using the unique keys so when the
+  // node is saved, it will have a title
+  $record = new stdClass();
+  // If the analysis has a name, use it as the node title. If not, construct
+  // the title using program, programversion, and sourcename
+  if ($node->analysisname) {
+    $record->title = $node->analysisname;
+  }
+  else {
+    //Construct node title as "program (version)
+    $record->title = "$node->program ($node->programversion)";
+  }
+
+  $record->nid = $node->nid;
+  drupal_write_record('node', $record, 'nid');
+  drupal_write_record('node_revisions', $record, 'nid');
+
+  // now update the properties
+  $properties = array(); // stores all of the properties we need to add
+  // get the list of properties for easy lookup (without doing lots of database queries
+  $properties_list = array();
+  $sql = "
+      SELECT DISTINCT CVT.cvterm_id, CVT.name, CVT.definition
+      FROM  {cvterm} CVT
+      INNER JOIN {cv} ON CVT.cv_id = CV.cv_id
+      WHERE
+      CV.name = 'analysis_property' AND
+      NOT CVT.is_obsolete = 1
+      ORDER BY CVT.name ASC
+      ";
+  $prop_types = chado_query($sql);
+  while ($prop = db_fetch_object($prop_types)) {
+    $properties_list[$prop->cvterm_id] = $prop->name;
+  }
+
+  // get the properties that should be added. Properties are in one of three forms:
+  //  1) prop_value-[type id]-[index]
+  //  2) new_value-[type id]-[index]
+  //  3) new_id, new_value
+  //  dpm($node);
+  foreach ($node as $key => $value) {
+    if (preg_match('/^prop_value-(\d+)-(\d+)/', $key, $matches)) {
+      $type_id = $matches[1];
+      $index = $matches[2];
+      $name = $properties_list[$type_id];
+      $properties[$name][$index] = trim($value);
+    }
+    if (preg_match('/^new_value-(\d+)-(\d+)/', $key, $matches)) {
+      $type_id = $matches[1];
+      $index = $matches[2];
+      $name = $properties_list[$type_id];
+      $properties[$name][$index] = trim($value);
+    }
+  }
+  if ($node->new_id and $node->new_value) {
+    $type_id = $node->new_id;
+    $name = $properties_list[$type_id];
+    $index = count($properties[$name]);
+    $properties[$name][$index] = trim($node->new_value);
+  }
+
+  // now add in the properties by first removing any the analysis
+  // already has and adding the ones we have
+  tripal_core_chado_delete('analysisprop', array('analysis_id' => $analysis_id));
+  foreach ($properties as $property => $elements) {
+    foreach ($elements as $rank => $value) {
+      $status = tripal_analysis_insert_property($analysis_id, $property, $value, FALSE, 'analysis_property');
+      if (!$status) {
+        drupal_set_message("Error cannot add property: '$property'", "error");
+        watchdog('t_analysis', "Error cannot add property: '%prop'",
+        array('%prop' => $property), WATCHDOG_ERROR);
+      }
+    }
+  }
 }
 
  /**
@@ -461,8 +461,25 @@ function tripal_analysis_help($path, $arg) {
 }
 
 /**
- *  The following function proves access control for users trying to
- *  perform actions on data managed by this module
+ * Implement hook_access().
+ *
+ * This hook allows node modules to limit access to the node types they define.
+ *
+ *  @param $op
+ *  The operation to be performed
+ *
+ *  @param $node
+ *  The node on which the operation is to be performed, or, if it does not yet exist, the
+ *  type of node to be created
+ *
+ *  @param $account
+ *  A user object representing the user for whom the operation is to be performed
+ *
+ *  @return
+ *  If the permission for the specified operation is not set then return FALSE. If the
+ *  permission is set then return NULL as this allows other modules to disable
+ *  access.  The only exception is when the $op == 'create'.  We will always 
+ *  return TRUE if the permission is set.
  *
  * @ingroup tripal_analysis
  */
@@ -471,7 +488,8 @@ function chado_analysis_access($op, $node, $account) {
   if ($op == 'create') {
     if (!user_access('create chado_analysis content', $account)) {
       return FALSE;
-      }
+    }
+    return TRUE;
   }
   if ($op == 'update') {
     if (!user_access('edit chado_analysis content', $account)) {
@@ -516,7 +534,7 @@ function tripal_analysis_perm() {
  * @ingroup tripal_analysis
  */
 function tripal_analysis_theme() {
-  return array(
+  $items = array(
     'tripal_analysis_base' => array(
        'arguments' => array('node' => NULL),
        'template' => 'tripal_analysis_base',
@@ -530,14 +548,16 @@ function tripal_analysis_theme() {
       'arguments' =>  array(NULL),  
       'path' => drupal_get_path('module', 'tripal_analysis') . '/theme', 
     ),
-  	 'tripal_analysis_properties' => array(
-  				'arguments' => array('node' => NULL)
-  	 ),
+     'tripal_analysis_properties' => array(
+     'arguments' => array('node' => NULL)
+    ),
     // Themed Forms
     'chado_analysis_node_form' => array(
       'arguments' => array('form'),
     ),
   );
+  
+  return $items;
 }
 /**
  *

+ 0 - 68
tripal_bulk_loader/tripal_bulk_loader.admin.inc → tripal_bulk_loader/includes/tripal_bulk_loader.admin.inc

@@ -5,75 +5,7 @@
  * Bulk Loader Administration (Miscellaneous)
  */
 
-/**
- * Provides a description page and quick links for the bulk loader
- *
- * @ingroup tripal_bulk_loader
- */
-function tripal_bulk_loader_admin_template() {
-  $output = '';
 
-  $output .= '<br /><h3>Quick Links:</h3>';
-  $output .= '<ul>'
-    . '<li>'
-      . t('<a href="@link">Configure settings</a>',
-        array('@link' => url('admin/tripal/tripal_bulk_loader_template/configure')))
-      . '</li>'
-    . '<li>'
-      . t('List <a href="@link">Bulk Loader Jobs</a>',
-      array('@link' => url('admin/tripal/tripal_bulk_loader_template/jobs')))
-      . '</li>'
-    . '<li>'
-      . t('List <a href="@link">Manage Templates</a>',
-      array('@link' => url('admin/tripal/tripal_bulk_loader_template/manage_templates')))
-      . '</li>'
-      . '<ul>'
-      . '<li>'
-        . t('<a href="@create">Create</a> a new template',
-        array('@create' => url('admin/tripal/tripal_bulk_loader_template/manage_templates/create')))
-        . '</li>'
-      . '<li>'
-        . t('<a href="@edit">Edit</a> an existing template',
-        array('@edit' => url('admin/tripal/tripal_bulk_loader_template/manage_templates/edit')))
-        . '</li>'
-      . '<li>'
-        . t('<a href="@delete">Delete</a> an existing template',
-        array('@delete' => url('admin/tripal/tripal_bulk_loader_template/manage_templates/delete')))
-        . '</li>'
-      . '<li>'
-        . t('<a href="@import">Import</a> a new template',
-        array('@import' => url('admin/tripal/tripal_bulk_loader_template/manage_templates/import')))
-        . '</li>'
-      . '<li>'
-        . t('<a href="@export">Export</a> an existing template',
-        array('@export' => url('admin/tripal/tripal_bulk_loader_template/manage_templates/export')))
-        . '</li>'
-      . '</ul>'
-    . '</ul>';
-
-  $output .= '<h3>Module Description:</h3>';
-  $output .= '<p>This module provides the ability to create loading templates for any tab-delimited '
-    . 'data file allowing it to be loaded into chado. The Loading Templates are a direct mapping '
-    . 'between the columns in your file and the columns in chado tables. As such to use this tool '
-    . 'you need to be very familar with the chado schema -See '
-    . l(t('Chado -Getting Started'), 'http://gmod.org/wiki/Chado_-_Getting_Started')
-    . '. The ability to add constants and specify foreign key contraints is also provided '
-    . 'in order for the loader to fill chado columns which may be required but are not specified '
-    . 'in your input file.</p>';
-  $output .= '<br />';
-
-  $output .= '<h3>Setup Instructions</h3>';
-  $output .= '<p>After intallation of the bulk loader module, the following tasks should be performed:</p>';
-  $output .= '<ol>';
-  $output .= '<li><b>Install Theme:</b> In order for Bulk Loading pages to be displayed correctly, '
-    .'the contents of the Tripal Bulk Loader theme directory ([drupal root]/sites/all/modules/tripal/tripal_bulk_loader/theme) '
-    .'should be moved to the base directory of the Tripal theme ([drupal root]/sites/all/themes/tripal). '
-    .'Finally the drupal cache should be cleared for the new theme to take effect -navigate to admin/settings/performance '
-    .'and click the Clear Cached Data button.</li>';
-  $output .= '</ol>';
-
-  return $output;
-}
 
 /**
  * Provides a description page and quick links for template management

+ 0 - 0
tripal_bulk_loader/tripal_bulk_loader.admin.templates.inc → tripal_bulk_loader/includes/tripal_bulk_loader.admin.templates.inc


+ 0 - 0
tripal_bulk_loader/tripal_bulk_loader.constants.inc → tripal_bulk_loader/includes/tripal_bulk_loader.constants.inc


+ 0 - 0
tripal_bulk_loader/tripal_bulk_loader.loader.inc → tripal_bulk_loader/includes/tripal_bulk_loader.loader.inc


+ 26 - 0
tripal_bulk_loader/theme/tripal_bulk_loader_admin.tpl.php

@@ -0,0 +1,26 @@
+<h3>Quick Links:</h3>
+<ul>
+  <li><?php print l('Configure settings', 'admin/tripal/tripal_bulk_loader_template/configure') ?></li>
+  <li><?php print l('List Bulk Loader Jobs', 'admin/tripal/tripal_bulk_loader_template/jobs') ?></li>
+  <li><?php print l('Manage Templates', 'admin/tripal/tripal_bulk_loader_template/manage_templates')?>
+    <ul>
+      <li><?php print l('Create a new template', 'admin/tripal/tripal_bulk_loader_template/manage_templates/create')?></li>
+      <li><?php print l('Edit an existing template', 'admin/tripal/tripal_bulk_loader_template/manage_templates/edit')?></li>
+      <li><?php print l('Delete an existing template', 'admin/tripal/tripal_bulk_loader_template/manage_templates/delete')?></li>        
+      <li><?php print l('Import a new template', 'admin/tripal/tripal_bulk_loader_template/manage_templates/import')?></li>
+      <li><?php print l('Export an existing template', 'admin/tripal/tripal_bulk_loader_template/manage_templates/export')?></li>
+    </ul>
+  </li>
+</ul>
+<br>
+<h3>Module Description:</h3>
+<p>This module allows you to create loading templates for any tab-delimited 
+   data file which can be used repetitively for loading data into chado. The Loading Templates are a direct mapping 
+   between the columns in your file and the columns in chado tables. To use this tool 
+   you need to be very familar with the chado schema -See 
+   <?php  l(t('Chado -Getting Started'), 'http://gmod.org/wiki/Chado_-_Getting_Started') ?>.
+   The ability to add constants and specify values via foreign key contraints is also provided 
+   in order for the loader to fill chado columns which may be required but are not specified 
+   in your input file.
+</p>
+<br />

+ 47 - 22
tripal_bulk_loader/tripal_bulk_loader.module

@@ -6,10 +6,10 @@
  * @defgroup tripal_bulk_loader Tripal Bulk Loader Module
  * @ingroup tripal_modules
  */
-include('tripal_bulk_loader.loader.inc');
-include('tripal_bulk_loader.constants.inc');
-include('tripal_bulk_loader.admin.inc');
-include('tripal_bulk_loader.admin.templates.inc');
+include('includes/tripal_bulk_loader.loader.inc');
+include('includes/tripal_bulk_loader.constants.inc');
+include('includes/tripal_bulk_loader.admin.inc');
+include('includes/tripal_bulk_loader.admin.templates.inc');
 
 // API
 include('api/tripal_bulk_loader.api.templates.inc');
@@ -39,7 +39,7 @@ function tripal_bulk_loader_menu() {
     'description' => 'Edit a group of constants associated with the current bulk loader',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_bulk_loader_edit_constant_set_form', 1, 3),
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_CALLBACK,
   );
   $items['node/%node/constants/%/delete'] = array(
@@ -47,7 +47,7 @@ function tripal_bulk_loader_menu() {
     'description' => 'Delete a group of constants associated with the current bulk loader',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_bulk_loader_delete_constant_set_form', 1, 3),
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_CALLBACK,
   );
 
@@ -55,8 +55,9 @@ function tripal_bulk_loader_menu() {
   $items['admin/tripal/tripal_bulk_loader_template'] = array(
     'title' => 'Bulk Loader',
     'description' => 'Templates for loading tab-delimited data',
-    'page callback' => 'tripal_bulk_loader_admin_template',
-    'access arguments' => array('administer site configuration'),
+    'page callback' => 'theme',
+    'page arguments' => array('tripal_bulk_loader_admin'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_NORMAL_ITEM,
   );
   $items['admin/tripal/tripal_bulk_loader_template/configure'] = array(
@@ -64,21 +65,21 @@ function tripal_bulk_loader_menu() {
     'description' => 'Configuration of global options related to bulk loading jobs',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_bulk_loader_configuration_form'),
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_NORMAL_ITEM,
   );
   $items['admin/tripal/tripal_bulk_loader_template/manage_templates'] = array(
     'title' => 'Manage Templates',
     'description' => 'Create/Update/Delete/Import/Export Templates',
     'page callback' => 'tripal_bulk_loader_admin_manage_templates',
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_NORMAL_ITEM,
   );
   $items['admin/tripal/tripal_bulk_loader_template/jobs'] = array(
     'title' => 'Bulk Loader Jobs',
     'description' => 'Listing of Bulk Loading Jobs',
     'page callback' => 'tripal_bulk_loader_admin_jobs',
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_NORMAL_ITEM,
   );
 
@@ -88,7 +89,7 @@ function tripal_bulk_loader_menu() {
     'description' => 'Create loader template for loading tab-delimited data',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_bulk_loader_modify_template_base_form', 'create'),
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_NORMAL_ITEM,
   );
   $items['admin/tripal/tripal_bulk_loader_template/manage_templates/edit'] = array(
@@ -96,7 +97,7 @@ function tripal_bulk_loader_menu() {
     'description' => 'Edit loader template for loading tab-delimited data',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_bulk_loader_modify_template_base_form', 'edit'),
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_NORMAL_ITEM,
   );
   $items['admin/tripal/tripal_bulk_loader_template/edit_record'] = array(
@@ -104,7 +105,7 @@ function tripal_bulk_loader_menu() {
     'description' => 'Edit a record in an existing tripal bulk loader template.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_bulk_loader_edit_template_record_form'),
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_CALLBACK,
   );
   $items['admin/tripal/tripal_bulk_loader_template/add_field'] = array(
@@ -112,7 +113,7 @@ function tripal_bulk_loader_menu() {
     'description' => 'Add a template field to an existing tripal bulk loader template.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_bulk_loader_add_template_field_form'),
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_CALLBACK,
   );
   $items['admin/tripal/tripal_bulk_loader_template/edit_field'] = array(
@@ -120,7 +121,7 @@ function tripal_bulk_loader_menu() {
     'description' => 'Edit an existing field from a tripal bulk loader template.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_bulk_loader_edit_template_field_form'),
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_CALLBACK,
   );
   // Delete Template -----
@@ -129,7 +130,7 @@ function tripal_bulk_loader_menu() {
     'description' => 'Delete bulk loader template',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_bulk_loader_delete_template_base_form'),
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_NORMAL_ITEM,
   );
   // Import/Export ---------
@@ -138,7 +139,7 @@ function tripal_bulk_loader_menu() {
     'description' => 'Import Loaders',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_bulk_loader_import_export_template_form', 'import'),
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_NORMAL_ITEM,
   );
   $items['admin/tripal/tripal_bulk_loader_template/manage_templates/export'] = array(
@@ -146,18 +147,18 @@ function tripal_bulk_loader_menu() {
     'description' => 'Export Loaders',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_bulk_loader_import_export_template_form', 'export'),
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_NORMAL_ITEM,
   );
   // AHAH ---------
   $items['admin/tripal/tripal_bulk_loader_template/add_field_ahah'] = array(
     'page callback' => 'tripal_bulk_loader_add_field_ahah',
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_CALLBACK,
   );
   $items['admin/tripal/tripal_bulk_loader_template/edit_field_ahah'] = array(
     'page callback' => 'tripal_bulk_loader_edit_field_ahah',
-    'access arguments' => array('administer site configuration'),
+    'access arguments' => array('administer tripal_bulk_loader'),
     'type' => MENU_CALLBACK,
   );
 
@@ -191,12 +192,34 @@ function tripal_bulk_loader_theme() {
       'arguments' => array('form' => NULL),
       'template' => 'tripal_bulk_loader_add_template_field_form',
     ),
+    'tripal_bulk_loader_admin' => array(
+      'template' => 'tripal_bulk_loader_admin',
+      'arguments' =>  array(NULL),
+      'path' => drupal_get_path('module', 'tripal_bulk_loader') . '/theme'
+    ),
   );
 }
 
 /**
- *  Implements hook_access
+ * Implement hook_access().
+ *
+ * This hook allows node modules to limit access to the node types they define.
+ *
+ *  @param $op
+ *  The operation to be performed
+ *
+ *  @param $node
+ *  The node on which the operation is to be performed, or, if it does not yet exist, the
+ *  type of node to be created
+ *
+ *  @param $account
+ *  A user object representing the user for whom the operation is to be performed
  *
+ *  @return
+ *  If the permission for the specified operation is not set then return FALSE. If the
+ *  permission is set then return NULL as this allows other modules to disable
+ *  access.  The only exception is when the $op == 'create'.  We will always 
+ *  return TRUE if the permission is set.
  * @ingroup tripal_bulk_loader
  */
 function tripal_bulk_loader_access($op, $node, $account) {
@@ -204,6 +227,7 @@ function tripal_bulk_loader_access($op, $node, $account) {
     if (!user_access('create tripal_bulk_loader', $account)) {
       return FALSE;
     }
+    return TRUE;
   }
   if ($op == 'update') {
     if (!user_access('edit tripal_bulk_loader', $account)) {
@@ -234,6 +258,7 @@ function tripal_bulk_loader_perm() {
       'create tripal_bulk_loader',
       'delete tripal_bulk_loader',
       'edit tripal_bulk_loader',
+      'administer tripal_bulk_loader',
   );
 }
 

+ 1 - 1
tripal_contact/includes/tripal_contact.form.inc

@@ -4,7 +4,7 @@
  *
  *
  *
- *  @parm &$node
+ *  @parm $node
  *    The node that is created when the database is initialized
  *
  *  @parm $form_state

+ 23 - 8
tripal_contact/tripal_contact.install

@@ -10,10 +10,15 @@
  * multiple contact/mysql instances as well as manage and create such contact instances
  */
 
+
 /**
  * Implementation of hook_install().
  */
 function tripal_contact_install() {
+	
+	// create the module's data directory
+  tripal_create_moddir('tripal_contact');
+  
   // add the tripal_contact table to Drupal
   drupal_install_schema('tripal_contact');
   
@@ -39,22 +44,32 @@ function tripal_contact_uninstall() {
 function tripal_contact_schema() {
   $schema['chado_contact'] = array(
     'fields' => array(
-      'nid' => array(
+      'vid' => array(
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
+        'default' => 0
       ),
-      'vid' => array(
-          'type' => 'int',
-          'not null' => TRUE,
-      ),
-      'contact_id' => array(
+      'nid' => array(
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
+        'default' => 0
       ),
+      'contact_id' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0
+      )
+    ),
+    'indexes' => array(
+      'contact_id' => array('contact_id')
+    ),
+    'unique keys' => array(
+      'nid_vid' => array('nid', 'vid'),
+      'vid' => array('vid')
     ),
-    'primary key' => array('nid', 'vid', 'contact_id'),
+    'primary key' => array('nid'),
   );
   return $schema;
 }
@@ -139,7 +154,7 @@ function tripal_contact_add_custom_tables(){
       ),
     ),
   );
-  tripal_core_create_custom_table(&$ret, 'contactprop', $schema, TRUE);
+  tripal_core_create_custom_table($ret, 'contactprop', $schema, TRUE);
 }
 /**
  *  Update for Drupal 6.x, Tripal 1.0

+ 6 - 2
tripal_contact/tripal_contact.module

@@ -199,14 +199,18 @@ function tripal_contact_perm() {
  *  A user object representing the user for whom the operation is to be performed
  *
  *  @return
- *  TRUE
+ *  If the permission for the specified operation is not set then return FALSE. If the
+ *  permission is set then return NULL as this allows other modules to disable
+ *  access.  The only exception is when the $op == 'create'.  We will always 
+ *  return TRUE if the permission is set.
  *
  */
 function chado_contact_access($op, $node, $account ) {
   if ($op == 'create') {
     if (!user_access('create chado_contact content', $account)) {
       return FALSE;
-      }
+    }
+    return TRUE;
   }
 
   if ($op == 'update') {

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

@@ -1545,7 +1545,7 @@ function tripal_core_expand_chado_vars($object, $type, $to_expand, $table_option
 
   // make sure we have a value
   if (!$object) {
-    watchdog('tripal_core', 'Cannot pass non array as arugment, $object, to tripal_core_expand_chado_vars function.', array(), WATCHDOG_ERROR);
+    watchdog('tripal_core', 'Cannot pass non array as argument, $object, to tripal_core_expand_chado_vars function.', array(), WATCHDOG_ERROR);
     return $object;
   }
 

+ 34 - 1
tripal_cv/api/tripal_cv.api.inc

@@ -264,6 +264,9 @@ function tripal_cv_get_cvterm_by_name($name, $cv_id = NULL, $cv_name = 'tripal')
       array('%name' => $name, '%cv' => $cv_name ? $cv_name : $cv_id), WATCHDOG_ERROR);
     return FALSE;
   }
+  if (count($r) == 0) {
+  	return FALSE;
+  }
   return $r[0];
 }
 
@@ -830,6 +833,7 @@ function tripal_cv_get_custom_tables($table = NULL) {
  *   
  * @ingroup tripal_cv_api
  */
+
 function tripal_cv_submit_obo_job($obo_id = NULL, $obo_name = NULL, $obo_url = NULL, $obo_file = NULL) {
   global $user;
 
@@ -874,5 +878,34 @@ function tripal_cv_add_obo_ref($name, $path) {
   $record->name = $name;
   $record->path = $path;
   drupal_write_record('tripal_cv_obo', $record);
-  return $record->obo_id;
+  return $record->obo_id;  
+}
+
+/**
+ * This function is intended to be used in autocomplete forms
+ * for searching for CV terms that begin with the provided string
+ * 
+ * @param $cv_id
+ * The CV ID in which to search for the term
+ * @param $string
+ * The string to search for
+ * 
+ * @return
+ * A json array of terms that begin with the provided string
+ *  
+ * @ingroup tripal_cv_api
+ */
+function tripal_cv_cvterm_name_autocomplete($cv_id, $string = '') {
+  $sql = "
+    SELECT cvterm_id, name 
+    FROM {cvterm} 
+    WHERE cv_id = %d and lower(name) like lower('%s%%') 
+    ORDER by name
+  ";
+  $results = chado_query($sql, $cv_id, $string);
+  $items = array();
+  while($term = db_fetch_object($results)) {
+     $items[$term->name] = $term->name;
+  }  
+  drupal_json($items);   
 }

+ 1 - 1
tripal_cv/includes/trees.inc

@@ -42,7 +42,7 @@ function tripal_cv_show_browser() {
  * to the function.  For example, the Tripal GO Analysis module generates
  * tree ids of the form:
  *
- *  tripal_analysis_go_cv_tree_10_2_bp
+ *  tripal_analysis_go_cv_tree_10-2_bp
  *
  * In this case the module that will manage this tree is identified as 'tripal_analysis_go' and within
  * the [unique id] portion contains the

+ 561 - 0
tripal_cv/includes/tripal_cv_admin.inc

@@ -0,0 +1,561 @@
+<?php
+/**
+ * Purpose: Provides the form for Updating and Deleteing existing
+ *   chado controlled vocabularies (See chado cv table)
+ *
+ * @ingroup tripal_cv
+ */
+function tripal_cv_edit_page() {
+  $output .= drupal_get_form('tripal_cv_select_form');
+  $output .= '<div id="cv-edit-div">Please select a vocabulary above to view or edit</div>';
+
+  return $output;
+}
+
+/**
+ * Purpose: Provides the actual "Select CV" form on the Update/Delete Controlled
+ *   Vocabulary page. This form also triggers the edit javascript
+ * @todo Modify this form to use Drupal AJAX
+ *
+ * @ingroup tripal_cv
+ */
+function tripal_cv_select_form() {
+
+  // get a list of db from chado for user to choose
+  $sql = "SELECT * FROM {cv} WHERE NOT name = 'tripal' ORDER BY name ";
+  $results = chado_query($sql);
+
+  $cvs = array();
+  $cvs[] = '';
+  while ($cv = db_fetch_object($results)) {
+    $cvs[$cv->cv_id] = $cv->name;
+  }
+
+  $form['cvid'] = array(
+    '#title' => t('Controlled Vocabulary/Ontology Name'),
+    '#type' => 'select',
+    '#options' => $cvs,
+    '#ahah' => array(
+      'path' => 'admin/tripal/tripal_cv/cv/edit/js',
+      'wrapper' => 'cv-edit-div',
+      'effect' => 'fade',
+      'event' => 'change',
+      'method' => 'replace',
+    ),
+  );
+
+  return $form;
+}
+
+/**
+ * Purpose: The edit controlled vocabulary javascript
+ *
+ * @ingroup tripal_cv
+ */
+function tripal_ajax_cv_edit() {
+
+  // get the database id, build the form and then return the JSON object
+  $cvid = filter_xss($_POST['cvid']);
+  $form = drupal_get_form('tripal_cv_edit_form', $cvid);
+  drupal_json(array('status' => TRUE, 'data' => $form));
+
+}
+
+/**
+ * Purpose: Provides a form to allow updating/deleteing of controlled vocabularies
+ *
+ * @ingroup tripal_cv
+ */
+function tripal_cv_edit_form(&$form_state = NULL, $cvid = NULL) {
+
+  $sql = "SELECT * FROM {cv} WHERE cv_id = %d ";
+  $cv = db_fetch_object(chado_query($sql, $cvid));
+
+  // set the default values.  If there is a value set in the
+  // form_state then let's use that, otherwise, we'll pull
+  // the values from the database
+  $default_db = $form_state['values']['name'];
+  $default_desc = $form_state['values']['description'];
+  $default_url = $form_state['values']['url'];
+  $default_urlprefix = $form_state['values']['urlprefix'];
+  if (!$default_db) {
+    $default_cv = $cv->name;
+  }
+  if (!$default_desc) {
+    $default_desc = $cv->definition;
+  }
+
+  $form['cvid'] = array(
+    '#type' => 'hidden',
+    '#value' => $cvid
+  );
+
+  $form['name']= array(
+    '#type'          => 'textfield',
+    '#title'         => t("Controlled Vocabulary name"),
+    '#description'   => t('Please enter the name for this vocabulary.'),
+    '#required'      => FALSE,
+    '#default_value' => $default_cv,
+    '#weight'        => 1
+  );
+
+  $form['definition']= array(
+    '#type'          => 'textarea',
+    '#title'         => t('Description'),
+    '#description'   => t('Please enter a description for this vocabulary'),
+    '#default_value' => $default_desc,
+    '#weight'        => 2
+  );
+
+  $form['update'] = array(
+    '#type'         => 'submit',
+    '#value'        => t('Update'),
+    '#weight'       => 5,
+    '#executes_submit_callback' => TRUE,
+  );
+  $form['delete'] = array(
+    '#type'         => 'submit',
+    '#value'        => t('Delete'),
+    '#weight'       => 6,
+    '#executes_submit_callback' => TRUE,
+  );
+
+  $form['#redirect'] = 'admin/tripal/tripal_cv';
+
+
+  return $form;
+}
+
+/**
+ * Purpose: The submit function of the update/delete controlled vocabulary form
+ *
+ * @ingroup tripal_cv
+ */
+function tripal_cv_edit_form_submit($form, &$form_state) {
+
+  $name =  $form_state['values']['name'];
+  $desc =  $form_state['values']['definition'];
+  $cvid =  $form_state['values']['cvid'];
+  $op   =  $form_state['values']['op'];
+
+  if (strcmp($op, 'Update') == 0) {
+    $sql = "
+       UPDATE {cv} SET
+         name = '%s',
+         definition = '%s'
+       WHERE cv_id = %d
+    ";
+    $db = chado_query($sql, $name, $desc, $cvid);
+    if ($db) {
+      drupal_set_message(t("Controlled vocabulary updated"));
+    }
+    else {
+      drupal_set_message(t("Failed to update controlled vocabulary."), 'error');
+    }
+  }
+  if (strcmp($op, 'Delete')==0) {
+    $sql = "
+       DELETE FROM {cv}
+       WHERE cv_id = %d
+    ";
+    $db = chado_query($sql, $cvid);
+    if ($db) {
+      drupal_set_message(t("Controlled vocabulary deleted"));
+    }
+    else {
+      drupal_set_message(t("Failed to delete controlled vocabulary."), 'error');
+    }
+  }
+
+}
+
+
+/**
+ * Purpose: Provides the Add controlled vocabulary form
+ *
+  * @ingroup tripal_cv
+ */
+function tripal_cv_add_form(&$form_state = NULL) {
+
+  $form['cvid'] = array(
+    '#type' => 'hidden',
+    '#value' => $cvid
+  );
+
+  $form['name']= array(
+    '#type'          => 'textfield',
+    '#title'         => t("Controlled Vocabulary name"),
+    '#description'   => t('Please enter the name for this vocabulary.  This field will be ignored if an OBO file or URL is provided above'),
+    '#required'      => FALSE,
+    '#default_value' => $default_cv,
+    '#weight'        => 1
+  );
+
+  $form['definition']= array(
+    '#type'          => 'textarea',
+    '#title'         => t('Description'),
+    '#description'   => t('Please enter a description for this vocabulary'),
+    '#default_value' => $default_desc,
+    '#weight'        => 2
+  );
+
+  $form['add'] = array(
+    '#type'         => 'submit',
+    '#value'        => t('Add'),
+    '#weight'       => 5,
+    '#executes_submit_callback' => TRUE,
+  );
+
+  $form['#redirect'] = 'admin/tripal/tripal_cv';
+
+  return $form;
+}
+
+/**
+ * Purpose: The submit function for the add controlled vocabulary form
+ *
+ * @ingroup tripal_cv
+ */
+function tripal_cv_add_form_submit($form, &$form_state) {
+
+  $name =  $form_state['values']['name'];
+  $desc =  $form_state['values']['definition'];
+
+  $sql = "
+    INSERT INTO {cv}
+     (name,definition)
+    VALUES
+     ('%s','%s')
+  ";
+  $db = chado_query($sql, $name, $desc);
+  if ($db) {
+    drupal_set_message(t("Controlled vocabulary added"));
+  }
+  else {
+    drupal_set_message(t("Failed to add controlled vocabulary."), 'error');
+  }
+
+}
+
+/**
+ * Purpose: Provides the form that allows adding of terms to an existing
+ *   controlled vocabulary
+ *
+  * @ingroup tripal_cv
+ */
+function tripal_cv_cvterm_form(&$form_state, $action = 'add') {
+  tripal_core_ahah_init_form();
+  
+  $form = array();
+
+  // get defaults  
+  $cv_id = $form_state['values']['cv_id'] ? $form_state['values']['cv_id'] : FALSE;
+  $name  = $form_state['values']['name'] ? $form_state['values']['name'] : '';
+  
+  // if we have a cv_id and a term name then get the rest of the term details
+  if ($cv_id and $name) {
+     $values = array(
+       'cv_id' => $cv_id,
+       'name' => $name,
+     );     
+     $results = tripal_core_chado_select('cvterm', array('*'), $values);
+     if (!$results or count($results) == 0) {
+       // we can't find the cvterm so reset the name to blank
+       $name = '';
+     }
+     else {
+       $cvterm = $results[0];
+       $definition = $cvterm->definition;
+       $is_relationshiptype = $cvterm->is_relationshiptype;
+       $is_obsolete = $cvterm->is_obsolete;
+       
+       // now get the database
+       $values = array('dbxref_id' => $cvterm->dbxref_id);
+       $results = tripal_core_chado_select('dbxref', array('*'), $values);
+       $dbxref = $results[0];
+       $accession = $dbxref->accession;
+       $db_id = $dbxref->db_id;
+     }
+  }
+  
+  $values = array();
+  $columns = array('cv_id', 'name');
+  $options = array('order_by' => array('name' => 'ASC'));
+  $results = tripal_core_chado_select('cv', $columns, $values, $options);
+  $cvs = array();
+  $cvs[] = '';
+  foreach ($results as $cv) {
+    $cvs[$cv->cv_id] = $cv->name;
+  }
+
+  $form['wrapper-top'] = array(
+    '#type' => 'markup',
+    '#value' => '<div id="cvterm-form">', 
+  );
+  
+  $form['form_action'] = array(
+    '#type' => 'hidden',
+    '#value' => $action, 
+  );   
+  
+  $form['cv_id'] = array(
+    '#title' => t('Controlled Vocabulary (Ontology) Name'),
+    '#type' => 'select',
+    '#options' => $cvs,
+    '#required' => TRUE,
+    '#default_value' => $cv_id,
+    '#ahah' => array(
+       'path'    => 'admin/tripal/tripal_cv/cvterm/ahah',
+       'wrapper' => 'cvterm-form',
+       'event'   => 'change',
+       'method'  => 'replace',
+    ),    
+  );
+  
+  if ($cv_id) {
+    $form['add_cvterm'] = array(
+      '#type'           => 'fieldset',
+      '#title'          => t('Term Details'),
+      '#prefix'         => '<div id="cvterm-add-div">',
+      '#suffix'         => '</div>'
+    );
+    $description = t('Please enter the name for this vocabulary term.');
+    if ($action == 'edit') {
+      $description = t('Enter the name of the term to edit.  This field will update automatically as you type. Click outside of the box after entering the term.');
+    }
+    $form['add_cvterm']['name']= array(
+      '#type'          => 'textfield',
+      '#title'         => t("Term Name"),
+      '#description'   => $description,
+      '#default_value' => $name,
+      '#required'      => TRUE,
+    );
+    if ($action == 'edit') {
+      if ($name) {
+        $form['add_cvterm']['name']['#attributes'] = array('readonly' => 'readonly');
+        $form['add_cvterm']['name']['#description'] = 'The term name cannot be changed. If the name is incorrect, please create a new term and make this one as obsolete.';
+      } else {
+        $form['add_cvterm']['name']['#autocomplete_path'] = "admin/tripal/tripal_cv/cvterm/auto_name/$cv_id";
+        $form['add_cvterm']['name']['#ahah'] = array(
+           'path'    => 'admin/tripal/tripal_cv/cvterm/ahah',
+           'wrapper' => 'cvterm-form',
+           'method'  => 'replace',
+        );
+      }
+    }   
+
+    if ($action == 'add' or $name) { 
+      
+      
+      $form['add_cvterm']['definition']= array(
+        '#type'          => 'textarea',
+        '#title'         => t('Description'),
+        '#description'   => t('Please enter a description for this term'),
+        '#default_value' => $definition,
+      );
+  
+      $form['add_cvterm']['is_relationshiptype'] = array(
+        '#type'          => 'checkbox',
+        '#title'         => t('This term describes a relationship?'),
+        '#default_value' => $is_relationshiptype,
+      );
+  
+      $form['add_cvterm']['is_obsolete'] = array(
+        '#type'          => 'checkbox',
+        '#title'         => t('This term is obsolete?'),
+        '#default_value' => $is_obsolete,
+      );
+  
+      $values = array();
+      $columns = array('db_id', 'name');
+      $options = array('order_by' => array('name' => 'ASC'));
+      $results = tripal_core_chado_select('db', $columns, $values, $options);
+      $dbs = array();
+      $dbs[] = '';
+      foreach ($results as $db) {
+        $dbs[$db->db_id] = $db->name;
+      }
+      $form['add_cvterm']['db_id'] = array(
+        '#type'         => 'select',
+        '#title'         => t('Database'),
+        '#description'   => t('All terms must be assocated with an external database.
+                            Please select the external database to associate with
+                            this term'),
+        '#options'      => $dbs,
+        '#default_value' => $db_id,
+        '#required' => TRUE,
+      );
+      if ($action == 'edit') {
+        // we don't want to allow the user to change the database on an edit.
+        $form['add_cvterm']['db_id']['#disabled'] = TRUE;
+        $form['add_cvterm']['db_id']['#description'] = 'The database to which this term belongs cannot be changed.';
+      }
+      
+      $form['add_cvterm']['accession']= array(
+        '#type'          => 'textfield',
+        '#title'         => t("Accession"),
+        '#description'   => t('If this term has an existing accession (unique identifier) in the database 
+           please enter that here.  If the accession is numeric with a database prefix (e.g. GO:003023), please
+           enter just the numeric value.  The database prefix will be appended whenever the term is displayed. 
+           If the accession is not numeric then enter it as is.  If no value is provied, the term name 
+           provided above will be used as the accession.'),
+        '#required'      => FALSE,
+        '#default_value' => $accession,
+      );
+      if ($action == 'edit') {
+        $form['add_cvterm']['accession']['#attributes'] = array('readonly' => 'readonly');
+        $form['add_cvterm']['accession']['#description'] = 'Cannot change the term accession.';
+      }
+      $button_text = 'Add Term';
+      if ($action == 'edit') {
+        $button_text = 'Update Term';
+      }
+      $form['add_cvterm']['submit'] = array(
+        '#type'  => 'submit',
+        '#value' => $button_text,
+      );
+    } // end if name selected (or action == 'add')
+  } //end of if cv selected
+    
+  
+  $form['wrapper-bottom'] = array(
+    '#type' => 'markup',
+    '#value' => '</div>',
+  );
+
+  return $form;
+}
+
+
+/**
+ * Purpose: Validates the input for adding a cvterm
+ *
+  * @ingroup tripal_cv
+ */
+function tripal_cv_cvterm_form_validate($form, &$form_state) {
+
+  // Ensure that submit does not get called unless the AHAH in the form was called
+  if (!empty($form_state['ahah_submission'])) {
+    return;
+  }
+
+}
+
+/**
+ * Purpose: Adds terms to an existing controlled vocabulary
+ *
+ * @ingroup tripal_cv
+ */
+function tripal_cv_cvterm_form_submit($form, &$form_state) {
+
+  // Ensure the AHAH in the form was called
+  if (!empty($form_state['ahah_submission'])) {
+    return;
+  }
+    
+  // get the database
+  $values = array('db_id' => $form_state['values']['db_id']);
+  $results = tripal_core_chado_select('db', array('name'), $values);
+  if (!$results or count($results) == 0){
+    drupal_set_message(t('Unable to add term.  Cannot find the database.'), 'error');
+    return;
+  }
+  $db = $results[0];
+  
+  // get the cv
+  $values = array('cv_id' => $form_state['values']['cv_id']);
+  $results = tripal_core_chado_select('cv', array('name'), $values);
+  if (!$results or count($results) == 0){
+    drupal_set_message(t('Unable to add term.  Cannot find the vocabulary.'), 'error');
+    return;
+  }
+  $cv = $results[0];
+  
+  // get the accession for this term
+  $accession = $form_state['values']['accession'];
+  if (!$accession) {
+    $accession = $form_state['values']['name'];
+  }  
+  if (is_numeric($accession)) {
+    $accession = $db->name . ":" . $accession;
+  }
+  
+  
+  $update = 0;
+  if ($form_state['values']['form_action'] == 'edit') {
+    $update = 1;
+  }
+  
+  // now add the term
+  $term = array(    
+    'name' => $form_state['values']['name'],
+    'namespace' => $cv->name,
+    'id' => $accession,
+    'def' => $form_state['values']['definition'],
+    'is_obsolete' => $form_state['values']['is_obsolete'],
+  );  
+  
+  $is_relationship = $form_state['values']['is_relationshiptype'];
+  $cvterm = tripal_cv_add_cvterm($term, $cv->name, $is_relationship, $update, $db->name);
+  if ($cvterm) {
+    if (!$update) {
+      drupal_set_message('Term added successfully.');
+    }
+    else {
+      drupal_set_message('Term updated successfully.');
+    }
+  } 
+  else {
+    drupal_set_message('Could not add term. Check Drupal recent logs for error messages.', 'error');  
+  }
+
+}
+
+/**
+ * Purpose: This function gets called when the selecting of a cv from
+ *   the select list triggers it. This function simply rebuilds the form
+ *   with new information. No elements are created here
+ *
+ * @ingroup tripal_cv
+ */
+function tripal_cv_cvterm_callback() {
+  $status = TRUE;
+
+  // prepare and render the form
+  $form = tripal_core_ahah_prepare_form();   
+  $data = drupal_render($form);  
+
+  // bind javascript events to the new objects that will be returned 
+  // so that AHAH enabled elements will work.
+  $settings = tripal_core_ahah_bind_events();
+   
+  // return the updated JSON
+  drupal_json(
+    array(
+      'status'   => $status, 
+      'data'     => $data,
+      'settings' => $settings,
+    )  
+  );
+}
+
+/**
+ * Cvterm path form submit
+ *
+ * @ingroup tripal_cv
+ */
+function tripal_cv_cvtermpath_form_submit($form, &$form_state) {
+  global $user;
+
+  $cvid =  $form_state['values']['cvid'];
+
+  // first get the controlled vocabulary name:
+  $cv = db_fetch_object(chado_query("SELECT * FROM {cv} WHERE cv_id = %d", $cvid));
+
+  // Submit a job to update cvtermpath
+  $job_args = array($cvid);
+  if ($form_state['values']['op'] == t('Update cvtermpath')) {
+    tripal_add_job("Update cvtermpath: $cv->name", 'tripal_cv',
+       'tripal_cv_update_cvtermpath', $job_args, $user->uid);
+  }
+}

+ 0 - 32
tripal_feature/includes/tripal_feature.admin.inc

@@ -85,34 +85,6 @@ function tripal_feature_admin() {
        '#weight' => 2,
     );
 
-
-    $form['feature_edit'] = array(
-       '#type' => 'fieldset',
-       '#title' => t('Feature Editing'),
-       '#collapsible' => 1,
-       '#collapsed' => 1 ,
-    );
-
-    $form['feature_edit']['browser_desc'] = array(
-       '#type'        => 'markup',
-       '#value' => 'When editing or creating a feature, a user must provide the feature type. '.
-                   'The Sequence Ontology list is very large, therefore, to simply the list of types for the user, the following '.
-                   'textbox allows you to specify which features types can be used. This list of terms will appear in the '.
-                   'feature type drop down list of the feature creation/edit form.',
-
-    );
-    $form['feature_edit']['feature_edit_types'] = array(
-       '#title'       => t('Feature Types'),
-       '#type'        => 'textarea',
-       '#description' => t("Enter the Sequence Ontology (SO) terms for the allowed feature types when creating or editing features."),
-       '#default_value' => variable_get('chado_edit_feature_types', 'gene contig EST mRNA'),
-    );
-
-    $form['feature_edit']['set_feature_types'] = array(
-       '#type' => 'submit',
-       '#value' => t('Set Feature Types'),
-    );
-
     $form['summary'] = array(
        '#type' => 'fieldset',
        '#title' => t('Feature Summary Report'),
@@ -208,10 +180,6 @@ function tripal_feature_admin_validate($form, &$form_state) {
       variable_set('tripal_analysis_feature_browse_setting', $form_state['values']['browse_features_analysis']);
     break;
 
-    case t('Set Feature Types') :
-      variable_set('tripal_feature_type_setting', $form_state['values']['feature_edit_types']);
-    break;
-
     case t('Set Summary') :
       variable_set('tripal_feature_summary_setting', $form_state['values']['feature_summary']);
       variable_set('tripal_feature_summary_report_mapping', $form_state['values']['feature_mapping']);

+ 37 - 103
tripal_feature/tripal_feature.module

@@ -23,10 +23,10 @@ require_once "includes/seq_extract.inc";
 require_once "api/tripal_feature.api.inc";
 
 require_once "includes/tripal_feature-delete.inc";
-require_once "includes/tripal_feature-secondary_tables.inc";
-require_once "includes/tripal_feature-properties.inc";
-require_once "includes/tripal_feature-relationships.inc";
-require_once "includes/tripal_feature-db_references.inc";
+//require_once "includes/tripal_feature-secondary_tables.inc";
+//require_once "includes/tripal_feature-properties.inc";
+//require_once "includes/tripal_feature-relationships.inc";
+//require_once "includes/tripal_feature-db_references.inc";
 
 
 /**
@@ -117,15 +117,34 @@ function tripal_feature_perm() {
 }
 
 /**
- *  Set the permission types that the module uses.
+ * Implement hook_access().
  *
+ * This hook allows node modules to limit access to the node types they define.
+ *
+ *  @param $op
+ *  The operation to be performed
+ *
+ *  @param $node
+ *  The node on which the operation is to be performed, or, if it does not yet exist, the
+ *  type of node to be created
+ *
+ *  @param $account
+ *  A user object representing the user for whom the operation is to be performed
+ *
+ *  @return
+ *  If the permission for the specified operation is not set then return FALSE. If the
+ *  permission is set then return NULL as this allows other modules to disable
+ *  access.  The only exception is when the $op == 'create'.  We will always 
+ *  return TRUE if the permission is set.
+ *  
  * @ingroup tripal_feature
  */
 function chado_feature_access($op, $node, $account) {
   if ($op == 'create') {
     if (!user_access('create chado_feature content', $account)) {
       return FALSE;
-      }
+    }
+    return TRUE;
   }
 
   if ($op == 'update') {
@@ -223,68 +242,6 @@ function tripal_feature_menu() {
     'type' => MENU_NORMAL_ITEM,
   );
 
-  // Adding Secondary Properties
-
-  /**
-  $items['node/%tf_node/tf_properties'] = array(
-    'title' => t('Add Properties & Synonyms'),
-    'description' => t('Settings for Features'),
-    'page callback' => 'tripal_feature_add_ALL_property_page',
-    'page arguments' => array(1),
-    'access arguments' => array('create chado_feature content'),
-    'type' => MENU_CALLBACK
-  );
-
-  $items['node/%tf_node/tf_db_references'] = array(
-    'title' => t('Add Database References'),
-    'description' => t('Settings for Features'),
-    'page callback' => 'tripal_feature_add_ALL_dbreferences_page',
-    'page arguments' => array(1),
-    'access arguments' => array('create chado_feature content'),
-    'type' => MENU_CALLBACK
-  );
-
-  $items['node/%tf_node/tf_relationships'] = array(
-    'title' => t('Add Relationships'),
-    'description' => t('Settings for Features'),
-    'page callback' => 'tripal_feature_add_ALL_relationships_page',
-    'page arguments' => array(1),
-    'access arguments' => array('create chado_feature content'),
-    'type' => MENU_CALLBACK
-  );
-  */
-
-  //Edit/Deleting Secondary Properties-------------
-  $items['node/%tf_node/edit_feature_properties'] = array(
-    'title' => 'Edit Properties',
-    'description' => 'Settings for Features',
-    'page callback' => 'tripal_feature_edit_ALL_properties_page',
-    'page arguments' => array(1),
-    'access arguments' => array('edit chado_feature content'),
-    'type' => MENU_LOCAL_TASK,
-    'weight' => 8,
-  );
-  /**
-  $items['node/%tf_node/tf_edit_relationships'] = array(
-    'title' => t('Edit Relationships'),
-    'description' => t('Settings for Feature'),
-    'page callback' => 'tripal_feature_edit_ALL_relationships_page',
-    'page arguments' => array(1),
-    'access arguments' => array('edit chado_feature content'),
-    'type' => MENU_LOCAL_TASK,
-    'weight' => 9,
-  );
-  */
-  $items['node/%tf_node/tf_edit_db_references'] = array(
-    'title' => 'Edit References',
-    'description' => 'Settings for Feature',
-    'page callback' => 'tripal_feature_edit_ALL_dbreferences_page',
-    'page arguments' => array(1),
-    'access arguments' => array('edit chado_feature content'),
-    'type' => MENU_LOCAL_TASK,
-    'weight' => 10,
-  );
-
   // the menu link for addressing any feature (by name, uniquename, synonym)
   $items['feature/%'] = array(
     'title' => 'Matched Features',
@@ -297,24 +254,6 @@ function tripal_feature_menu() {
 
   return $items;
 }
-
-/**
- * Implements Menu wildcard_load hook
- * Purpose: Allows the node ID of a chado feature to be dynamically
- *   pulled from the path. The node is loaded from this node ID
- *   and supplied to the page as an arguement
- *
- * @ingroup tripal_feature
- */
-function tf_node_load($nid) {
-  if (is_numeric($nid)) {
-    $node = node_load($nid);
-    if ($node->type == 'chado_feature') {
-      return $node;
-    }
-  }
-  return FALSE;
-}
 /**
  *  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
@@ -864,7 +803,6 @@ function chado_feature_form($node, $param) {
     '#required' => TRUE,
     '#default_value' => $node->title,
     '#description' => t('The title must be a unique identifier for this feature.  It is recommended to use a combination of uniquename, organism and feature type in the title as this is guranteed to be unique.'),
-    '#weight' => 1,
     '#maxlength' => 255
   );
 
@@ -874,7 +812,6 @@ function chado_feature_form($node, $param) {
     '#required' => TRUE,
     '#default_value' => $feature->uniquename,
     '#description' => t('Enter a unique name for this feature.  This name must be unique for the organism and feature type.'),
-    '#weight' => 1,
     '#maxlength' => 255
   );
 
@@ -884,26 +821,21 @@ function chado_feature_form($node, $param) {
     '#required' => TRUE,
     '#default_value' => $feature->name,
     '#description' => t('Enter the name used by humans to refer to this feature.'),
-    '#weight' => 1,
     '#maxlength' => 255
   );
 
-  // get the list of supported feature types
-  $ftypes = array();
-  $ftypes[''] = '';
-  $supported_ftypes = split("[ \n]", variable_get('tripal_feature_type_setting', 'gene mRNA EST contig'));
-  foreach ($supported_ftypes as $ftype) {
-    $ftypes["$ftype"] = $ftype;
-  }
+  // get the sequence ontology CV ID
+  $values = array('name' => 'sequence');
+  $cv = tripal_core_chado_select('cv', array('cv_id'), $values); 
+  $cv_id = $cv[0]->cv_id; 
 
   $form['feature_type'] = array(
    '#title'       => t('Feature Type'),
-   '#type'        => t('select'),
+   '#type'        => 'textfield',
    '#description' => t("Choose the feature type."),
    '#required'    => TRUE,
    '#default_value' => $feature->type_id->name,
-   '#options'     => $ftypes,
-   '#weight'      => 2
+   '#autocomplete_path' => "admin/tripal/tripal_cv/cvterm/auto_name/$cv_id",
   );
 
   // get the list of organisms
@@ -921,7 +853,6 @@ function chado_feature_form($node, $param) {
     '#required'    => TRUE,
     '#default_value' => $feature->organism_id->organism_id,
     '#options'     => $organisms,
-    '#weight'      => 3,
   );
 
   // Get synonyms
@@ -941,7 +872,6 @@ function chado_feature_form($node, $param) {
     '#required' => FALSE,
     '#default_value' => $syn_text,
     '#description' => t('Enter alternate names (synonmys) for this feature to help in searching and identification. You may enter as many alternate names as needed each on different lines.'),
-    '#weight' => 5,
   );
 
   $form['residues']= array(
@@ -950,7 +880,6 @@ function chado_feature_form($node, $param) {
     '#required' => FALSE,
     '#default_value' => $feature->residues,
     '#description' => t('Enter the nucelotide sequences for this feature'),
-    '#weight' => 6
   );
 
   $checked = '';
@@ -963,7 +892,6 @@ function chado_feature_form($node, $param) {
     '#required' => FALSE,
     '#default_value' => $checked,
     '#description' => t('Check this box if this sequence should be retired and no longer included in further analysis.'),
-    '#weight' => 8
   );
   return $form;
 }
@@ -974,6 +902,12 @@ function chado_feature_form($node, $param) {
  */
 function chado_feature_validate($node) {
   $result = 0;
+  
+  // make sure the feature type is a real sequence ontology term
+  $type = tripal_cv_get_cvterm_by_name($node->feature_type, NULL, 'sequence');
+  if (!$type) {
+     form_set_error('feature_type', t("The feature type is not a valid name from the Sequence Ontology."));	
+  }
 
   // if this is an update, we want to make sure that a different feature for
   // the organism doesn't already have this uniquename. We don't want to give

+ 7 - 1
tripal_featuremap/includes/tripal_featuremap.form.inc

@@ -515,7 +515,13 @@ function theme_chado_featuremap_node_form($form) {
   $markup .= drupal_render($form['title']);
   $markup .= drupal_render($form['unittype_id']);
   $markup .= drupal_render($form['description']);
-  $markup .= "<b>Include Additional Details</b><br>You may add additional properties to this map by scrolling to the bottom of this table, selecting a property type from the dropdown and adding text.  You may add as many properties as desired by clicking the plus button on the right.  To remove a property, click the minus button";
+  $markup .= "<b>Include Additional Details</b><br>You may add additional 
+    properties to this map by scrolling to the bottom of this table, selecting 
+    a property type from the dropdown and adding text.  You may add as many 
+    properties as desired by clicking the plus button on the right.  To 
+    remove a property, click the minus button. If a property is not available
+    you may add it by " . l('adding the term', 'admin/tripal/tripal_cv/cvterm/add') . "
+    to the <b>featuremap_property</b> vocabulary within the <b>tripal</b> database.";
   $markup .= $properties_table;
   $markup .= drupal_render($form['is_obsolete']);
 

+ 3 - 3
tripal_featuremap/tripal_featuremap.install

@@ -218,7 +218,7 @@ function tripal_featuremap_add_custom_tables(){
       ),
     ),
   );  
-  tripal_core_create_custom_table(&$ret, 'featuremapprop', $schema, TRUE);
+  tripal_core_create_custom_table($ret, 'featuremapprop', $schema, TRUE);
   
   // add the featuremap_dbxref table to Chado
   $schema = array (
@@ -270,7 +270,7 @@ function tripal_featuremap_add_custom_tables(){
     ),
     'referring_tables' => NULL,
   );
-  tripal_core_create_custom_table(&$ret, 'featuremap_dbxref', $schema, TRUE);
+  tripal_core_create_custom_table($ret, 'featuremap_dbxref', $schema, TRUE);
   
   $schema = array (
     'table' => 'featureposprop',
@@ -330,7 +330,7 @@ function tripal_featuremap_add_custom_tables(){
       ),
     ),
   );
-  tripal_core_create_custom_table(&$ret, 'featureposprop', $schema, TRUE);
+  tripal_core_create_custom_table($ret, 'featureposprop', $schema, TRUE);
 }
 
 /**

+ 20 - 2
tripal_featuremap/tripal_featuremap.module

@@ -275,8 +275,25 @@ function tripal_featuremap_cron() {
 
 }
 /**
- *  The following function proves access control for users trying to
- *  perform actions on data managed by this module
+ * Implement hook_access().
+ *
+ * This hook allows node modules to limit access to the node types they define.
+ *
+ *  @param $op
+ *  The operation to be performed
+ *
+ *  @param $node
+ *  The node on which the operation is to be performed, or, if it does not yet exist, the
+ *  type of node to be created
+ *
+ *  @param $account
+ *  A user object representing the user for whom the operation is to be performed
+ *
+ *  @return
+ *  If the permission for the specified operation is not set then return FALSE. If the
+ *  permission is set then return NULL as this allows other modules to disable
+ *  access.  The only exception is when the $op == 'create'.  We will always 
+ *  return TRUE if the permission is set.
  *
  * @ingroup tripal_featuremap
  */
@@ -285,6 +302,7 @@ function tripal_featuremap_map_access($op, $node, $account) {
     if (!user_access('create chado_featuremap content', $account)) {
       return FALSE;
     }
+    return TRUE;
   }
 
   if ($op == 'update') {

+ 7 - 6
tripal_library/includes/tripal_library.admin.inc

@@ -76,12 +76,12 @@ function get_tripal_library_admin_form_taxonomy_set(&$form) {
   );
 
   // get the list of libraries
-  $sql = "SELECT * FROM {Library} ORDER BY uniquename";
+  $sql = "SELECT * FROM {library} ORDER BY uniquename";
   $lib_rset = chado_query($sql);
 
   // iterate through all of the libraries
   $lib_boxes = array();
-  while ($library = db_fetch_object($lib_rset)) {
+  foreach ($lib_rset as $library) {
     $lib_boxes[$library->library_id] = "$library->name";
   }
 
@@ -164,7 +164,7 @@ function get_tripal_library_admin_form_sync_set(&$form) {
 
 
   // get the list of libraries
-  $sql = "SELECT * FROM {Library} ORDER BY uniquename";
+  $sql = "SELECT * FROM {library} ORDER BY uniquename";
   $lib_rset = chado_query($sql);
 
   // if we've added any libraries to the list that can be synced
@@ -173,11 +173,12 @@ function get_tripal_library_admin_form_sync_set(&$form) {
   // a message stating that all libraries are currently synced.
   $lib_boxes = array();
   $added = 0;
-  while ($library = db_fetch_object($lib_rset)) {
+  foreach ($lib_rset as $libary) {
     // check to see if the library is already present as a node in drupal.
     // if so, then skip it.
-    $sql = "SELECT * FROM {chado_library} WHERE library_id = %d";
-    if (!db_fetch_object(db_query($sql, $library->library_id))) {
+    $sql = "SELECT * FROM {chado_library} WHERE library_id = :library_id";
+    $chado_library = db_query($sql, array(':library_id' => $library->library_id))->fetchObject();
+    if (!$chado_library) {
       $lib_boxes[$library->library_id] = "$library->name";
       $added++;
     }

+ 20 - 1
tripal_library/tripal_library.module

@@ -70,7 +70,25 @@ function tripal_library_perm() {
   );
 }
 /**
- *  Set the permission types that the module uses.
+ * Implement hook_access().
+ *
+ * This hook allows node modules to limit access to the node types they define.
+ *
+ *  @param $op
+ *  The operation to be performed
+ *
+ *  @param $node
+ *  The node on which the operation is to be performed, or, if it does not yet exist, the
+ *  type of node to be created
+ *
+ *  @param $account
+ *  A user object representing the user for whom the operation is to be performed
+ *
+ *  @return
+ *  If the permission for the specified operation is not set then return FALSE. If the
+ *  permission is set then return NULL as this allows other modules to disable
+ *  access.  The only exception is when the $op == 'create'.  We will always 
+ *  return TRUE if the permission is set.
  *
  * @ingroup tripal_library
  */
@@ -79,6 +97,7 @@ function chado_library_access($op, $node, $account) {
     if (!user_access('create chado_library content', $account)) {
       return FALSE;
     }
+    return TRUE;
   }
   if ($op == 'update') {
     if (!user_access('edit chado_library content', $account)) {

+ 21 - 3
tripal_organism/tripal_organism.module

@@ -150,8 +150,25 @@ function tripal_organism_theme() {
   );
 }
 /**
- *  The following function proves access control for users trying to
- *  perform actions on data managed by this module
+ * Implement hook_access().
+ *
+ * This hook allows node modules to limit access to the node types they define.
+ *
+ *  @param $op
+ *  The operation to be performed
+ *
+ *  @param $node
+ *  The node on which the operation is to be performed, or, if it does not yet exist, the
+ *  type of node to be created
+ *
+ *  @param $account
+ *  A user object representing the user for whom the operation is to be performed
+ *
+ *  @return
+ *  If the permission for the specified operation is not set then return FALSE. If the
+ *  permission is set then return NULL as this allows other modules to disable
+ *  access.  The only exception is when the $op == 'create'.  We will always 
+ *  return TRUE if the permission is set.
  *
  * @ingroup tripal_organism
  */
@@ -159,7 +176,8 @@ function chado_organism_access($op, $node, $account) {
   if ($op == 'create') {
     if (!user_access('create chado_organism content', $account)) {
       return FALSE;
-      }
+    }
+    return TRUE;
   }
   if ($op == 'update') {
     if (!user_access('edit chado_organism content', $account)) {

+ 16 - 12
tripal_project/tripal_project.module

@@ -77,23 +77,26 @@ function tripal_project_perm() {
 }
 
 /**
- * Implements hook_access()
+ * Implement hook_access().
  *
- *  This function sets the access permission for operations on the database.
+ * This hook allows node modules to limit access to the node types they define.
  *
- *  @parm $op
- *    The operation that is to be performed
+ *  @param $op
+ *  The operation to be performed
  *
- *  @parm $node
- *    The specific node that is to have the operation performed
+ *  @param $node
+ *  The node on which the operation is to be performed, or, if it does not yet exist, the
+ *  type of node to be created
  *
- *  @parm $account
- *    The account of the user that is performing the operations
+ *  @param $account
+ *  A user object representing the user for whom the operation is to be performed
  *
  *  @return
- *    True if a operation was performed
- *
- *
+ *  If the permission for the specified operation is not set then return FALSE. If the
+ *  permission is set then return NULL as this allows other modules to disable
+ *  access.  The only exception is when the $op == 'create'.  We will always 
+ *  return TRUE if the permission is set.
+ *  
  * @ingroup tripal_project
  */
 function chado_project_access($op, $node, $account) {
@@ -102,6 +105,7 @@ function chado_project_access($op, $node, $account) {
     if (!user_access('create chado_projects content', $account)) {
       return FALSE;
     }
+    return TRUE;
   }
   if ($op == 'update') {
     if (!user_access('edit chado_projects content', $account)) {
@@ -185,7 +189,7 @@ function tripal_project_theme() {
  *
  *  This form takes the Project Title information and description from the user.
  *
- *  @parm &$node
+ *  @parm $node
  *    The initialized node
  *
  *  @parm $form_state

+ 320 - 21
tripal_pub/api/tripal_pub.api.inc

@@ -953,35 +953,334 @@ function tripal_pub_delete_property($pub_id, $property) {
   return tripal_core_delete_property('pub', $pub_id, $property, 'tripal_pub');
 }
 
-/*
- *
+
+
+/**
+ * This function generates an array suitable for use with the 
+ * tripal_pub_create_citation function for any publication
+ * already stored in the Chado tables.
+ *  
+ * @param $pub_id
+ *   The publication ID
+ * @param $skip_existing
+ *   Set to TRUE to skip publications that already have a citation
+ *   in the pubprop table.  Set to FALSE to generate a citation 
+ *   regardless if the citation already exists.
+ *   
+ * @return
+ *   An array suitable for the trpial_pub_create_citation function. On
+ *   failure returns FALSE.
  */
-function tripal_pub_create_citation($pub) {
-  $citation = $pub['Authors'] . '. ' . $pub['Title'] .  '. ';
 
-  if ($pub['Journal Name']) {
-    $citation .= $pub['Journal Name'] . '. ';
+function tripal_pub_get_publication_array($pub_id, $skip_existing = TRUE) {
+
+  $options = array('return_array' => 1);
+
+  // ---------------------------------
+  // get the publication
+  // ---------------------------------
+  $values = array('pub_id' => $pub_id);
+  $pub = tripal_core_generate_chado_var('pub', $values);
+
+  // expand the title
+  $pub = tripal_core_expand_chado_vars($pub, 'field', 'pub.title');
+  $pub = tripal_core_expand_chado_vars($pub, 'field', 'pub.volumetitle');
+  $pub = tripal_core_expand_chado_vars($pub, 'field', 'pub.uniquename');
+  $pub_array = array();
+  if (trim($pub->title)) {
+    $pub_array['Title'] = $pub->title;
+  }
+  if (trim($pub->volumetitle)) {
+    $pub_array['Volume Title'] = $pub->volumetitle;
   }
-  elseif ($pub['Journal Abbreviation']) {
-    $citation .= $pub['Journal Abbreviation'] . '. ';
+  if (trim($pub->volume)) {
+    $pub_array['Volume'] = $pub->volume;
   }
-  $citation .= $pub['Publication Date'];
-  if ($pub['Volume'] or $pub['Issue'] or $pub['Pages']) {
-    $citation .= '; ';
+  if (trim($pub->series_name)) {
+    $pub_array['Series Name'] = $pub->series_name;
   }
-  if ($pub['Volume']) {
-    $citation .= $pub['Volume'];
+  if (trim($pub->issue)) {
+    $pub_array['Issue'] = $pub->issue;
   }
-  if ($pub['Issue']) {
-    $citation .= '(' . $pub['Issue'] . ')';
+  if (trim($pub->pyear)) {
+    $pub_array['Year'] = $pub->pyear;
   }
-  if ($pub['Pages']) {
-    if($pub['Volume']) {
-      $citation .= ':';
+  if (trim($pub->pages)) {
+    $pub_array['Pages'] = $pub->pages;
+  }
+  if (trim($pub->miniref)) {
+    $pub_array['Mini Ref'] = $pub->miniref;
+  }
+  if (trim($pub->uniquename)) {
+    $pub_array['Uniquename'] = $pub->uniquename;
+  }
+  $pub_array['Publication Type'][] = $pub->type_id->name;
+
+  // ---------------------------------
+  // get the citation
+  // ---------------------------------
+  $values = array(
+    'pub_id' => $pub->pub_id, 
+    'type_id' => array(
+      'name' => 'Citation',
+    ),
+  );
+  $citation = tripal_core_generate_chado_var('pubprop', $values);
+  if ($citation) {
+    $citation = tripal_core_expand_chado_vars($citation, 'field', 'pubprop.value', $options);
+    if (count($citation) > 1) {
+    	watchdog('tripal_pub', "Publication has multiple citations already: %pub_id",
+    	array('%pub_id' => $pubid), WATCHDOG_ERROR);
+    	return FALSE;
+    }
+    elseif (count($citation) == 1 and $skip_existing == TRUE) {
+    	// skip this publication, it already has a citation
+    	return FALSE;
+    }
+  }  
+
+  // ---------------------------------
+  // get the publication types
+  // ---------------------------------
+  $values = array(
+    'pub_id' => $pub->pub_id, 
+    'type_id' => array(
+      'name' => 'Publication Type',
+    ),
+  );
+  $ptypes = tripal_core_generate_chado_var('pubprop', $values, $options);
+  if ($ptypes) {
+    $ptypes = tripal_core_expand_chado_vars($ptypes, 'field', 'pubprop.value', $options);
+    foreach ($ptypes as $ptype) {
+     $pub_array['Publication Type'][] = $ptype->value;
     }
-    $citation .= $pub['Pages'];
   }
-  $citation .= '.';
 
-  return $citation;
+  // ---------------------------------
+  // get the authors list
+  // ---------------------------------
+  $values = array(
+    'pub_id' => $pub->pub_id, 
+    'type_id' => array(
+      'name' => 'Authors',
+    ),
+  );
+  $authors = tripal_core_generate_chado_var('pubprop', $values);
+  $authors = tripal_core_expand_chado_vars($authors, 'field', 'pubprop.value', $options);
+  if (count($authors) > 1) {
+   watchdog('tripal_pub', "Publication has multiple author lists. It should have only one list: %pub_id",
+   array('%pub_id' => $pubid), WATCHDOG_ERROR);
+   return FALSE;
+  }
+  else if (trim($authors->value)) {
+    $pub_array['Authors'] = $authors->value;
+  }
+  // if there is no 'Author's property then try to retreive authors from the pubauthor table
+  else {
+    $sql = "SELECT string_agg(surname || ' ' || givennames, ', ') FROM {pubauthor} WHERE pub_id = %d GROUP BY pub_id";
+    $au = db_result(chado_query($sql));
+    if ($au) {
+    	$pub_array['Authors'] = $au;
+    }
+  }
+
+  //Get other props
+  $props = array(
+    'Journal Abbreviation',
+    'Elocation',
+    'Media Code',
+    'Conference Name',
+    'Keywords',
+    'Series Name',
+    'pISSN',
+    'Publication Date',
+    'Journal Code',
+    'Journal Alias',
+    'Journal Country',
+    'Published Location',
+    'Publication Model',
+    'Language Abbr',
+    'Alias',
+    'Publication Dbxref',
+    'Copyright',
+    'Abstract',
+    'Notes',
+    'Citation',
+    'Language',
+    'URL',
+    'eISSN',
+    'DOI',
+    'ISSN',
+    'Publication Code',
+    'Comments',
+    'Publisher',
+    'Media Alias',
+    'Original Title');
+  foreach ($props AS $prop) {
+    $sql = 
+      "SELECT value FROM {pubprop} 
+       WHERE type_id = (SELECT cvterm_id FROM {cvterm} WHERE name = '%s' AND cv_id = (SELECT cv_id FROM cv WHERE name = 'tripal_pub')) 
+       AND pub_id = %d";
+    $val = trim(db_result(chado_query($sql, $prop, $pub->pub_id)));
+    if ($val) {
+      $pub_array[$prop] =$val;
+    } 
+  }
+  return $pub_array;  
 }
+
+
+/**
+ * This function generates citations for publications.  It requires
+ * an array structure with keys being the terms in the Tripal
+ * publication ontology.  This function is intended to be used
+ * for any function that needs to generate a citation. 
+ * 
+ * @param $pub
+ *   An array structure containing publication details where the keys
+ *   are the publication ontology term names and values are the 
+ *   corresponding details.  The pub array can contain the following
+ *   keys with corresponding values:   
+ *     - Publication Type:  an array of publication types. a publication can have more than one type
+ *     - Authors: a  string containing all of the authors of a publication
+ *     - Journal Name:  a string containing the journal name
+ *     - Journal Abbreviation: a string containing the journal name abbreviation
+ *     - Series Name: a string containing the series (e.g. conference proceedings) name
+ *     - Series Abbreviation: a string containing the series name abbreviation     
+ *     - Volume: the serives volume number
+ *     - Issue: the series issue number
+ *     - Pages: the page numbers for the publication
+ *     - Publication Date:  A date in the format "Year Month Day"
+ *      
+ * @return
+ *   A text string containing the citation
+ */
+function tripal_pub_create_citation($pub) {
+	$citation = '';
+	$pub_type = '';
+	
+	// An article may have more than one publication type. For example,
+	// a publication type can be 'Journal Article' but also a 'Clinical Trial'.
+	// Therefore, we need to select the type that makes most sense for 
+	// construction of the citation. Here we'll iterate through them all
+	// and select the one that matches best.
+	if(is_array($pub['Publication Type'])) {
+	  foreach ($pub['Publication Type'] as $ptype) {
+	    if ($ptype == 'Journal Article' ) {
+	      $pub_type = $ptype;
+	      break;
+	    } else if ($ptype == 'Conference Proceedings'){ 
+	      $pub_type = $ptype;
+	      break;
+	    } else if ($ptype == 'Book') {
+	      $pub_type = $ptype;
+	      break;
+	    } else if ($ptype == 'Book Chapter') {
+	      $pub_type = $ptype;
+	      break;
+	    }
+	  }
+	  if (!$pub_type) {
+      watchdog('tripal_pub', "Cannot generate citation for publication type: %types", 
+        array('%types' => print_r($pub['Publication Type'], TRUE)), WATCHDOG_ERROR);
+      return FALSE;
+    }
+	}
+	else {
+	  $pub_type = $pub['Publication Type'];
+	}		
+  print "[$pub_type]\n";
+	//----------------------
+  // Journal Article
+  //----------------------
+	if ($pub_type == 'Journal Article') {
+	  $citation = $pub['Authors'] . '. ' . $pub['Title'] .  '. ';
+	
+	  if ($pub['Journal Name']) {
+	    $citation .= $pub['Journal Name'] . '. ';
+	  }
+	  elseif ($pub['Journal Abbreviation']) {
+	    $citation .= $pub['Journal Abbreviation'] . '. ';
+	  }
+	  elseif ($pub['Series Name']) {
+	    $citation .= $pub['Series Name'] . '. ';	
+	  }
+	  elseif ($pub['Series Abbreviation']) {
+      $citation .= $pub['Series Abbreviation'] . '. ';
+    }
+    if ($pub['Publication Date']) {
+	    $citation .= $pub['Publication Date'];
+    }
+    elseif ($pub['Year']) {
+    	$citation .= $pub['Year'];
+    }
+	  if ($pub['Volume'] or $pub['Issue'] or $pub['Pages']) {
+	    $citation .= '; ';
+	  }
+	  if ($pub['Volume']) {
+	    $citation .= $pub['Volume'];
+	  }
+	  if ($pub['Issue']) {
+	    $citation .= '(' . $pub['Issue'] . ')';
+	  }
+	  if ($pub['Pages']) {
+	    if($pub['Volume']) {
+	      $citation .= ':';
+	    }
+	    $citation .= $pub['Pages'];
+	  }
+	  $citation .= '.';
+	}
+	//----------------------
+  // Book
+  //----------------------
+	elseif ($pub_type == 'Book') {
+	
+	}
+	//----------------------
+  // Book Chapter
+  //----------------------
+  elseif ($pub_type == 'Book Chapter') {
+  	
+  }
+	//----------------------
+	// Conference Proceedings
+  //----------------------
+  elseif ($pub_type == 'Conference Proceedings') {
+    $citation = $pub['Authors'] . '. ' . $pub['Title'] .  '. ';
+  
+    if ($pub['Conference Name']) {
+      $citation .= $pub['Conference Name'] . '. ';
+    }
+    elseif ($pub['Series Name']) {
+      $citation .= $pub['Series Name'] . '. ';  
+    }
+    elseif ($pub['Series Abbreviation']) {
+      $citation .= $pub['Series Abbreviation'] . '. ';
+    }
+    if ($pub['Publication Date']) {
+      $citation .= $pub['Publication Date'];
+    }
+    elseif ($pub['Year']) {
+      $citation .= $pub['Year'];
+    }
+    if ($pub['Volume'] or $pub['Issue'] or $pub['Pages']) {
+      $citation .= '; ';
+    }
+    if ($pub['Volume']) {
+      $citation .= $pub['Volume'];
+    }
+    if ($pub['Issue']) {
+      $citation .= '(' . $pub['Issue'] . ')';
+    }
+    if ($pub['Pages']) {
+      if($pub['Volume']) {
+        $citation .= ':';
+      }
+      $citation .= $pub['Pages'];
+    }
+    $citation .= '.';
+  }
+
+  return $citation;
+}

+ 14 - 1
tripal_pub/files/tpub.obo

@@ -112,8 +112,9 @@ relationship: part_of TPUB:0000002 ! Publication
 [Term]
 id: TPUB:0000038
 name: Journal Abbreviation
-relationship: part_of TPUB:0000037 ! Publication Details
 def: The journal title ISO Abbreviation.
+is_a: TPUB:0000257 ! Series Abbreviation
+relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
 id: TPUB:0000039
@@ -272,6 +273,7 @@ is_a: TPUB:0000070 ! Conference Proceedings
 [Term]
 id: TPUB:0000075
 name: Journal Name
+is_a: TPUB:0000256 ! Series Name
 relationship: part_of TPUB:0000037 ! Publication Details
 
 [Term]
@@ -1410,6 +1412,17 @@ name: Patent Number
 relationship: part_of TPUB:0000037 ! Publication Details
 def: A unique special code for journal article, book, book chapter or any publication type.
 
+[Term]
+id: TPUB:0000256
+name: Series Name
+relationship: part_of TPUB:0000037 ! Publication Details
+def: The name media that produces a series of publications (e.g. journal, conference proceedings, etc.)
+
+[Term]
+id: TPUB:0000257
+name: Series Abbreviation
+relationship: part_of TPUB:0000037 ! Publication Details
+def: An abbreviation for the series name.  (e.g. the journal title ISO Abbreviation).
 
 [Typedef]
 id: is_a

+ 43 - 21
tripal_pub/includes/importers/AGL.inc

@@ -2,7 +2,8 @@
 /**
  *
  */
-function tripal_pub_remote_alter_form_AGL(&$form, $form_state) {
+function tripal_pub_remote_alter_form_AGL($form, $form_state) {
+
   $num_criteria = $form['num_criteria']['#default_value'];
 
   // So far we haven't been able to get AGL to filter results to only
@@ -15,12 +16,12 @@ function tripal_pub_remote_alter_form_AGL(&$form, $form_state) {
   for($i = 1; $i <= $num_criteria; $i++) {
     unset($form['criteria'][$i]["scope-$i"]['#options']['journal']);
   }
-
+  return $form;
 }
 /**
  *
  */
-function tripal_pub_remote_validate_form_AGL(&$form, $form_state) {
+function tripal_pub_remote_validate_form_AGL($form, $form_state) {
   $days =  trim($form_state['values']["days"]);
   $num_criteria = $form['num_criteria']['#default_value'];
 
@@ -42,6 +43,7 @@ function tripal_pub_remote_validate_form_AGL(&$form, $form_state) {
       form_set_error("search_terms-$i", "Unfortuantely, the AGL importer can only support a single accession at a time. Please remove the others.");
     }
   }
+  return $form;
 }
 /**
  *
@@ -329,7 +331,7 @@ function tripal_pub_remote_search_AGL($search_array, $num_to_retrieve, $pager_id
     );
     yaz_ccl_conf($yazc, $fields);
 
-    if (!yaz_ccl_parse($yazc, $ccl, &$cclresult)) {
+    if (!yaz_ccl_parse($yazc, $ccl, $cclresult)) {
       drupal_set_message('Error parsing search string: ' . $cclresult["errorstring"], "error");
       watchdog('tripal_pub', 'Error: %errstr', array('%errstr' => $cclresult["errorstring"]), WATCHDOG_ERROR);
       return array();
@@ -436,8 +438,10 @@ function tripal_pub_AGL_range($search_array, $start = 0, $limit = 10) {
 function tripal_pub_AGL_parse_pubxml($pub_xml) {
   $pub = array();
 
-  // publications from the NAL Article Citation Database are all journal articles
-  $pub['Publication Type'][] = 'Journal Article';
+  // we will set the default publication type as a journal article. The NAL
+  // dataset doesn't specify an article type so we'll have to glean the type
+  // from other information (e.g. series name has 'Proceedings' in it)
+  $pub['Publication Type'][0] = 'Journal Article';
 
   if (!$pub_xml) {
     return $pub;
@@ -693,7 +697,20 @@ function tripal_pub_AGL_parse_pubxml($pub_xml) {
           $codes = tripal_pub_remote_search_AGL_get_subfield($xml);
           foreach ($codes as $code => $value) {
             switch ($code) {
+            	case 'a':
+            		if (preg_match('/Proceedings/i', $value)) {
+            		  $pub['Series Name'] = preg_replace('/\.$/', '', $value);
+            		  $pub['Publication Type'][0] = 'Conference Proceedings';
+            		}
+            		else {
+            			$pub['Journal Name'] = preg_replace('/\.$/', '', $value);
+            		}
+                break;
               case 't':
+                if (preg_match('/Proceedings/i', $value)) {
+                  $pub['Series Name'] = preg_replace('/\.$/', '', $value);
+                  $pub['Publication Type'][0] = 'Conference Proceedings';
+                }
                 $pub['Journal Name'] = preg_replace('/\.$/', '', $value);
                 break;
               case 'g':
@@ -769,21 +786,26 @@ function tripal_pub_AGL_parse_pubxml($pub_xml) {
   }
 
   // build the full authors list
-  foreach ($pub['Author List'] as $author) {
-    if ($author['valid'] == 'N') {
-      // skip non-valid entries.  A non-valid entry should have
-      // a corresponding corrected entry so we can saftely skip it.
-      continue;
-    }
-    if ($author['Collective']) {
-      $authors .= $author['Collective'] . ', ';
-    }
-    else {
-      $authors .= $author['Surname'] . ' ' . $author['First Initials'] . ', ';
-    }
+  if (is_array($pub['Author List'])) {
+	  foreach ($pub['Author List'] as $author) {
+	    if ($author['valid'] == 'N') {
+	      // skip non-valid entries.  A non-valid entry should have
+	      // a corresponding corrected entry so we can saftely skip it.
+	      continue;
+	    }
+	    if ($author['Collective']) {
+	      $authors .= $author['Collective'] . ', ';
+	    }
+	    else {
+	      $authors .= $author['Surname'] . ' ' . $author['First Initials'] . ', ';
+	    }
+	  }
+	  $authors = substr($authors, 0, -2);
+	  $pub['Authors'] = $authors;
+  }
+  else {
+    $pub['Authors'] = $pub['Author List'];	
   }
-  $authors = substr($authors, 0, -2);
-  $pub['Authors'] = $authors;
 
   // build the citation
   $pub['Citation'] = tripal_pub_create_citation($pub);
@@ -852,4 +874,4 @@ function tripal_pub_remote_search_AGL_get_author($xml, $ind1) {
     }
   }
   return $author;
-}
+}

+ 41 - 19
tripal_pub/includes/importers/PMID.inc

@@ -9,7 +9,7 @@
 /**
  *
  */
-function tripal_pub_remote_alter_form_PMID(&$form, $form_state) {
+function tripal_pub_remote_alter_form_PMID($form, $form_state) {
   $num_criteria = $form['num_criteria']['#default_value'];
 
   // PubMed doesn't have an 'Abstract' field, so we need to convert the criteria
@@ -17,11 +17,13 @@ function tripal_pub_remote_alter_form_PMID(&$form, $form_state) {
   for($i = 1; $i <= $num_criteria; $i++) {
     $form['criteria'][$i]["scope-$i"]['#options']['abstract'] = 'Abstract/Title';
   }
+
+  return $form;
 }
 /**
  *
  */
-function tripal_pub_remote_validate_form_PMID(&$form, $form_state) {
+function tripal_pub_remote_validate_form_PMID($form, $form_state) {
   $num_criteria = $form['num_criteria']['#default_value'];
 
   for ($i = 1; $i <= $num_criteria; $i++) {
@@ -31,6 +33,7 @@ function tripal_pub_remote_validate_form_PMID(&$form, $form_state) {
       form_set_error("search_terms-$i", "The PubMed accession must be a numeric value, prefixed with 'PMID:' (e.g. PMID:23024789).");
     }
   }
+  return $form;
 }
 /**
  *
@@ -56,30 +59,47 @@ function tripal_pub_remote_search_PMID($search_array, $num_to_retrieve, $pager_i
 
     // if this is phrase make sure the search terms are surrounded by quotes
     if ($is_phrase) {
-      $search_terms = "\"$search_terms\"";
+      $search_str .= "(\"$search_terms\" |SCOPE|) ";
+    }
+    // if this is not a phase then we want to separate each 'OR or 'AND' into a unique criteria
+    else {
+    	$search_str .= "(";
+    	if (preg_match('/and/i', $search_terms)) {
+    	  $elements = preg_split('/\s+and+\s/i', $search_terms);
+    	  foreach ($elements as $element) {
+          $search_str .= "($element |SCOPE|) AND ";
+    	  }
+    	  $search_str = substr($search_str, 0, -5); // remove trailing 'AND '              
+    	} 
+      elseif (preg_match('/or/i', $search_terms)) {
+        $elements = preg_split('/\s+or+\s/i', $search_terms);
+        foreach ($elements as $element) {
+          $search_str .= "($element |SCOPE|) OR ";
+        }
+        $search_str = substr($search_str, 0, -4); // remove trailing 'OR '        
+      }
+      else {
+      	$search_str .= "($search_terms |SCOPE|) ";
+      }
+      $search_str .= ') ';
     }
-    $search_str .= '(';
 
     if ($scope == 'title') {
-      $search_str .= $search_terms . '[Title]';
+    	$search_str = preg_replace('/\|SCOPE\|/', '[Title]', $search_str);
     }
     elseif ($scope == 'author') {
-      $search_str .= $search_terms . '[Author]';
+    	$search_str = preg_replace('/\|SCOPE\|/', '[Author]', $search_str);
     }
     elseif ($scope == 'abstract') {
-      $search_str .= $search_terms . '[Title/Abstract]';
+    	$search_str = preg_replace('/\|SCOPE\|/', '[Title/Abstract]', $search_str);
     }
     elseif ($scope == 'journal') {
-      $search_str .= $search_terms . '[Journal]';
+      $search_str = preg_replace('/\|SCOPE\|/', '[Journal]', $search_str);
     }
     elseif ($scope == 'id') {
-      $search_terms = preg_replace('/PMID:([^\s]*)/', '$1', $search_terms);
-      $search_str .=  $search_terms . '[Uid]';
-    }
-    else {
-      $search_str .= $search_terms;
+      $search_str = preg_replace('/PMID:([^\s]*)/', '$1', $search_str);
+      $search_str = preg_replace('/\|SCOPE\|/', '[Uid]', $search_str);
     }
-    $search_str .= ')';
   }
   if ($days) {
     // get the date of the day suggested
@@ -91,6 +111,7 @@ function tripal_pub_remote_search_PMID($search_array, $num_to_retrieve, $pager_i
   $search_array['limit'] = $num_to_retrieve;
   $search_array['search_string'] = $search_str;
 
+  //dpm($search_str);
   unset($_SESSION['tripal_pub_PMID_query']);
   // we want to get the list of pubs using the search terms but using a Drupal style pager
   $pubs = tripal_pager_callback('tripal_pub_PMID_range',  $num_to_retrieve, $pager_id,
@@ -367,7 +388,7 @@ function tripal_pub_PMID_parse_pubxml($pub_xml) {
     }
   }
   $pub['Citation'] = tripal_pub_create_citation($pub);
-
+  
   $pub['raw'] = $pub_xml;
   return $pub;
 }
@@ -513,13 +534,14 @@ function tripal_pub_PMID_parse_publication_type($xml, &$pub) {
       switch ($element) {
         case 'PublicationType':
           $xml->read();
-          $pub_cvterm = tripal_cv_get_cvterm_by_name($xml->value, NULL, 'tripal_pub');
+          $value = $xml->value;          
+          $pub_cvterm = tripal_cv_get_cvterm_by_name($value, NULL, 'tripal_pub');          
           if (!$pub_cvterm) {
             // see if this we can find the name using a synonym
-            $pub_cvterm = tripal_cv_get_cvterm_by_synonym($xml->value, NULL, 'tripal_pub');
+            $pub_cvterm = tripal_cv_get_cvterm_by_synonym($value, NULL, 'tripal_pub');
             if (!$pub_cvterm) {
               watchdog('tpub_pubmed', 'Cannot find a valid vocabulary term for the publication type: "%term".',
-              array('%term' => $xml->value), WATCHDOG_ERROR);
+              array('%term' => $value), WATCHDOG_ERROR);
             }
           }
           else {
@@ -877,4 +899,4 @@ function tripal_pub_remote_search_get_language($lang_abbr) {
     'wel' => 'Welsh',
   );
   return $languages[strtolower($lang_abbr)];
-}
+}

+ 82 - 0
tripal_pub/includes/pub_citation.inc

@@ -0,0 +1,82 @@
+<?php
+/*
+ * The admin form for submitting job to create citations
+*/
+function tripal_pub_citation_form($form_state) {
+
+  $form['create_all'] = array(
+    '#type' => 'item',
+    '#value' => t('Submit a job to create citation for the publications in chado. '),
+  );
+  
+  $form['options'] = array(
+    '#type' => 'radios',
+    '#options' => 
+      array('all' => 'Create citation for all publications. Replace the existing citation if it exists.', 
+                'new' => 'Create citation for publication only if it does not already have one.'),
+    '#default_value' => 'all'
+  );
+  
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#weight' => 10,
+    '#value' => t('Submit')
+  );
+
+  return $form;
+}
+
+/*
+ * Submit form. Create Tripal job for citations
+ */
+
+function tripal_pub_citation_form_submit(&$form_state) {
+  $options [0] = $form_state['options']['#value'];
+  tripal_add_job("Create citations ($options[0])", 'tripal_pub',
+       'tripal_pub_create_citations', $options, $user->uid);
+}
+
+/*
+ * Launch the Tripal job to generate citations
+ */
+function tripal_pub_create_citations ($options) {
+  $skip_existing = TRUE;
+  $citation_type_id = db_result(chado_query("SELECT cvterm_id FROM {cvterm} WHERE name = 'Citation' AND cv_id = (SELECT cv_id FROM {cv} WHERE name = 'tripal_pub')"));
+  // Create and replace citation for all pubs
+  if ($options == 'all') {
+  	$sql = "SELECT pub_id FROM {pub} P WHERE pub_id <> 1";
+    $skip_existing = FALSE;
+  // Create citation for pubs that don't already have one
+  } else if ($options == 'new') {
+  	$sql = "SELECT pub_id FROM {pub} P WHERE (SELECT value FROM {pubprop} PB WHERE type_id = $citation_type_id AND P.pub_id = PB.pub_id AND rank = 0) IS NULL AND  pub_id <> 1";
+  	$skip_existing = TRUE;
+  }
+
+  $result = chado_query($sql);
+  $counter_updated = 0;
+  $counter_generated = 0;
+  while ($pub = db_fetch_object($result)) {
+    $pub_arr = tripal_pub_get_publication_array($pub->pub_id, $skip_existing);
+    if ($pub_arr) {
+      $citation = tripal_pub_create_citation ($pub_arr);
+      print $citation . "\n\n";
+      // Replace if citation exists. This condition is never TRUE if $skip_existing is TRUE
+      if ($pub_arr['Citation']) {
+        $sql = 
+            "UPDATE {pubprop} 
+             SET value = '%s' 
+             WHERE pub_id = %d 
+             AND type_id = %d
+             AND rank = %d";
+        chado_query($sql, $citation, $pub->pub_id, $citation_type_id, 0);
+        $counter_updated ++;
+      // Generate a new citation
+      } else {
+      	$sql = "INSERT INTO {pubprop} (pub_id, type_id, value, rank) VALUES (%d, %d, '%s', %d)";
+      	chado_query($sql, $pub->pub_id, $citation_type_id, $citation, 0);
+      	$counter_generated ++;
+      }
+    }
+  }
+  print "$counter_generated citations generated. $counter_updated citations updated.\n";
+}

+ 28 - 7
tripal_pub/includes/pub_form.inc

@@ -63,6 +63,9 @@ function chado_pub_form($node, $form_state) {
       $d_type_id = $pub_type->cvterm_id;
     }
   }
+  
+  // reset the default to use the stored variable if one exists
+  $d_type_id = variable_get('tripal_pub_default_type', $d_type_id);
 
   // get publication properties list
   $properties_select = array();
@@ -122,20 +125,22 @@ function chado_pub_form($node, $form_state) {
     '#default_value' => $d_pyear,
     '#required' => TRUE,
     '#size' => 5,
+    '#description' => t('Enter the year of publication. Also, if available, please add a <b>Publication Date</b> property to specify the full date of publication.'),
   );
   $form['uniquename'] = array(
     '#type' => 'textarea',
     '#title' => t('Citation'),
     '#default_value' => $d_uniquename,
-    '#description' => t('All publications must have a unique citation. Please enter the full citation for this publication. 
-      For PubMed style citations list 
+    '#description' => t('All publications must have a unique citation. 
+      <b>Please enter the full citation for this publication or leave blank and one will be generated 
+      automatically if possible</b>.  For PubMed style citations list 
       the last name of the author followed by initials. Each author should be separated by a comma. Next comes 
       the title, followed by the series title (e.g. journal name), publication date (4 digit year, 3 character Month, day), volume, issue and page numbers. You may also use HTML to provide a link in the citation.  
       Below is an example: <pre>Medeiros PM, Ladio AH, Santos AM, Albuquerque UP. <a href="http://www.ncbi.nlm.nih.gov/pubmed/23462414" target="_blank">Does the selection of medicinal plants by Brazilian local populations 
         suffer taxonomic influence?</a> J Ethnopharmacol. 2013 Apr 19; 146(3):842-52.</pre>'),
-    '#required' => TRUE,
   );
 
+
   // add in the properties that are actually stored in the pub table fields.
   $num_properties = chado_pub_node_form_add_pub_table_props($form, $form_state, $properties_list,
   $d_properties, $d_removed, $d_volume, $d_volumetitle, $d_issue, $d_pages, $d_series_name);
@@ -195,11 +200,15 @@ function chado_pub_validate($node, &$form) {
   $pub_id       = $node->pub_id;
   $num_properties = $node->num_properties;
   $num_new = $node->num_new;
+  dpm($node);
+  
+  $pub = array();
 
   // if this is a delete then don't validate
   if($node->op == 'Delete') {
     return;
   }
+  
 
   // make sure the year is four digits
   if(!preg_match('/^\d{4}$/', $pyear)){
@@ -215,9 +224,9 @@ function chado_pub_validate($node, &$form) {
     $message = t('Invalid publication type.');
     form_set_error('type_id', $message);
     return;
-  }
+  }  
 
-  // get the media name looking at the properties
+  // get the media name looking at the properties  
   foreach ($node as $element => $value) {
     // if this is an existing property (either previously in the database or
     // added via AHAH/AJAX callback)
@@ -230,16 +239,28 @@ function chado_pub_validate($node, &$form) {
       if($prop_type->name == 'Citation') {
         $uniquename = $value;
       }
+      $pub[$prop_type->name] = $value;
     }
     // if this is a new property (added by this submit of the form)
-    elseif ($element = 'new_id') {
+    elseif ($element == 'new_id') {    	 
       $prop_type = tripal_cv_get_cvterm_by_id($value);
       if($prop_type->name == 'Conference Name' or $prop_type->name == 'Journal Name') {
         $series_name = $node->new_value;
       }
       if($prop_type->name == 'Citation') {
-        $uniquename = $value;
+        $uniquename = $node->new_value;
       }
+      $pub[$prop_type->name] = $node->new_value;
+    }
+  }
+  // if the citation is missing then try to generate one
+  if (!$uniquename) {
+    $pub['Title'] = $title;
+    $pub['Publication Type'][0] = $cvterm[0]->name;
+    $pub['Year'] = $pyear;
+    $uniquename = tripal_pub_create_citation($pub);
+    if (!$uniquename) {
+    	form_set_error('uniquename', 'Cannot automatically generate a citation for this publication type. Please add one manually.');
     }
   }
 

+ 48 - 25
tripal_pub/includes/pub_importers.inc

@@ -25,21 +25,21 @@ function tripal_pub_importers_list() {
     }
 
     $rows[] = array(
-    l(t('Edit/Test'), "admin/tripal/tripal_pub/import/edit/$importer->pub_import_id"),
-    $importer->name,
-    $criteria['remote_db'],
-    $criteria_str,
-    $importer->disabled ? 'Yes' : 'No',
-    $importer->do_contact ? 'Yes' : 'No',
-    l(t('Delete'), "admin/tripal/tripal_pub/import/delete/$importer->pub_import_id"),
+      l(t('Edit/Test'), "admin/tripal/tripal_pub/import/edit/$importer->pub_import_id"),
+      $importer->name,
+      $criteria['remote_db'],
+      $criteria_str,
+      $importer->disabled ? 'Yes' : 'No',
+      $importer->do_contact ? 'Yes' : 'No',
+      l(t('Delete'), "admin/tripal/tripal_pub/import/delete/$importer->pub_import_id"),
     );
   }
 
   $rows[] = array(
     'data' => array(
-  array('data' => l(t('Create a new publication importer.'), "admin/tripal/tripal_pub/import/new"),
+     array('data' => l(t('Create a new publication importer.'), "admin/tripal/tripal_pub/import/new"),
         'colspan' => 7),
-  )
+     )
   );
 
   $page = theme('table', $header, $rows);
@@ -54,6 +54,18 @@ function tripal_pub_importer_setup($action = 'new', $pub_import_id = NULL) {
 
   $pager_id = 0;
   $limit = 20;
+  
+  // make sure the tripal_pub and tripal_contact ontologies are loaded
+  $values = array('name' => 'tripal_pub');
+  $tpub_cv = tripal_core_chado_select('cv', array('cv_id'), $values);
+  if (count($tpub_cv) == 0) {
+  	drupal_set_message(t('Before importing publications you must first ') . l(t('load the Tripal Pub Ontology'), 'admin/tripal/tripal_cv/obo_loader'), 'error');
+  }
+  $values = array('name' => 'tripal_contact');
+  $tpub_cv = tripal_core_chado_select('cv', array('cv_id'), $values);
+  if (count($tpub_cv) == 0) {
+    drupal_set_message(t('If you want to create contact pages for authors, you must first ') . l(t('load the Tripal Contact Ontology'), 'admin/tripal/tripal_cv/obo_loader'), 'error');
+  }
 
   // generate the search form
   $form = drupal_get_form('tripal_pub_importer_setup_form',  $pub_import_id, $action);
@@ -309,6 +321,7 @@ function tripal_pub_importer_setup_form(&$form_state = NULL, $pub_import_id = NU
     'NOT' => 'NOT'
     );
     for($i = 1; $i <= $num_criteria; $i++) {
+    	$is_phrase = 1;
 
       // if we have criteria supplied from the database then use that as the initial defaults
       if ($criteria) {
@@ -322,6 +335,7 @@ function tripal_pub_importer_setup_form(&$form_state = NULL, $pub_import_id = NU
       $scope        = isset($_SESSION['tripal_pub_import']['criteria'][$i]['scope'])        ? $_SESSION['tripal_pub_import']['criteria'][$i]['scope']        : $scope;
       $is_phrase    = isset($_SESSION['tripal_pub_import']['criteria'][$i]['is_phrase'])    ? $_SESSION['tripal_pub_import']['criteria'][$i]['is_phrase']    : $is_phrase;
       $operation    = isset($_SESSION['tripal_pub_import']['criteria'][$i]['operation'])    ? $_SESSION['tripal_pub_import']['criteria'][$i]['operation']    : $operation;
+      
       // If the form_state has variables then use those.  This happens when an error occurs on the form or the
       // form is resbumitted using AJAX
       if ($form_state['values']) {
@@ -332,23 +346,24 @@ function tripal_pub_importer_setup_form(&$form_state = NULL, $pub_import_id = NU
       }
 
       $form['criteria'][$i]["search_terms-$i"] = array(
-      '#type'          => 'textfield',
-      '#description'   => t('Please provide a list of words for searching. You may use 
-        conjunctions such as "AND" or "OR" to separate words if they are expected in 
-        the same scope. Uncheck the "Is Phrase" checkbox to use conjunctions'),
-      '#default_value' => $search_terms,
-      '#required'      => TRUE,
+        '#type'          => 'textfield',
+        '#description'   => t('Please provide a list of words for searching. You may use 
+          conjunctions such as "AND" or "OR" to separate words if they are expected in 
+          the same scope, but do not mix ANDs and ORs.  Uncheck the "Is Phrase" checkbox to use conjunctions'),
+        '#default_value' => $search_terms,
+        '#required'      => TRUE,
+        '#maxlength' => 2048,
       );
       $form['criteria'][$i]["scope-$i"] = array(
-      '#type'          => 'select',
-      '#description'   => t('Please select the fields to search for this term.'),
-      '#options'       => $scope_choices,
-      '#default_value' => $scope,
+        '#type'          => 'select',
+        '#description'   => t('Please select the fields to search for this term.'),
+        '#options'       => $scope_choices,
+        '#default_value' => $scope,
       );
       $form['criteria'][$i]["is_phrase-$i"] = array(
-      '#type'    => 'checkbox',
-      '#title'   => t('Is Phrase?'),    
-      '#default_value' => $is_phrase,
+        '#type'    => 'checkbox',
+        '#title'   => t('Is Phrase?'),    
+        '#default_value' => $is_phrase,
       );
 
       if ($i == 1) {
@@ -416,7 +431,7 @@ function tripal_pub_importer_setup_form(&$form_state = NULL, $pub_import_id = NU
 
     // allow the selected remote database to make changes to the form if needed
     $callback = "tripal_pub_remote_alter_form_$remote_db";
-    call_user_func($callback, &$form, $form_state);
+    $form = call_user_func($callback, $form, $form_state);
 
     return $form;
 }
@@ -437,14 +452,22 @@ function tripal_pub_importer_setup_form_validate($form, &$form_state) {
     $scope =  $form_state['values']["scope-$i"];
     $is_phrase =  $form_state['values']["is_phrase-$i"];
     $operation =  $form_state['values']["operation-$i"];
+    
+    if (!$is_phrase) {
+    	if (preg_match('/and/i', $search_terms) and preg_match('/or/i', $search_terms)) {
+    	  form_set_error("search_terms-$i", "You may use 'AND' or 'OR' but cannot use both. Add a new entry below with the same scope for the other conunction.");
+    	  $_SESSION['tripal_pub_import']['perform_search'] = 0;	
+    	}
+    }
   }
 
   if ($days and !is_numeric($days) or preg_match('/\./', $days)) {
     form_set_error("days", "Please enter a numeric, non decimal value, for the number of days.");
+    $_SESSION['tripal_pub_import']['perform_search'] = 0;
   }
   // allow the selected remote database to validate any changes to the form if needed
   $callback = "tripal_pub_remote_validate_form_$remote_db";
-  call_user_func($callback, &$form, $form_state);
+  $form = call_user_func($callback, $form, $form_state);
 }
 
 /**
@@ -600,4 +623,4 @@ function tripal_pub_importer_setup_page_update_criteria($action, $i) {
       'settings' => $settings,
   )
   );
-}
+}

+ 50 - 1
tripal_pub/includes/tripal_pub.admin.inc

@@ -20,6 +20,7 @@ function tripal_pub_admin() {
   if (!$active_jobs) {
     get_tripal_pub_admin_form_select_search_list($form);
     get_tripal_pub_admin_form_importing_set($form);
+    get_tripal_pub_admin_form_default_type($form);
     get_tripal_pub_admin_form_cleanup_set($form);
   }
   else {
@@ -34,6 +35,51 @@ function tripal_pub_admin() {
 
   return system_settings_form($form);
 }
+
+/**
+ * 
+ * @param $form
+ */
+function get_tripal_pub_admin_form_default_type(&$form) {
+
+  // get the list of publication types.  In the Tripal publication
+  // ontologies these are all grouped under the term 'Publication Type'
+  // we want the default to be 'Journal Article'
+  $sql = "
+    SELECT CVTS.cvterm_id, CVTS.name
+    FROM {cvtermpath} CVTP
+      INNER JOIN {cvterm} CVTS ON CVTP.subject_id = CVTS.cvterm_id
+      INNER JOIN {cvterm} CVTO ON CVTP.object_id = CVTO.cvterm_id
+      INNER JOIN {cv} ON CVTO.cv_id = CV.cv_id
+    WHERE CV.name = 'tripal_pub' and CVTO.name = 'Publication Type' and 
+      NOT CVTS.is_obsolete = 1
+    ORDER BY CVTS.name ASC 
+  ";
+  $results = chado_query($sql);
+  $pub_types = array();
+  while ($pub_type = db_fetch_object($results)) {
+    $pub_types[$pub_type->cvterm_id] = $pub_type->name;
+    if (strcmp($pub_type->name,"Journal Article") == 0) {
+      $d_type_id = $pub_type->cvterm_id;
+    }
+  }
+  
+  // override the default by using the stored variable
+  $d_type_id = variable_get('tripal_pub_default_type', $d_type_id);
+  
+  $form['default_type'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Default Publication Type'),
+  );
+  $form['default_type']['type_id'] = array(
+    '#type' => 'select',
+    '#title' => t('Publication Type'),
+    '#options' => $pub_types,
+    '#description' => t('Please set a default publiation type used for manual entry of a new publication.  This is useful in the event that someone is manually adding the same
+      publication repetitively'),
+    '#default_value' => $d_type_id
+  );
+}
 /**
  *
  *
@@ -51,7 +97,7 @@ function get_tripal_pub_admin_form_importing_set(&$form) {
       'title_year' => t('Title and Year'), 
       'title_year_media' => t('Title, Year, Media name (e.g. Journal Name, etc.)'), 
       'title_year_type' => t('Title, Year, Media type (e.g. Journal, Conference Proceedings, etc.'),
-  ),
+    ),
     '#description' => t('During import, Tripal will attempt to find duplicate publications. 
        There are several options for how to find a duplicate publication.  Choose the
        option that best suits your needs.'),
@@ -142,6 +188,9 @@ function tripal_pub_admin_validate($form, &$form_state) {
 
   $import_duplicate_check = $form_state['values']['import_duplicate_check'];
   variable_set('tripal_pub_import_duplicate_check', $import_duplicate_check);
+  
+  $default_type = $form_state['values']['type_id'];
+  variable_set('tripal_pub_default_type', $default_type);
 
   // -------------------------------------
   // Submit the Cleanup Job if selected

+ 22 - 21
tripal_pub/tripal_pub.install

@@ -59,16 +59,17 @@ function tripal_pub_schema() {
       'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
       'pub_id' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
       'sync_date' => array('type' => 'int', 'not null' => FALSE, 'description' => 'UNIX integer sync date/time'),
-  ),
+    ),
     'indexes' => array(
       'pub_id' => array('pub_id')
-  ),
+    ),
     'unique keys' => array(
       'nid_vid' => array('nid', 'vid'),
       'vid' => array('vid')
-  ),
+    ),
     'primary key' => array('nid'),
   );
+  
   $schema['tripal_pub_import'] = array(
     'fields' => array(
       'pub_import_id' => array('type' => 'serial', 'not null' => TRUE),
@@ -76,11 +77,11 @@ function tripal_pub_schema() {
       'criteria' => array('type' => 'text', 'size' => 'normal', 'not null' => TRUE, 'description' => 'Contains a serialized PHP array containing the search criteria'),
       'disabled'  => array('type' => 'int', 'unsigned' => TRUE, 'not NULL' => TRUE, 'default' => 0),      
       'do_contact'  => array('type' => 'int', 'unsigned' => TRUE, 'not NULL' => TRUE, 'default' => 0),
-  ),
+    ),
     'primary key' => array('pub_import_id'),
     'indexes' => array(
       'name' => array('name')
-  ),
+    ),
   );
    
   return $schema;
@@ -116,39 +117,39 @@ function tripal_pub_add_custom_tables() {
       'pubauthor_contact_id' => array (
         'type' => 'serial',
         'not null' => true,
-  ),
+      ),
       'contact_id' => array (
         'type' => 'int',
         'not null' => true,
-  ),
+      ),
       'pubauthor_id' => array (
         'type' => 'int',
         'not null' => true,
-  ),
-  ),
+      ),
+    ),
     'primary key' => array (
-  0 => 'pubauthor_contact_id',
-  ),
+      0 => 'pubauthor_contact_id',
+    ),
     'unique keys' => array (
       'pubauthor_contact_c1' => array (
-  0 => 'contact_id',
-  1 => 'pubauthor_id',
-  ),
-  ),
+        0 => 'contact_id',
+        1 => 'pubauthor_id',
+      ),
+    ),
     'foreign keys' => array (
       'contact' => array (
         'table' => 'contact',
         'columns' => array (
           'contact_id' => 'contact_id',
-  ),
-  ),
+        ),
+      ),
       'pubauthor' => array (
         'table' => 'pubauthor',
         'columns' => array (
           'pubauthor_id' => 'pubauthor_id',
-  ),
-  ),
-  ),
+        ),
+      ),
+    ),
   );
-  tripal_core_create_custom_table(&$ret, 'pubauthor_contact', $schema, TRUE);
+  tripal_core_create_custom_table($ret, 'pubauthor_contact', $schema, TRUE);
 }

+ 51 - 3
tripal_pub/tripal_pub.module

@@ -6,6 +6,7 @@ require_once "includes/pub_sync.inc";
 require_once "includes/pub_form.inc";
 require_once "includes/pub_importers.inc";
 require_once "includes/pub_search.inc";
+require_once "includes/pub_citation.inc";
 require_once "includes/importers/PMID.inc";
 require_once "includes/importers/AGL.inc";
 /**
@@ -174,6 +175,14 @@ function tripal_pub_menu() {
     'type ' => MENU_CALLBACK,
   );
 
+  $items['admin/tripal/tripal_pub/citation'] = array(
+      'title' => ' Create Citations',
+      'description' => 'Create citations in Chado with Drupal',
+      'page callback' => 'drupal_get_form',
+      'page arguments' => array('tripal_pub_citation_form'),
+      'access arguments' => array('administer tripal pubs'),
+      'type' => MENU_NORMAL_ITEM,
+  );
 
   return $items;
 }
@@ -274,7 +283,10 @@ function tripal_pub_perm() {
  *  A user object representing the user for whom the operation is to be performed
  *
  *  @return
- *  TRUE
+ *  If the permission for the specified operation is not set then return FALSE. If the
+ *  permission is set then return NULL as this allows other modules to disable
+ *  access.  The only exception is when the $op == 'create'.  We will always 
+ *  return TRUE if the permission is set.
  *
  */
 function chado_pub_access($op, $node, $account ) {
@@ -282,6 +294,7 @@ function chado_pub_access($op, $node, $account ) {
     if (!user_access('create chado_pub content', $account)) {
       return FALSE;
     }
+    return TRUE;
   }
 
   if ($op == 'update') {
@@ -319,6 +332,10 @@ function chado_pub_access($op, $node, $account ) {
  */
 function chado_pub_insert($node) {
 
+	// 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();
+	
   // if a pub_id already exists for this node then it already exists in Chado and
   // we get here because we are syncing the node.  Therefore, we can skip the insert
   // but we always want to set the URL path alias to be the Chado pub ID
@@ -373,8 +390,13 @@ function chado_pub_insert($node) {
 
     // iterate through all of the properties and remove those that really are
     // part of the pub table fields
-    foreach ($properties as $name => $element) {
+    foreach ($properties as $name => $element) {    	    
       $value = trim($element[0]);
+      
+    	// populate our $pub_array for building a citation
+    	$pub_arr[$name] = $value;
+    	
+      // remove properties that are stored in the pub table
       if ($name == "Volume") {
         $volume = $value;
         unset($properties[$name]);
@@ -409,7 +431,16 @@ function chado_pub_insert($node) {
         $cross_refs[] = $value;
       }
     }
-
+    // generate a citation for this pub if one doesn't already exist 
+    if (!$node->uniquename and array_key_exists('Citation', $properties)) {
+    	$pub_type = tripal_cv_get_cvterm_by_id($node->type_id);
+    	$pub_arr['Title'] = $node->pubtitle;
+      $pub_arr['Publication Type'][0] = $pub_type->name;
+      $pub_arr['Year'] = $node->pyear;
+      $node->uniquename = tripal_pub_create_citation($pub_arr);
+      $properties['Citation'][0] = $node->uniquename;
+    }
+    
     // insert the pub record
     $values = array(
       'title'       => trim($node->pubtitle),
@@ -493,6 +524,10 @@ function chado_pub_update($node) {
     // there is no way to handle revisions in Chado but leave
     // this here just to make not we've addressed it.
   }
+  
+  // 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();
 
   // get the publication ID for this publication
   $pub_id = chado_get_id_for_node('pub', $node->nid) ;
@@ -554,6 +589,10 @@ function chado_pub_update($node) {
   // part of the pub table fields
   foreach ($properties as $name => $element) {
     foreach ($element as $index => $value) {
+    	// populate our $pub_array for building a citation
+      $pub_arr[$name] = $value;
+      
+      // remove properties that are stored in the pub table
       if ($name == "Volume") {
         $volume = $value;
         unset($properties[$name]);
@@ -589,6 +628,15 @@ function chado_pub_update($node) {
       }
     }
   }
+  // generate a citation for this pub if one doesn't already exist 
+  if (!$node->uniquename) {
+    $pub_type = tripal_cv_get_cvterm_by_id($node->type_id);
+    $pub_arr['Title'] = $node->pubtitle;
+    $pub_arr['Publication Type'][0] = $pub_type->name;
+    $pub_arr['Year'] = $node->pyear;
+    $node->uniquename = tripal_pub_create_citation($pub_arr);
+    $properties['Citation'][0] = $node->uniquename;
+  }
 
   // update the pub record
   $match = array(

+ 372 - 0
tripal_pub/tripal_pub.views.inc

@@ -10,3 +10,375 @@
  *  http://views2.logrus.com/doc/html/index.html.
  */
 
+/**
+ *
+ * @ingroup tripal_pub_views
+ */
+function tripal_pub_views_default_views() {
+  $views = array();
+
+  if (!module_exists('tripal_views')) {
+    return $views;
+  }
+
+  // Main default view
+  $view = new view;
+  $view->name = 'pub_listing';
+  $view->description = 'This view lists all pubs by default.';
+  $view->tag = 'chado default';
+  $view->base_table = 'pub';
+  $view->core = 0;
+  $view->api_version = '2';
+  $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+  $handler = $view->new_display('default', 'Defaults', 'default');
+  $handler->override_option('fields', array(
+    'title' => array(
+      'label' => 'Title',
+      'alter' => array(
+        'alter_text' => 0,
+        'text' => '',
+        'make_link' => 0,
+        'path' => '',
+        'link_class' => '',
+        'alt' => '',
+        'prefix' => '',
+        'suffix' => '',
+        'target' => '',
+        'help' => '',
+        'trim' => 0,
+        'max_length' => '',
+        'word_boundary' => 1,
+        'ellipsis' => 1,
+        'html' => 0,
+        'strip_tags' => 0,
+      ),
+      'empty' => '',
+      'hide_empty' => 0,
+      'empty_zero' => 0,
+      'link_to_node' => 1,
+      'exclude' => 0,
+      'id' => 'title',
+      'table' => 'pub',
+      'field' => 'title',
+      'relationship' => 'none',
+    ),
+    'pyear' => array(
+      'label' => 'Year',
+      'alter' => array(
+        'alter_text' => 0,
+        'text' => '',
+        'make_link' => 0,
+        'path' => '',
+        'link_class' => '',
+        'alt' => '',
+        'prefix' => '',
+        'suffix' => '',
+        'target' => '',
+        'help' => '',
+        'trim' => 0,
+        'max_length' => '',
+        'word_boundary' => 1,
+        'ellipsis' => 1,
+        'html' => 0,
+        'strip_tags' => 0,
+      ),
+      'empty' => '',
+      'hide_empty' => 0,
+      'empty_zero' => 0,
+      'exclude' => 0,
+      'id' => 'name',
+      'table' => 'pub',
+      'field' => 'pyear',
+      'relationship' => 'none',
+    ),
+    'type' => array(
+      'label' => 'Type',
+      'alter' => array(
+        'alter_text' => 0,
+        'text' => '',
+        'make_link' => 0,
+        'path' => '',
+        'link_class' => '',
+        'alt' => '',
+        'prefix' => '',
+        'suffix' => '',
+        'target' => '',
+        'help' => '',
+        'trim' => 0,
+        'max_length' => '',
+        'word_boundary' => 1,
+        'ellipsis' => 1,
+        'html' => 0,
+        'strip_tags' => 0,
+      ),
+      'empty' => '',
+      'hide_empty' => 0,
+      'empty_zero' => 0,
+      'exclude' => 0,
+      'id' => 'type',
+      'table' => 'cvterm',
+      'field' => 'name',
+      'relationship' => 'none',
+    ),
+  ));
+  $handler->override_option('sorts', array(
+    'pyear' => array(
+      'order' => 'ASC',
+      'id' => 'year',
+      'table' => 'pub',
+      'field' => 'pyear',
+      'relationship' => 'none',
+    ),
+    'title' => array(
+      'order' => 'ASC',
+      'id' => 'title',
+      'table' => 'pub',
+      'field' => 'title',
+      'relationship' => 'none',
+    ),
+    'type' => array(
+      'order' => 'ASC',
+      'id' => 'type',
+      'table' => 'cvterm',
+      'field' => 'name',
+      'relationship' => 'none',
+    ),
+  ));
+  $handler->override_option('filters', array(
+    'search_results' => array(
+      'operator' => '=',
+      'value' => '',
+      'group' => '0',
+      'exposed' => FALSE,
+      'expose' => array(
+        'operator' => FALSE,
+        'label' => '',
+      ),
+      'id' => 'search_results',
+      'table' => 'views',
+      'field' => 'search_results',
+      'relationship' => 'none',
+      'apply_button' => 'Show',
+      'no_results_text' => 'Click "Show" to see a list of all pubs matching the entered criteria. If you leave a any of the criteria blank then the pubs will be not be filtered based on that field. Furthermore, if you leave all criteria blank then all pubs will be listed.',
+    ),
+    'title' => array(
+      'operator' => '=',
+      'value' => array(),
+      'group' => '0',
+      'exposed' => TRUE,
+      'expose' => array(
+        'use_operator' => 0,
+        'operator' => 'title_op',
+        'identifier' => 'pub_title',
+        'label' => 'Title',
+        'remember' => 0,
+      ),
+      'case' => 1,
+      'id' => 'title',
+      'table' => 'pub',
+      'field' => 'title',
+      'relationship' => 'none',
+    ),
+    'type_id' => array(
+      'operator' => '=',
+      'value' => '',
+      'group' => '0',
+      'exposed' => TRUE,
+      'expose' => array(
+        'use_operator' => 0,
+        'operator' => 'type_id_op',
+        'identifier' => 'type_id',
+        'label' => 'Type',
+        'remember' => 0,
+      ),
+      'case' => 1,
+      'id' => 'type_id',
+      'table' => 'pub',
+      'field' => 'type_id',
+      'relationship' => 'none',
+      'values_form_type' => 'select',
+      'multiple' => 1,
+      'optional' => 0,
+      'show_all' => 0,
+      'agg' => array(
+        'records_with' => 1,
+        'aggregates_with' => 1,
+      ),
+    ),
+    'year' => array(
+      'operator' => '=',
+      'value' => '',
+      'group' => '0',
+      'exposed' => TRUE,
+      'expose' => array(
+        'use_operator' => 0,
+        'operator' => 'name_op',
+        'identifier' => 'name',
+        'label' => 'Name Contains',
+        'remember' => 0,
+      ),
+      'case' => 0,
+      'id' => 'name',
+      'table' => 'pub',
+      'field' => 'name',
+      'relationship' => 'none',
+      'values_form_type' => 'select',
+      'multiple' => 1,
+      'optional' => 0,
+      'show_all' => 0,
+      'agg' => array(
+        'records_with' => 1,
+        'aggregates_with' => 1,
+      ),
+    ),
+  ));
+  $handler->override_option('access', array(
+    'type' => 'perm',
+    'perm' => 'access chado_pub content',
+  ));
+  $handler->override_option('cache', array(
+    'type' => 'none',
+  ));
+  $handler->override_option('title', 'Publications');
+  $handler->override_option('header', 'Click "Show" to see a list of all publications matching the entered criteria. If you leave a any of the criteria blank then the pubs will be not be filtered based on that field. Furthermore, if you leave all criteria blank then all publications will be listed.');
+  $handler->override_option('header_format', '2');
+  $handler->override_option('header_empty', 0);
+  $handler->override_option('empty', 'No publications match the supplied criteria.');
+  $handler->override_option('empty_format', '1');
+  $handler->override_option('items_per_page', 50);
+  $handler->override_option('use_pager', '1');
+  $handler->override_option('style_plugin', 'table');
+  $handler->override_option('style_options', array(
+    'grouping' => '',
+    'override' => 1,
+    'sticky' => 0,
+    'order' => 'asc',
+    'columns' => array(
+      'title' => 'title',
+      'pyear' => 'pyear',
+      'type' => 'type',
+      'all_dbxref' => 'all_dbxref',
+      'all_properties' => 'all_properties',
+      'all_relationships' => 'all_relationships',
+    ),
+    'info' => array(
+      'title' => array(
+        'sortable' => 1,
+        'separator' => '',
+      ),
+      'type' => array(
+        'sortable' => 1,
+        'separator' => '',
+      ),
+      'pyear' => array(
+        'sortable' => 1,
+        'separator' => '',
+      ),
+      'all_dbxref' => array(
+        'separator' => '',
+      ),
+      'all_properties' => array(
+        'separator' => '',
+      ),
+      'all_relationships' => array(
+        'separator' => '',
+      ),
+    ),
+    'default' => '-1',
+  ));
+  $default_handler = $handler;
+  $handler = $view->new_display('page', 'Page', 'page_1');
+  $handler->override_option('path', 'chado/pubs');
+  $handler->override_option('menu', array(
+    'type' => 'normal',
+    'title' => 'Publications',
+    'description' => 'A published article, book, conference proceeding, etc.',
+    'weight' => '10',
+    'name' => 'navigation',
+  ));
+  $handler->override_option('tab_options', array(
+    'type' => 'none',
+    'title' => '',
+    'description' => '',
+    'weight' => 0,
+    'name' => 'navigation',
+  ));
+  // Add code specific to a local chado installation
+  // NOTE: Edit $handler above to $default_handler for the default display
+  if (tripal_core_chado_schema_exists()) {
+    // Add nid field
+    $fields = $view->get_items('field', 'default');
+    $new_fields = array(
+      'nid' => array(
+        'label' => 'Nid',
+        'alter' => array(
+          'alter_text' => 0,
+          'text' => '',
+          'make_link' => 0,
+          'path' => '',
+          'absolute' => 0,
+          'link_class' => '',
+          'alt' => '',
+          'rel' => '',
+          'prefix' => '',
+          'suffix' => '',
+          'target' => '',
+          'help' => '',
+          'trim' => 0,
+          'max_length' => '',
+          'word_boundary' => 1,
+          'ellipsis' => 1,
+          'html' => 0,
+          'strip_tags' => 0,
+        ),
+        'empty' => '',
+        'hide_empty' => 0,
+        'empty_zero' => 0,
+        'hide_alter_empty' => 1,
+        'link_to_node' => 0,
+        'exclude' => 1,
+        'id' => 'nid',
+        'table' => 'node',
+        'field' => 'nid',
+        'relationship' => 'none',
+      )
+    );
+    $fields = $new_fields + $fields;
+    // Change analysis.name to have a link to the node
+    $fields['name_2']['alter']['link_to_node'] = 1;
+    $default_handler->override_option('fields', $fields);
+    // Adds pub => Node relationship
+    $default_handler->override_option('relationships', array(
+      'nid' => array(
+        'label' => 'Publication to Node',
+        'required' => 0,
+        'id' => 'nid',
+        'table' => 'chado_pub',
+        'field' => 'nid',
+        'relationship' => 'none',
+      ),
+    ));
+    // Only show records with published nodes
+    /**
+    $filters = $view->get_items('filter', 'default');
+    $filters['status'] = array(
+      'operator' => '=',
+      'value' => '1',
+      'group' => '0',
+      'exposed' => FALSE,
+      'expose' => array(
+        'operator' => FALSE,
+        'label' => '',
+      ),
+      'id' => 'status',
+      'table' => 'node',
+      'field' => 'status',
+      'relationship' => 'none',
+    );
+    $default_handler->override_option('filters', $filters);
+    */
+  }
+  $views[$view->name] = $view;
+
+  return $views;
+}

+ 18 - 9
tripal_stock/tripal_stock.module

@@ -167,17 +167,25 @@ function tripal_stock_perm() {
 }
 
 /**
- * Implements hook_access(): Maps permission catagories to actions
+ * Implement hook_access().
  *
- * @param $op
- *   The operation current operation: one of create, update, delete
- * @param $node
- *   The node object the current operation is being performed on
- * @param $account
- *   A user object representing the user for whom the operation is to be performed
+ * This hook allows node modules to limit access to the node types they define.
  *
- * @return
- *   TRUE grants access; FALSE denies it
+ *  @param $op
+ *  The operation to be performed
+ *
+ *  @param $node
+ *  The node on which the operation is to be performed, or, if it does not yet exist, the
+ *  type of node to be created
+ *
+ *  @param $account
+ *  A user object representing the user for whom the operation is to be performed
+ *
+ *  @return
+ *  If the permission for the specified operation is not set then return FALSE. If the
+ *  permission is set then return NULL as this allows other modules to disable
+ *  access.  The only exception is when the $op == 'create'.  We will always 
+ *  return TRUE if the permission is set.
  *
  * @ingroup tripal_stock
  */
@@ -186,6 +194,7 @@ function chado_stock_access($op, $node, $account) {
     if (!user_access('create chado_stock content', $account)) {
       return FALSE;
     }
+    return TRUE;
   }
   if ($op == 'update') {
     if (!user_access('edit chado_stock content', $account)) {

+ 1 - 1
tripal_views/api/tripal_views.api.inc

@@ -617,7 +617,7 @@ function tripal_views_get_integration_array_for_chado_table($table_name, $base_t
 /**
  * Adds the joins necessary to link a chado table to it's node counterpart
  *
- * @param &$defn_array
+ * @param $defn_array
  *   The current definition array for a given table
  *
  * @ingroup tripal_views_api

+ 3 - 3
tripal_views/includes/tripal_views_integration.inc

@@ -196,7 +196,7 @@ function tripal_views_integration_delete($setup_id) {
  *   handlers when integrating a table with views.  This form is used for both
  *   creating a new record and editing an existing record.
  *
- * @param &$form_state
+ * @param $form_state
  *    The form state which is passed automatically by drupal
  *
  * @param $setup_id
@@ -847,7 +847,7 @@ function tripal_views_integration_form(&$form_state, $setup_id = NULL) {
  * @param $form
  *    The form object which is passed automatically by drupal
  *
- * @param &$form_state
+ * @param $form_state
  *    The form state pbject which is passed automatically by drupal
  *
  * @ingroup tripal_views_integration
@@ -883,7 +883,7 @@ function tripal_views_integration_form_validate($form, &$form_state) {
  * @param $form
  *    The form object which is passed automatically by drupal
  *
- * @param &$form_state
+ * @param $form_state
  *    The form state pbject which is passed automatically by drupal
  *
  * @ingroup tripal_views_integration