Procházet zdrojové kódy

Updated modules with nodes to use new sync functionality. Working on supporting checkboxes in syncing as well... not quite done

Stephen Ficklin před 11 roky
rodič
revize
0bd1f019a7

+ 75 - 1
tripal_analysis/includes/tripal_analysis.chado_node.inc

@@ -1,4 +1,35 @@
-<?php 
+<?php
+/**
+ * Provide information to drupal about the node types that we're creating
+ * in this module
+ *
+ * @ingroup tripal_analysis
+ */
+function tripal_analysis_node_info() {
+  $nodes = array();
+  $nodes['chado_analysis'] = array(
+    'name' => t('Analysis'),
+    'base' => 'chado_analysis',
+    'description' => t('An analysis'),
+    'has_title' => FALSE,
+    'title_label' => t('Analysis'),
+    'locked' => TRUE,
+    'chado_node_api' => array(
+      'base_table' => 'analysis',
+      'hook_prefix' => 'chado_analysis',
+      'record_type_title' => array(
+        'singular' => t('Analysis'),
+        'plural' => t('Analyses')
+      ),
+      'sync_filters' => array(
+        'type_id' => FALSE,
+        'organism_id' => FALSE,
+        'checkboxes' => array('name'),
+      ),
+    )
+  );
+  return $nodes;
+} 
 /**
  *  When editing or creating a new node of type 'chado_analysis' we need
  *  a form.  This function creates the form that will be used for this.
@@ -567,4 +598,47 @@ function chado_analysis_node_access($node, $op, $account) {
     }
   }
   return NULL;
+}
+/**
+ *
+ * @ingroup tripal_analysis
+ */
+function tripal_analysis_node_view($node, $view_mode, $langcode) {
+  switch ($node->type) {
+    case 'chado_analysis':
+      // Show feature browser and counts
+      if ($view_mode == 'full') {
+        $node->content['tripal_analysis_base'] = array(
+          '#value' => theme('tripal_analysis_base', array('node' => $node)),
+        );
+        $node->content['tripal_analysis_properties'] = array(
+          '#value' => theme('tripal_analysis_properties', array('node' => $node)),
+        );
+      }
+      if ($view_mode == 'teaser') {
+        $node->content['tripal_analysis_teaser'] = array(
+          '#value' => theme('tripal_analysis_teaser', array('node' => $node)),
+        );
+      }
+      break;
+  }
+}
+/**
+ *
+ * @param $node
+ */
+function tripal_analysis_node_presave($node) {
+  // If this is an analysis of some type it will should have thre three required
+  // fields for the Chado analysis table: program, programversion and sourcename.
+  // So we will set the title for any node that has these three fields
+  if (property_exists($node, 'program') and
+  property_exists($node, 'programversion') and
+  property_exists($node, 'sourcename')) {
+    if ($node->analysisname) {
+      $node->title = $node->analysisname;
+    }
+    else {
+      $node->title = "$node->program ($node->programversion) $node->sourcename";
+    }
+  }
 }

+ 0 - 221
tripal_analysis/includes/tripal_analysis.sync.inc

@@ -1,221 +0,0 @@
-<?php 
-
-/**
- * 
- */
-function tripal_analysis_sync_form () {
-  $form = array();
-  
-  // define the fieldsets
-  $form['sync'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Sync Analyses')
-  );
-
-  // get the list of analyses
-  $sql = "SELECT * FROM {analysis} ORDER BY name";
-  $ana_rset = chado_query($sql);
-
-  // if we've added any analyses to the list that can be synced
-  // then we want to build the form components to allow the user
-  // to select one or all of them.  Otherwise, just present
-  // a message stating that all analyses are currently synced.
-  $ana_boxes = array();
-  $added = 0;
-  while ($analysis = $ana_rset->fetchObject()) {
-    // check to see if the analysis is already present as a node in drupal.
-    // if so, then skip it.
-    $sql = "SELECT * FROM {chado_analysis} WHERE analysis_id = :analysis_id";
-    if (!db_query($sql, array(':analysis_id' => $analysis->analysis_id))->fetchObject()) {
-      $ana_boxes[$analysis->analysis_id] = "$analysis->name";
-      $added++;
-    }
-  }
-
-  // if we have analyses we need to add to the checkbox then
-  // build that form element
-  if ($added > 0) {
-    $ana_boxes['all'] = "All analyses";
-
-    $form['sync']['analyses'] = array(
-      '#title'       => t('Available analyses'),
-      '#type'        => t('checkboxes'),
-      '#description' => t("Check the analyses you want to sync.  Drupal " .
-          "content will be created for each of the analyses listed above. " .
-          "Select 'All analyses' to sync all of them."),
-      '#required'    => FALSE,
-      '#prefix'      => '<div id="ana_boxes">',
-      '#suffix'      => '</div>',
-      '#options'     => $ana_boxes,
-    );
-    $form['sync']['button'] = array(
-      '#type' => 'submit',
-      '#value' => t('Submit Sync Job')
-    );
-  }
-  // we don't have any analyses to select from
-  else {
-    $form['sync']['value'] = array(
-      '#markup' => t('All analyses in Chado are currently synced with Drupal.')
-    );
-  }
-  
-  $form['cleanup'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Clean Up')
-  );
-  $form['cleanup']['description'] = array(
-    '#markup' => t("With Drupal and chado residing in different databases " .
-        "it is possible that nodes in Drupal and analyses in Chado become " .
-        "\"orphaned\".  This can occur if an analysis node in Drupal is " .
-        "deleted but the corresponding chado analysis is not and/or vice " .
-        "versa. Click the button below to resolve these discrepancies."),
-    '#weight' => 1,
-  );
-  $form['cleanup']['button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Clean up orphaned analyses'),
-    '#weight' => 2,
-  );
-  
-  return $form;
-}
-
-/**
- * Validate the administrative form
- *
- * @param $form
- *   The form API array of the form to be validated
- * @form_state
- *   The user submitted values
- *
- * @ingroup tripal_analysis
- */
-function tripal_analysis_sync_form_submit($form, &$form_state) {
-  global $user;  // we need access to the user info
-  $job_args = array();
-
-  if ($form_state['values']['op'] == t('Submit Sync Job')) {
-
-    // check to see if the user wants to sync chado and drupal.  If
-    // so then we need to register a job to do so with tripal
-    $analyses = $form_state['values']['analyses'];
-    $do_all = FALSE;
-    $to_sync = array();
-
-    foreach ($analyses as $analysis_id) {
-      if (preg_match("/^all$/i", $analysis_id)) {
-        $do_all = TRUE;
-      }
-      if ($analysis_id and preg_match("/^\d+$/i", $analysis_id)) {
-        // get the list of analyses
-        $sql = "SELECT * FROM {analysis} WHERE analysis_id = :analysis_id";
-        $analysis = chado_query($sql, array(':analysis_id' => $analysis_id))->fetchObject();
-        $to_sync[$analysis_id] = $analysis->name;
-      }
-    }
-
-    // submit the job the tripal job manager
-    if ($do_all) {
-      tripal_add_job('Sync all analyses', 'tripal_analysis', 'tripal_analysis_sync_analyses', $job_args, $user->uid);
-    }
-    else{
-      foreach ($to_sync as $analysis_id => $name) {
-        $job_args[0] = $analysis_id;
-        tripal_add_job("Sync analysis: $name", 'tripal_analysis', 'tripal_analysis_sync_analyses', $job_args, $user->uid);
-      }
-    }
-  }  
-  // -------------------------------------
-  // Submit the Cleanup Job if selected
-  if ($form_state['values']['op'] == t('Clean up orphaned analyses')) {
-    tripal_add_job('Cleanup orphaned analyses', 'tripal_analysis',
-    'tripal_analyses_cleanup', $job_args, $user->uid);
-  }
-}
-/**
- * Synchronize analyses from chado to drupal
- *
- * @ingroup tripal_analysis
- */
-function tripal_analysis_sync_analyses($analysis_id = NULL, $job_id = NULL) {
-  global $user;
-  $page_content = '';
-
-  if (!$analysis_id) {
-    $sql = "SELECT * FROM {analysis}";
-    $results = chado_query($sql);
-  }
-  else {
-    $sql = "SELECT * FROM {analysis} WHERE analysis_id = :analysis_id";
-    $results = chado_query($sql, array(':analysis_id' => $analysis_id));
-  }
-
-  // We'll use the following SQL statement for checking if the analysis
-  // already exists as a drupal node.
-  $sql = "SELECT * FROM {chado_analysis} WHERE analysis_id = :analysis_id";
-
-  foreach ($results as $analysis) {
-
-    // check if this analysis already exists in the drupal database. if it
-    // does then skip this analysis and go to the next one.
-    if (!db_query($sql, array(':analysis_id' => $analysis->analysis_id))->fetchObject()) {
-
-      $new_node = new stdClass();
-      $new_node->type = 'chado_analysis';
-      $new_node->uid = $user->uid;
-      $new_node->analysis_id    = $analysis->analysis_id;
-      $new_node->analysisname   = $analysis->name;
-      $new_node->description    = $analysis->description;
-      $new_node->program        = $analysis->program;
-      $new_node->programversion = $analysis->programversion;
-      $new_node->algorithm      = $analysis->algorithm;
-      $new_node->sourcename     = $analysis->sourcename;
-      $new_node->sourceversion  = $analysis->sourceversion;
-      $new_node->sourceuri      = $analysis->sourceuri;
-      $new_node->timeexecuted   = $analysis->timeexecuted;
-
-      // If the analysis has a name, use it as the node title. If not,
-      // construct the title using program, programversion, and sourcename
-      if ($new_node->analysisname) {
-        $new_node->title = $new_node->analysisname;
-      }
-      else {
-        // Construct node title as "program (version)"
-        $new_node->title = "$analysis->program ($analysis->programversion)";
-      }
-      
-      $form = array(); // dummy variable
-      $form_state = array(); // dummy variable
-      node_validate($new_node, $form, $form_state);
-      if (!form_get_errors()) {
-        $node = node_submit($new_node);
-        node_save($node);
-        if ($node->nid) {
-          print "Added $new_node->title\n";
-        }
-      }
-      else {
-        print "Failed to insert analysis $analysis->name\n";
-        watchdog('tanalysis_sync', "Unable to create analysis node. ID: %analysis_id, Name: %name.",
-         array('%analysis_id' => $analysis->analysis_id, '%name' => $analysis->name), WATCHDOG_WARNING);
-      }
-    }
-  }
-}
-
-/**
- * Remove orphaned drupal nodes
- *
- * @param $dummy
- *   Not Used -kept for backwards compatibility
- * @param $job_id
- *   The id of the tripal job executing this function
- *
- * @ingroup tripal_analysis
- */
-function tripal_analyses_cleanup($dummy = NULL, $job_id = NULL) {
-
-  return tripal_core_chado_node_cleanup_orphaned('analysis', $job_id);
-
-}

+ 8 - 67
tripal_analysis/tripal_analysis.module

@@ -18,7 +18,6 @@ require_once 'api/tripal_analysis.api.inc';
 require_once 'includes/tripal_analysis_privacy.inc';
 require_once 'includes/tripal_analysis.admin.inc';
 require_once 'includes/tripal_analysis.chado_node.inc';
-require_once 'includes/tripal_analysis.sync.inc';
 require_once "api/tripal_analysis.schema.api.inc";
 
 
@@ -32,24 +31,7 @@ function tripal_analysis_init() {
   drupal_add_css(drupal_get_path('module', 'tripal_analysis') . '/theme/css/tripal_analysis.css');
 }
 
-/**
- * Provide information to drupal about the node types that we're creating
- * in this module
- *
- * @ingroup tripal_analysis
- */
-function tripal_analysis_node_info() {
-  $nodes = array();
-  $nodes['chado_analysis'] = array(
-      'name' => t('Analysis'),
-      'base' => 'chado_analysis',
-      'description' => t('An analysis'),
-      'has_title' => FALSE,
-      'title_label' => t('Analysis'),
-      'locked' => TRUE
-  );
-  return $nodes;
-}
+
 /**
  * Implementation of hook_menu().
  * Entry points and paths of the module
@@ -88,13 +70,13 @@ function tripal_analysis_menu() {
   );
 
   $items['admin/tripal/chado/tripal_analysis/sync'] = array(
-    'title' => 'Sync',
-    'description' => 'Sync Chado analyses with Drupal.',
+    'title' => ' Sync',
+    'description' => 'Create pages on this site for analyses stored in Chado',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('tripal_analysis_sync_form'),
-    'access arguments' => array('administer tripal analyses'),
+    'page arguments' => array('tripal_core_chado_node_sync_form', 'tripal_analysis', 'chado_analysis'),
+    'access arguments' => array('administer tripal analysis'),
     'type' => MENU_LOCAL_TASK,
-    'weight' => 0
+    'weight' => 2
   );
 
   return $items;
@@ -233,49 +215,8 @@ function tripal_analysis_block_view($delta = '') {
   }
 }
 
-/**
- *
- * @ingroup tripal_analysis
- */
-function tripal_analysis_node_view($node, $view_mode, $langcode) {
-  switch ($node->type) {
-    case 'chado_analysis':
-      // Show feature browser and counts
-      if ($view_mode == 'full') {
-        $node->content['tripal_analysis_base'] = array(
-          '#value' => theme('tripal_analysis_base', array('node' => $node)),
-        );
-        $node->content['tripal_analysis_properties'] = array(
-          '#value' => theme('tripal_analysis_properties', array('node' => $node)),
-        );
-      }
-      if ($view_mode == 'teaser') {
-        $node->content['tripal_analysis_teaser'] = array(
-          '#value' => theme('tripal_analysis_teaser', array('node' => $node)),
-        );
-      }
-      break;
-  }
-}
-/**
- * 
- * @param $node
- */
-function tripal_analysis_node_presave($node) {
-  // If this is an analysis of some type it will should have thre three required
-  // fields for the Chado analysis table: program, programversion and sourcename.
-  // So we will set the title for any node that has these three fields
-  if (property_exists($node, 'program') and 
-      property_exists($node, 'programversion') and
-      property_exists($node, 'sourcename')) {
-    if ($node->analysisname) {
-      $node->title = $node->analysisname;
-    }
-    else {
-      $node->title = "$node->program ($node->programversion) $node->sourcename";
-    }
-  }
-}
+
+
 /**
  * Implements hook_views_api()
  * Purpose: Essentially this hook tells drupal that there is views support for

+ 0 - 131
tripal_contact/includes/contact_sync.inc

@@ -1,131 +0,0 @@
-<?php
-/*
- * 
- */
-function tripal_contact_sync_form() {
-
-  $form['sync'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Sync Contacts')
-  );
-  $form['sync']['sync_all'] = array(
-    '#markup' => t('<p>Syncing a contact will create a Drupal page for every contact 
-      record in the Chado database. Click the button below to sync all contacts in 
-      Chado that currently are not already synced with Drupal.</p>'),
-  );
-
-  $form['sync']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Sync contacts')
-  );
-  
-  $form['cleanup'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Clean Up')
-  );
-  $form['cleanup']['description'] = array(
-    '#markup' => t("<p>With Drupal and chado residing in different databases ".
-      "it is possible that nodes in Drupal and contacts in Chado become ".
-      "\"orphaned\".  This can occur if an contact node in Drupal is ".
-      "deleted but the corresponding chado contact is not and/or vice ".
-      "versa. Click the button below to resolve these discrepancies.</p>"),
-  );
-  $form['cleanup']['button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Clean up orphaned contacts'),
-  );
-
-  return $form;
-}
-
-
-/*
- * 
- */
-function tripal_contact_sync_form_submit($form, $form_state) {
-  global $user;    //needed to make the current users details available so access of user id is available
-  
-  if ($form_state['values']['op'] == t('Sync contacts')) {
-    $job_args = array();
-    $job_id = tripal_add_job('Sync contacts', 'tripal_contact', 'tripal_contact_sync_contacts', 
-      $job_args, $user->uid);
-  }
-
-  // Submit the Cleanup Job if selected
-  if ($form_state['values']['op'] == t('Clean up orphaned contacts')) {
-    $job_args = array();
-    tripal_add_job('Cleanup orphaned contacts', 'tripal_contact',
-     'tripal_contact_cleanup', $job_args, $user->uid);
-  }
-}
-/**
- *
- *
- * @ingroup tripal_contact
- */
-function tripal_contact_sync_contacts($job_id = NULL) {
-  global $user;
-  
-  // get the list of contacts that have not yet been synced
-  // and ignore the default 'NULL' contact. we don't want
-  // to sync that one.
-  $sql = "
-    SELECT C.*
-    FROM chado.contact C
-      LEFT JOIN {chado_contact} CP ON CP.contact_id = C.contact_id
-    WHERE CP.contact_id IS NULL and NOT C.name = 'null'
-  ";
-  $results = db_query($sql);
-  
-  // We'll use the following SQL statement for checking if the contact
-  // already exists as a drupal node.
-  $sql = "SELECT * FROM {chado_contact} WHERE contact_id = :contact_id";
-
-  while ($contact = $results->fetchObject()) {
-    
-    // check if this contact already exists in the drupal database. if it
-    // does then skip this contact and go to the next one.
-    if (!db_query($sql, array(':contact_id' => $contact->contact_id))->fetchObject()) {
-    
-      $new_node = new stdClass();
-      $new_node->uid = $user->uid;
-      $new_node->contact_id = $contact->contact_id;
-      $new_node->type = 'chado_contact';
-      $new_node->title = $contact->name;
-      $new_node->description = $contact->description;
-      $new_node->type_id = $contact->type_id;
-    
-      $form = array(); // dummy variable
-      $form_state = array(); // dummy variable
-      node_validate($new_node, $form, $form_state);
-      if (!form_get_errors()) {
-        $node = node_submit($new_node);
-        node_save($node);
-        if ($node->nid) {
-          print "Added contact: $new_node->title\n";
-        }
-      }
-      else {
-        watchdog('tcontact_sync', "Unable to create contact node. ID: %contact_id, Name: %name.",
-          array('%contact_id' => $contact->contact_id, '%name' => $contact->name), WATCHDOG_WARNING);      
-        
-      }
-    } 
-  }
-}
-
-/**
- * Remove orphaned drupal nodes
- *
- * @param $dummy
- *   Not Used -kept for backwards compatibility
- * @param $job_id
- *   The id of the tripal job executing this function
- *
- * @ingroup tripal_contact
- */
-function tripal_contact_cleanup($dummy = NULL, $job_id = NULL) {
-
-  return tripal_core_chado_node_cleanup_orphaned('contact', $job_id);
-
-}

+ 64 - 0
tripal_contact/includes/tripal_contact.chado_node.inc

@@ -1,4 +1,36 @@
 <?php
+/**
+ * Implementation of hook_tripal_contact_node_info().
+ *
+ * This node_info, is a simple node that describes the functionallity of the module.
+ *
+ */
+function tripal_contact_node_info() {
+
+  return array(
+    'chado_contact' => array(
+      'name' => t('Contact'),
+      'base' => 'chado_contact',
+      'description' => t('A contact from the Chado database'),
+      'title_label' => t('Article Title'),
+      'body_label' => t('Abstract'),
+      'has_title' => TRUE,
+      'has_body' => FALSE,
+      'chado_node_api' => array(
+        'base_table' => 'contact',
+        'hook_prefix' => 'chado_contact',
+        'record_type_title' => array(
+          'singular' => t('Contact'),
+          'plural' => t('Contacts')
+        ),
+        'sync_filters' => array(
+          'type_id' => FALSE,
+          'organism_id' => FALSE
+        ),
+      )
+    ),
+  );
+}
 /**
  * Implementation of tripal_contact_form().
  *
@@ -464,4 +496,36 @@ function chado_contact_delete(&$node) {
   // Remove data from contact and contactprop tables of chado database as well
   chado_query("DELETE FROM {contactprop} WHERE contact_id = :contact_id", array(':contact_id' => $contact_id));
   chado_query("DELETE FROM {contact} WHERE contact_id = :contact_id", array(':contact_id' => $contact_id));
+}
+
+
+/**
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_contact_node_view($node, $view_mode, $langcode) {
+  switch ($node->type) {
+  	case 'chado_contact':
+  	  // Show feature browser and counts
+  	  if ($view_mode == 'full') {
+  	    $node->content['tripal_contact_base'] = array(
+  	      '#value' => theme('tripal_contact_base', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_contact_properties'] = array(
+  	      '#value' => theme('tripal_contact_properties', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_contact_publications'] = array(
+  	      '#value' => theme('tripal_contact_publications', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_contact_relationships'] = array(
+  	      '#value' => theme('tripal_contact_relationships', array('node' => $node)),
+  	    );
+  	  }
+  	  if ($view_mode == 'teaser') {
+  	    $node->content['tripal_contact_teaser'] = array(
+  	      '#value' => theme('tripal_contact_teaser', array('node' => $node)),
+  	    );
+  	  }
+  	  break;
+  }
 }

+ 72 - 0
tripal_contact/theme/tripal_contact.theme.inc

@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ *
+ * @ingroup tripal_contact
+ */
+function tripal_contact_preprocess_tripal_contact_relationships(&$variables) {
+  // we want to provide a new variable that contains the matched contacts.
+  $contact = $variables['node']->contact;
+
+  // normally we would use tripal_core_expand_chado_vars to expand our
+  // organism object and add in the relationships, however whan a large
+  // number of relationships are present this significantly slows the
+  // query, therefore we will manually perform the query
+  $sql = "
+    SELECT C.name, C.contact_id, CP.nid, CVT.name as rel_type
+    FROM {contact_relationship} PR
+      INNER JOIN {contact} C              ON PR.object_id  = C.contact_id
+      INNER JOIN {cvterm} CVT             ON PR.type_id    = CVT.cvterm_id
+      LEFT  JOIN public.chado_contact CP  ON C.contact_id  = CP.contact_id
+    WHERE PR.subject_id = :contact_id
+  ";
+  $as_subject = chado_query($sql, array(':contact_id' => $contact->contact_id));
+  $sql = "
+    SELECT C.name, C.contact_id, CP.nid, CVT.name as rel_type
+    FROM {contact_relationship} PR
+      INNER JOIN {contact} C              ON PR.subject_id = C.contact_id
+      INNER JOIN {cvterm} CVT             ON PR.type_id    = CVT.cvterm_id
+      LEFT  JOIN public.chado_contact CP  ON C.contact_id  = CP.contact_id
+    WHERE PR.object_id = :contact_id
+  ";
+  $as_object = chado_query($sql, array(':contact_id' => $contact->contact_id));
+
+  // combine both object and subject relationshisp into a single array
+  $relationships = array();
+  $relationships['object'] = array();
+  $relationships['subject'] = array();
+
+  // iterate through the object relationships
+  while ($relationship = $as_object->fetchObject()) {
+
+    // get the relationship and child types
+    $rel_type = t(preg_replace('/_/', " ", $relationship->rel_type));
+    $sub_type = t(preg_replace('/_/', " ", $relationship->sub_type));
+
+    if (!array_key_exists($rel_type, $relationships['object'])) {
+      $relationships['object'][$rel_type] = array();
+    }
+    if (!array_key_exists($sub_type, $relationships['object'][$rel_type])) {
+      $relationships['object'][$rel_type][$sub_type] = array();
+    }
+    $relationships['object'][$rel_type][$sub_type][] = $relationship;
+  }
+
+  // now add in the subject relationships
+  while ($relationship = $as_subject->fetchObject()) {
+
+    // get the relationship and child types
+    $rel_type = t(preg_replace('/_/', " ", $relationship->rel_type));
+    $obj_type = t(preg_replace('/_/', " ", $relationship->obj_type));
+
+    if (!array_key_exists($rel_type, $relationships['subject'])) {
+      $relationships['subject'][$rel_type] = array();
+    }
+    if (!array_key_exists($obj_type, $relationships['subject'][$rel_type])) {
+      $relationships['subject'][$rel_type][$obj_type] = array();
+    }
+    $relationships['subject'][$rel_type][$obj_type][] = $relationship;
+  }
+
+  $contact->all_relationships = $relationships;
+}

+ 11 - 121
tripal_contact/tripal_contact.module

@@ -10,7 +10,7 @@
  */
 
 require('api/tripal_contact.api.inc');
-require('includes/contact_sync.inc');
+require('theme/tripal_contact.theme.inc');
 require('includes/tripal_contact.admin.inc');
 require('includes/tripal_contact.chado_node.inc');
 
@@ -52,26 +52,7 @@ function tripal_contact_init() {
 
 }
 
-/**
- * Implementation of hook_tripal_contact_node_info().
- *
- * This node_info, is a simple node that describes the functionallity of the module.
- *
- */
-function tripal_contact_node_info() {
 
-  return array(
-    'chado_contact' => array(
-      'name' => t('Contact'),
-      'base' => 'chado_contact',
-      'description' => t('A contact from the Chado database'),
-      'title_label' => t('Article Title'),
-      'body_label' => t('Abstract'),
-      'has_title' => TRUE,
-      'has_body' => FALSE,
-    ),
-  );
-}
 
 /**
  * Tripal-contact-Menu
@@ -124,6 +105,16 @@ function tripal_contact_menu() {
     'type' => MENU_LOCAL_TASK,
     'weight' => 0
   );
+  
+  $items['admin/tripal/chado/tripal_contact/sync'] = array(
+    'title' => ' Sync',
+    'description' => 'Create pages on this site for libraries stored in Chado',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_chado_node_sync_form', 'tripal_contact', 'chado_contact'),
+    'access arguments' => array('administer tripal contact'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 2
+  );
 
   // AJAX calls for adding/removing properties to a contact
   $items['tripal_contact/properties/add'] = array(
@@ -294,77 +285,7 @@ function tripal_contact_permissions() {
 }
 
 
-/**
- *
- *
- * @ingroup tripal_contact
- */
-function tripal_contact_preprocess_tripal_contact_relationships(&$variables) {
-  // we want to provide a new variable that contains the matched contacts.
-  $contact = $variables['node']->contact;
-
-  // normally we would use tripal_core_expand_chado_vars to expand our
-  // organism object and add in the relationships, however whan a large
-  // number of relationships are present this significantly slows the
-  // query, therefore we will manually perform the query
-  $sql = "
-    SELECT C.name, C.contact_id, CP.nid, CVT.name as rel_type
-    FROM {contact_relationship} PR
-      INNER JOIN {contact} C              ON PR.object_id  = C.contact_id
-      INNER JOIN {cvterm} CVT             ON PR.type_id    = CVT.cvterm_id
-      LEFT  JOIN public.chado_contact CP  ON C.contact_id  = CP.contact_id
-    WHERE PR.subject_id = :contact_id
-  ";
-  $as_subject = chado_query($sql, array(':contact_id' => $contact->contact_id));
-  $sql = "
-    SELECT C.name, C.contact_id, CP.nid, CVT.name as rel_type
-    FROM {contact_relationship} PR
-      INNER JOIN {contact} C              ON PR.subject_id = C.contact_id
-      INNER JOIN {cvterm} CVT             ON PR.type_id    = CVT.cvterm_id
-      LEFT  JOIN public.chado_contact CP  ON C.contact_id  = CP.contact_id
-    WHERE PR.object_id = :contact_id
-  ";
-  $as_object = chado_query($sql, array(':contact_id' => $contact->contact_id));
 
-  // combine both object and subject relationshisp into a single array
-  $relationships = array();
-  $relationships['object'] = array();
-  $relationships['subject'] = array();
-
-  // iterate through the object relationships
-  while ($relationship = $as_object->fetchObject()) {
-
-     // get the relationship and child types
-     $rel_type = t(preg_replace('/_/', " ", $relationship->rel_type));
-     $sub_type = t(preg_replace('/_/', " ", $relationship->sub_type));
-
-     if (!array_key_exists($rel_type, $relationships['object'])) {
-       $relationships['object'][$rel_type] = array();
-     }
-     if (!array_key_exists($sub_type, $relationships['object'][$rel_type])) {
-       $relationships['object'][$rel_type][$sub_type] = array();
-     }
-     $relationships['object'][$rel_type][$sub_type][] = $relationship;
-  }
-
-  // now add in the subject relationships
-  while ($relationship = $as_subject->fetchObject()) {
-
-     // get the relationship and child types
-     $rel_type = t(preg_replace('/_/', " ", $relationship->rel_type));
-     $obj_type = t(preg_replace('/_/', " ", $relationship->obj_type));
-
-     if (!array_key_exists($rel_type, $relationships['subject'])) {
-       $relationships['subject'][$rel_type] = array();
-     }
-     if (!array_key_exists($obj_type, $relationships['subject'][$rel_type])) {
-       $relationships['subject'][$rel_type][$obj_type] = array();
-     }
-     $relationships['subject'][$rel_type][$obj_type][] = $relationship;
-  }
-
-  $contact->all_relationships = $relationships;
-}
 
 /**
  * Implementation of hook_form_alter()
@@ -379,34 +300,3 @@ function tripal_contact_form_alter(&$form, &$form_state, $form_id) {
     $form['actions']['preview']['#access'] = FALSE;
   }
 }
-
-/**
- *
- * @ingroup tripal_feature
- */
-function tripal_contact_node_view($node, $view_mode, $langcode) {
-  switch ($node->type) {
-    case 'chado_contact':
-      // Show feature browser and counts
-      if ($view_mode == 'full') {
-        $node->content['tripal_contact_base'] = array(
-          '#value' => theme('tripal_contact_base', array('node' => $node)),
-        );
-        $node->content['tripal_contact_properties'] = array(
-          '#value' => theme('tripal_contact_properties', array('node' => $node)),
-        );
-        $node->content['tripal_contact_publications'] = array(
-          '#value' => theme('tripal_contact_publications', array('node' => $node)),
-        );
-        $node->content['tripal_contact_relationships'] = array(
-          '#value' => theme('tripal_contact_relationships', array('node' => $node)),
-        );
-      }
-      if ($view_mode == 'teaser') {
-        $node->content['tripal_contact_teaser'] = array(
-          '#value' => theme('tripal_contact_teaser', array('node' => $node)),
-        );
-      }
-      break;
-  }
-}

+ 106 - 42
tripal_core/api/tripal_core_chado_nodes.api.inc

@@ -47,9 +47,15 @@
             'singular' => t('Example'),         // Singular human-readable title
             'plural' => t('Examples')           // Plural human-readable title
           ),
-          'sync_filters' => array(                 // foreign keys present in your table
-            'type_id' => TRUE,                  // TRUE if there is an example.type_id field
-            'organism_id' => TRUE               // TRUE if there is an example.organism_id field
+          'sync_filters' => array( // filters for syncing
+            'type_id'     => TRUE,     // TRUE if there is an example.type_id field
+            'organism_id' => TRUE,     // TRUE if there is an example.organism_id field
+            'checkboxes'  => array('name')  // If the 'checkboxes' key is present then the
+                                            // value must be an array of column names in
+                                            // base table. The values from these columns will
+                                            // be retreived, contentated with a space delimeter
+                                            // and provided in a list of checkboxes
+                                            // for the user to choose which to sync.
           ),
         )
       ),
@@ -144,6 +150,7 @@ function tripal_core_chado_node_sync_form($form, &$form_state) {
   $form['sync'] = array(
     '#type' => 'fieldset',
     '#title' => 'Sync ' . $args['record_type_title']['plural'],
+    '#descrpition' => '',
   );
 
   $form['sync']['description'] = array(
@@ -168,14 +175,14 @@ function tripal_core_chado_node_sync_form($form, &$form_state) {
       )),
       '#type'        => 'textarea',
       '#description' => t("Enter the names of the %title_singular types to sync. " .
-         "Leave blank to sync all %title_plural. Pages for these %title_singular ".
+         "Leave blank to sync all %title_plural. Separate each type with a comma ". 
+         "or new line. Pages for these %title_singular ".
          "types will be created automatically for %title_plural that exist in the ".
-         "chado database.  The names listed here should be separated by a comma".
-         "or entered separately on new lines. The names must match ".
+         "chado database. The names must match ".
          "exactly (spelling and case) with terms in the ontologies",
          array(
-          '%title_singular' => $args['record_type_title']['singular'],
-          '%title_plural' => $args['record_type_title']['plural']
+          '%title_singular' => strtolower($args['record_type_title']['singular']),
+          '%title_plural' => strtolower($args['record_type_title']['plural'])
         )),
       '#default_value' => (isset($form_state['values']['type_id'])) ? $form_state['values']['type_id'] : '',
     );
@@ -184,16 +191,15 @@ function tripal_core_chado_node_sync_form($form, &$form_state) {
   // get the list of organisms
   if ($args['sync_filters']['organism_id']) {
     $sql = "SELECT * FROM {organism} ORDER BY genus, species";
-    $orgs = tripal_organism_get_synced();
+    $results = chado_query($sql);
     $organisms[] = '';
-    foreach ($orgs as $organism) {
+    foreach ($results as $organism) {
       $organisms[$organism->organism_id] = "$organism->genus $organism->species ($organism->common_name)";
     }
     $form['sync']['organism_id'] = array(
       '#title'       => t('Organism'),
       '#type'        => t('select'),
-      '#description' => t("Choose the organism for which %title_plural types set above will
-        be synced. Only organisms which also have been synced will appear in this list.",
+      '#description' => t("Choose the organism for which %title_plural types set above will be synced.",
          array(
           '%title_singular' => $args['record_type_title']['singular'],
           '%title_plural' => $args['record_type_title']['plural']
@@ -202,13 +208,54 @@ function tripal_core_chado_node_sync_form($form, &$form_state) {
       '#default_value' => (isset($form_state['values']['organism_id'])) ? $form_state['values']['organism_id'] : 0,
     );
   }
-
-  $form['sync']['max_sync'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Maximum number of records to Sync'),
-    '#description' => t('Leave this field empty to sync all records, regardless of number'),
-    '#default_value' => (isset($form_state['values']['max_sync'])) ? $form_state['values']['max_sync'] : '',
-  );
+  // get the list of organisms
+  if (array_key_exists('checkboxes', $args['sync_filters'])) {
+    // get the base schema
+    $base_table = $args['base_table'];
+    $table_info = tripal_core_get_chado_table_schema($base_table);
+    
+    // if the base table does not have a primary key or has more than one then 
+    // we can't proceed, otherwise, generate the checkboxes
+    if (array_key_exists('primary key', $table_info) and count($table_info['primary key']) == 1) {
+      $pkey = $table_info['primary key'][0];
+      $columns  = $args['sync_filters']['checkboxes'];
+      $select_cols = implode("|| ' ' ||", $columns);
+      
+      // get non-synced records
+      $sql = "
+        SELECT BT.$pkey as id, $select_cols as value 
+        FROM {" . $base_table . "} BT
+          LEFT JOIN public.$linking_table LT ON LT.$pkey = BT.$pkey
+        WHERE LT.$pkey IS NULL
+        ORDER BY value ASC
+      ";
+      $results = chado_query($sql);
+      $values = array();
+      foreach ($results as $result) {
+        $values[$result->id] = $result->value;
+      }
+      $form['sync']['ids'] = array(
+        '#title'         => 'Avaliable ' . $args['record_type_title']['plural'],
+        '#type'          => 'checkboxes',
+        '#description'   => t("The above  %title_plural have not been synced. Check those to be synced or leave all unchecked to sync them all.",
+          array(
+            '%title_singular' => strtolower($args['record_type_title']['singular']),
+            '%title_plural'   => strtolower($args['record_type_title']['plural'])
+          )),
+        '#options'       => $values,
+        '#default_value' => (isset($form_state['values']['ids'])) ? $form_state['values']['ids'] : array(),
+      );
+    }
+  }
+  // if we provide a list of checkboxes we shouldn't need a max_sync
+  else {
+    $form['sync']['max_sync'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Maximum number of records to Sync'),
+      '#description' => t('Leave this field empty to sync all records, regardless of number'),
+      '#default_value' => (isset($form_state['values']['max_sync'])) ? $form_state['values']['max_sync'] : '',
+    );
+  }
 
   $form['sync']['button'] = array(
     '#type' => 'submit',
@@ -278,27 +325,34 @@ function tripal_core_chado_node_sync_form_submit($form, $form_state) {
         $types[$i] = trim($temp_types[$i]);
       }
     }
-      // Job Arguments
+    
+    // Get the ids to be synced
+    $ids = array();
+    if (array_key_exists('ids', $form_state['values'])){
+      foreach ($form_state['values']['ids'] as $id => $selected) {
+        if ($selected) {
+          $ids[] = $id;
+        }
+      }
+    }
+    
+    // get the organism to be synced
+    $organism_id = FALSE;
+    if (array_key_exists('organism_id',  $form_state['values'])) {
+      $organism_id = $form_state['values']['organism_id'];
+    }
+    
+    // Job Arguments
     $job_args = array(
       'base_table' => $base_table,
       'max_sync' => (!empty($form_state['values']['max_sync'])) ? $form_state['values']['max_sync'] : FALSE,
-      'organism_id' => FALSE,
+      'organism_id' => $organism_id,
       'types' => $types,
+      'ids' => $ids,
     );
-    // Create Job based on presence of organism
-    if (array_key_exists('organism_id', $form_state['values']) and 
-        $form_state['values']['organism_id'] != 0) {
-      $organism_id = $form_state['values']['organism_id'];
-      $organism = tripal_core_chado_select('organism', array('genus', 'species'), array('organism_id' => $organism_id));
-      $title = "Sync all " . $args['record_type_title']['plural'] . " for " . $organism[0]->genus . " " . $organism[0]->species;
-  
-      $job_args['organism_id'] = $organism_id;
-      tripal_add_job($title, $module, 'tripal_core_chado_node_sync_records', $job_args, $user->uid);
-    }
-    else {
-      $title = t('Sync all ' . $args['record_type_title']['plural']);
-      tripal_add_job($title, $module, 'tripal_core_chado_node_sync_records', $job_args, $user->uid);
-    }
+    
+    $title = "Sync " . $args['record_type_title']['plural'];
+    tripal_add_job($title, $module, 'tripal_core_chado_node_sync_records', $job_args, $user->uid);
   }
   if (preg_match('/^Clean up orphaned/', $form_state['values']['op'])) {
     $module = $form_state['chado_node_api']['hook_prefix'];
@@ -311,7 +365,9 @@ function tripal_core_chado_node_sync_form_submit($form, $form_state) {
 /**
  * Actual Sync Function. Works on a group of records
  */
-function tripal_core_chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id = FALSE, $types = array(), $job_id = NULL) {
+function tripal_core_chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id = FALSE, 
+    $types = array(), $ids = array(), $job_id = NULL) {
+  
   global $user;
   $base_table_id = $base_table . '_id';
 
@@ -330,12 +386,18 @@ function tripal_core_chado_node_sync_records($base_table, $max_sync = FALSE, $or
 
     $select[] = 'cvterm.name as cvtname';
     $joins[] = "LEFT JOIN {cvterm} cvterm ON $base_table.type_id = cvterm.cvterm_id";
-    if (sizeof($types) == 1) {
-      $where_clauses[] = 'cvterm.name = :type_name';
-      $where_args[':type_name'] = $types[0];
-    } 
-    elseif (sizeof($types) > 1) {
-      $where_clauses[] = "cvterm.name IN ('" . implode("', '", $types) . "')";
+    foreach ($types as $type) {
+      $where_clauses[] = "cvterm.name = :type_name_$type";
+      $where_args[":type_name_$type"] = $type;
+    }
+  }
+  
+  // if IDs have been supplied
+  if ($ids) {
+    $restrictions .= "  Specific Records: " . count($ids) . " recored(s) directory specified.\n";
+    foreach ($ids as $id) {
+      $where_clauses[] = "$base_table_id = :id_$id";
+      $where_args[":id_$id"] = $id;
     }
   }
 
@@ -379,6 +441,8 @@ function tripal_core_chado_node_sync_records($base_table, $max_sync = FALSE, $or
   
   //print "\nQuery: " . preg_replace(array("/FROM/","/LEFT/","/WHERE/"), array("\nFROM","\nLEFT","\nWHERE"), $query) . "\n";
 
+  print_r($query, $where_args);
+  
   //print "Executing Query...\n";
   $results = chado_query($query, $where_args);
 

+ 18 - 0
tripal_example/includes/tripal_example.chado_node.inc

@@ -24,6 +24,24 @@ function tripal_example_node_info() {
   //  'has_title'   => FALSE,
   //  'has_body'    => FALSE,
   //  'locked'      => TRUE
+  // This section of the node type array specifies how Tripal will sync the node
+  // types with data in Chado. When Drupal creates a node it has no way of
+  // coordinating which node belongs to which record in Chado. Therefore,
+  // Tripal maintains tables in the Drupal schema that maps Drupal nodes
+  // to recrords in Chado.  Syncing is the process of creating Drupal nodes
+  // and linking them to the appropriate record. 
+  //  'chado_node_api' => array(
+  //    'base_table' => 'example',       // the base table name (e.g. feature, library, contact)
+  //    'hook_prefix' => 'chado_example',// the node type hook prefix
+  //    'record_type_title' => array(
+  //      'singular' => t('Library'),    // how to refer to the record 
+  //      'plural' => t('Libraries')     // how to refer to the record in plurals
+  //    ),
+  //    'sync_filters' => array(
+  //      'type_id' => TRUE,             // if the record has a type_id set to TRUE
+  //      'organism_id' => TRUE          // if the record has an organism_id set to TRUE
+  //    ),
+  //  )
   //);
   
   return $nodes;

+ 32 - 21
tripal_feature/includes/tripal_feature.chado_node.inc

@@ -1,5 +1,37 @@
 <?php 
+/**
+ *  Provide information to drupal about the node types that we're creating
+ *  in this module
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_feature_node_info() {
+  $nodes = array();
 
+  $nodes['chado_feature'] = array(
+    'name'        => t('Feature'),
+    'base'        => 'chado_feature',
+    'description' => t('A feature from the chado database'),
+    'has_title'   => FALSE,
+    'title_label' => t('Feature'),
+    'has_body'    => FALSE,
+    'body_label'  => t('Feature Description'),
+    'locked'      => TRUE,
+    'chado_node_api' => array(
+      'base_table' => 'feature',
+      'hook_prefix' => 'chado_feature',
+      'record_type_title' => array(
+        'singular' => t('Feature'),
+        'plural' => t('Features')
+      ),
+      'sync_filters' => array(
+        'type_id' => TRUE,
+        'organism_id' => TRUE
+      ),
+    )
+  );
+  return $nodes;
+}
 /**
  * Implementation of hook_form
  * 
@@ -589,27 +621,6 @@ function chado_feature_load($nodes) {
     }
   }
 }
-/**
- *  Provide information to drupal about the node types that we're creating
- *  in this module
- *
- * @ingroup tripal_feature
- */
-function tripal_feature_node_info() {
-  $nodes = array();
-
-  $nodes['chado_feature'] = array(
-    'name'        => t('Feature'),
-    'base'        => 'chado_feature',
-    'description' => t('A feature from the chado database'),
-    'has_title'   => FALSE,
-    'title_label' => t('Feature'),
-    'has_body'    => FALSE,
-    'body_label'  => t('Feature Description'),
-    'locked'      => TRUE
-  );
-  return $nodes;
-}
 /**
  *
  * @ingroup tripal_feature

+ 0 - 449
tripal_feature/includes/tripal_feature.sync_features.inc

@@ -1,449 +0,0 @@
-<?php
-
-/**
- * @file
- * @todo Add file header description
- */
-
-/**
- *
- */
-function tripal_feature_sync_form() {
-
-  $form['description'] = array(
-  '#markup' => t("Add feature types, optionally select an organism and " .
-     "click the 'Sync all Features' button to create Drupal " .
-     "content for features in chado. Only features of the types listed " .
-     "below in the Feature Types box will be synced. You may limit the " .
-     "features to be synced by a specific organism. Depending on the " .
-     "number of features in the chado database this may take a long " .
-     "time to complete. "),
-  );
-
-  $form['feature_types'] = array(
-    '#title'       => t('Feature Types'),
-    '#type'        => 'textarea',
-    '#description' => t("Enter the names of the feature types to sync.  Pages for these feature " .
-       "types will be created automatically for features that exist in the " .
-       "chado database.  The names listed here should be spearated by " .
-       "spaces or entered separately on new lines. The names must match " .
-       "exactly (spelling and case) with terms in the sequence ontology"),
-    '#required'    => TRUE,
-    '#default_value' => variable_get('chado_sync_feature_types', 'gene mRNA'),
-  );
-
-  // get the list of organisms
-  $sql = "SELECT * FROM {organism} ORDER BY genus, species";
-  $orgs = tripal_organism_get_synced();
-  $organisms[] = '';
-  foreach ($orgs as $organism) {
-    $organisms[$organism->organism_id] = "$organism->genus $organism->species ($organism->common_name)";
-  }
-  $form['organism_id'] = array(
-    '#title'       => t('Organism'),
-    '#type'        => t('select'),
-    '#description' => t("Choose the organism for which features types set above will be synced. Only organisms which also have been synced will appear in this list."),
-    '#options'     => $organisms,
-  );
-
-
-  $form['button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Sync all Features'),
-    '#weight' => 3,
-  );
-  
-  get_tripal_feature_admin_form_cleanup_set($form);
-
-  return $form;
-}
-
-/**
- *
- *
- * @ingroup tripal_feature
- */
-function get_tripal_feature_admin_form_cleanup_set(&$form) {
-  $form['cleanup'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Clean Up'),
-    '#collapsible' => FALSE,
-    '#collapsed' => FALSE,
-  );
-  $form['cleanup']['description'] = array(
-    '#markup' => t("With Drupal and chado residing in different databases " .
-        "it is possible that nodes in Drupal and features in Chado become " .
-        "\"orphaned\".  This can occur if a feature node in Drupal is " .
-        "deleted but the corresponding chado feature is not and/or vice " .
-        "versa.  The Cleanup function will also remove nodes for features " .
-        "that are not in the list of allowed feature types as specified " .
-        "above.  This is helpful when a feature type needs to be " .
-        "removed but was previously present as Drupal nodes. " .
-        "Click the button below to resolve these discrepancies."),
-    '#weight' => 1,
-  );
-  $form['cleanup']['button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Clean up orphaned features'),
-    '#weight' => 2,
-  );
-}
-
-/**
- *
- */
-function tripal_feature_sync_form_validate($form, &$form_state) {
-  $organism_id   = $form_state['values']['organism_id'];
-  $feature_types = $form_state['values']['feature_types'];
-}
-/**
- *
- */
-function tripal_feature_sync_form_submit($form, &$form_state) {
-
-  global $user;
-
-  $organism_id   = $form_state['values']['organism_id'];
-  $feature_types = $form_state['values']['feature_types'];
-  
-  switch ($form_state['values']['op']) {
-    case  t('Sync all Features') :
-      $job_args = array(0, $organism_id, $feature_types);
-      if ($organism_id) {
-        $organism = tripal_core_chado_select('organism', array('genus', 'species'), array('organism_id' => $organism_id));
-        $title = "Sync all features for " . $organism[0]->genus . " " . $organism[0]->species;
-      }
-      else {
-        $title = t('Sync all features for all synced organisms');
-      }
-      variable_set('chado_sync_feature_types', $feature_types);    
-      tripal_add_job($title, 'tripal_feature', 'tripal_feature_sync_features', $job_args, $user->uid);
-      break;
-      
-    case t('Clean up orphaned features') :
-      $job_args = array();
-      tripal_add_job('Cleanup orphaned features', 'tripal_feature',
-      'tripal_features_cleanup', $job_args, $user->uid);
-      break;
-  }
-}
-/**
- *  
- * @param $na 
- *   Tripal expects all jobs to have at least one argument. For this function
- *   we don't need any, so we have this dummy argument as a filler
- * @param $job_id
- */
-function tripal_feature_set_urls($na = NULL, $job = NULL) {
-  
-  // begin the transaction
-  db_query("BEGIN");
-      
-  print "\nNOTE: Setting of URLs is performed using a database transaction. \n" .
-        "If the load fails or is terminated prematurely then the entire set of \n" .
-        "new URLs will be rolled back and no changes will be made\n\n";
-  
-  // get the number of records we need to set URLs for
-  $csql = "SELECT count(*) FROM {chado_feature}";
-  $num_nodes = db_query($csql)->fetchField();
-    
-  // calculate the interval at which we will print an update on the screen
-  $num_set = 0;
-  $num_per_interval = 100;
-  
-  // prepate the statements which will quickly add url alias. Because these
-  // are not Chado tables we must manually prepare them 
-  $psql = "
-    PREPARE del_url_alias_by_src (text) AS
-    DELETE FROM {url_alias} WHERE source = \$1
-  ";
-  db_query($psql);
-  $psql = "
-    PREPARE ins_url_alias_nisrds (text, text) AS
-    INSERT INTO url_alias (source, alias) VALUES (\$1, \$2)
-  ";
-  db_query($psql);
-  
-  // get the URL alias syntax string
-  $url_alias = variable_get('chado_feature_url_string', '/feature/[genus]/[species]/[type]/[uniquename]'); 
-  if (!$url_alias) {
-    $url_alias = '/feature/[genus]/[species]/[type]/[uniquename]';
-  } 
-  $url_alias = preg_replace('/^\//', '', $url_alias); // remove any preceeding forward slash
-  
-  
-  // get the list of features that have been synced
-  $sql = "SELECT * FROM {chado_feature}";
-  $nodes = db_query($sql);  
-  while ($node = $nodes->fetchObject()) {
-   
-    // get the URL alias
-    $src = "node/$node->nid";
-    $dst = tripal_feature_get_feature_url($node, $url_alias);
-    if (!$dst) {
-      db_query('DEALLOCATE "del_url_alias_by_src"');
-      db_query('DEALLOCATE "ins_url_alias_nisrds"');
-      db_query("ROLLBACK"); 
-      return; 
-    }    
-    
-    // if the src and dst is the same (the URL alias couldn't be set)
-    // then skip to the next one. There's nothing we can do about this one.
-    if ($src == $dst) {
-      continue;
-    }
-    
-    // remove any previous alias and then add the new one
-    $success = db_query("EXECUTE del_url_alias_by_src(:source)", array(':source' => $src));    
-    if (!$success) {
-      db_query('DEALLOCATE "del_url_alias_by_src"');
-      db_query('DEALLOCATE "ins_url_alias_nisrds"');
-      db_query("ROLLBACK");
-      watchdog('trp-seturl', "Failed Removing URL Alias: %source", array('%source' => $src), WATCHDOG_ERROR);
-      return;
-    }
-    $success = db_query("EXECUTE ins_url_alias_nisrds(:source, :alias)", array(':source' => $src, ':alias' => $dst));
-    if (!$success) {
-      db_query('DEALLOCATE "del_url_alias_by_src"');
-      db_query('DEALLOCATE "ins_url_alias_nisrds"');
-      db_query("ROLLBACK");
-      watchdog('trp-seturl', "Failed Adding URL Alias: %alias", array('%alias' => $dst), WATCHDOG_ERROR);
-      return;
-    }
-
-    // update the job status every 1% features
-    if ($job and $num_set % $num_per_interval == 0) {
-      $percent = ($num_set / $num_nodes) * 100;
-      tripal_job_set_progress($job, intval($percent));
-      $percent = sprintf("%.2f", $percent);
-      print "Setting URLs (" . $percent . "%). Memory: " . number_format(memory_get_usage()) . " bytes.\r";
-      
-    }
-    $num_set++;
-  }
-  $percent = ($num_set / $num_nodes) * 100;
-  tripal_job_set_progress($job, intval($percent));
-  $percent = sprintf("%.2f", $percent);
-  print "Setting URLs (" . $percent . "%). Memory: " . number_format(memory_get_usage()) . " bytes.\r";
-  print "\nDone. Set " . number_format($num_set) . " URLs\n";
-  
-  // unprepare the statements
-  db_query('DEALLOCATE "del_url_alias_by_src"');
-  db_query('DEALLOCATE "ins_url_alias_nisrds"');
-  
-  db_query("COMMIT");
-}
-/**
- * 
- * @param $node
- *   A node object containing at least the feature_id and nid
- * @param $url_alias
- *   Optional.  This should be the URL alias syntax string that contains
- *   placeholders such as [id], [genus], [species], [name], [uniquename],
- *   and [type].  These placeholders will be substituted for actual values.
- *   If this parameter is not provided then the value of the 
- *   chado_feature_url_string Drupal variable will be used.
- */
-function tripal_feature_get_feature_url($node, $url_alias = NULL) {
-
-  // get the starting URL alias
-  if (!$url_alias) {
-    $url_alias = variable_get('chado_feature_url_string', '/feature/[genus]/[species]/[type]/[uniquename]'); 
-    if (!$url_alias) {
-      $url_alias = '/feature/[genus]/[species]/[type]/[uniquename]';
-    } 
-    $url_alias = preg_replace('/^\//', '', $url_alias); // remove any preceeding forward slash
-  }
-
-  // get the feature 
-  $values = array('feature_id' => $node->feature_id); 
-  $options = array('statement_name' => 'sel_feature_id');       
-  $feature = tripal_core_chado_select('feature', array('*'), $values, $options);
-  if (!$feature) {
-    watchdog('trp-seturl', "Cannot find feature when setting URL alias for feature: %id", array('%id' => $node->feature_id), WATCHDOG_ERROR);
-    return FALSE;  
-  }
-  $feature = (object) $feature[0];
-  
-  // get the organism
-  $values = array('organism_id' => $feature->organism_id);
-  $options = array('statement_name' => 'sel_organism_id');
-  $organism  = tripal_core_chado_select('organism', array('*'), $values, $options);  
-  if (!$organism) {
-    watchdog('trp-seturl', "Cannot find organism when setting URL alias for feature: %id", array('%id' => $node->feature_id), WATCHDOG_ERROR);
-    return FALSE;  
-  }
-  $genus = preg_replace('/\s/', '_', strtolower($organism[0]->genus));
-  $species = preg_replace('/\s/', '_', strtolower($organism[0]->species)); 
-
-  // get the type
-  $values = array('cvterm_id' => $feature->type_id);
-  $options = array('statement_name' => 'sel_cvterm_id');
-  $cvterm = tripal_core_chado_select('cvterm', array('name'), $values, $options);
-  if (!$cvterm) {
-    watchdog('trp-seturl', "Cannot find type when setting URL alias for feature: %id", array('%id' => $node->feature_id), WATCHDOG_ERROR);
-    return FALSE;  
-  }
-  $type = preg_replace('/\s/', '_', $cvterm[0]->name);
-  
-  // now substitute in the values
-  $url_alias = preg_replace('/\[id\]/', $feature->feature_id, $url_alias);
-  $url_alias = preg_replace('/\[genus\]/', $genus, $url_alias);
-  $url_alias = preg_replace('/\[species\]/', $species, $url_alias);
-  $url_alias = preg_replace('/\[type\]/', $type, $url_alias);
-  $url_alias = preg_replace('/\[name\]/', $feature->name, $url_alias);
-  $url_alias = preg_replace('/\[uniquename\]/', $feature->uniquename, $url_alias);
- 
-  // the dst field of the url_alias table is only 128 characters long. 
-  // if this is the case then simply return the node URL, we can't set this one
-  if (strlen($url_alias) > 128) {
-    watchdog('trp-seturl', "Cannot set alias longer than 128 characters: %alias.", array('%alias' => $url_alias), WATCHDOG_ERROR);
-    return "node/" . $node->nid;
-  }
-  
-  return $url_alias;
-}
-/**
- *
- *
- * @ingroup tripal_feature
- */
-function tripal_feature_sync_features($max_sync = 0, $organism_id = NULL,
-  $feature_types = NULL, $job_id = NULL) {
-  
-  global $user;
-    
-  // get the list of available sequence ontology terms for which
-  // we will build drupal pages from features in chado.  If a feature
-  // is not one of the specified typse we won't build a node for it.
-  if (!$feature_types) {
-    $allowed_types = variable_get('chado_sync_feature_types', 'gene mRNA');
-  }
-  else {
-    $allowed_types = $feature_types;
-  }
-  $allowed_types = preg_replace("/[\s\n\r]+/", " ", $allowed_types);
-
-  print "Looking for features of type: $allowed_types\n";
-
-  $so_terms = split(' ', $allowed_types);
-  $where_cvt = "";
-  $args = array();
-  $i = 0;
-  foreach ($so_terms as $term) {
-    $where_cvt .= "CVT.name = :term$i OR ";
-    $args[":term$i"] = $term;
-    $i++;
-  }
-  $where_cvt = drupal_substr($where_cvt, 0, drupal_strlen($where_cvt)-3);  # strip trailing 'OR'
-
-  // get the list of organisms that are synced and only include features from
-  // those organisms
-  $orgs = tripal_organism_get_synced();
-  $where_org = "";
-  $i = 0;
-  foreach ($orgs as $org) {
-    if ($organism_id) {
-      if ($org->organism_id and $org->organism_id == $organism_id) {
-        $where_org .= "F.organism_id = :org_id$i OR ";
-        $args[":org_id$i"] = $org->organism_id;
-      }
-    }
-    else {
-      if ($org->organism_id) {
-        $where_org .= "F.organism_id = :org_id$i OR ";
-        $args[":org_id$i"] = $org->organism_id;
-      }
-    }
-    $i++;
-  }
-  $where_org = drupal_substr($where_org, 0, drupal_strlen($where_org)-3);  # strip trailing 'OR'
-
-  // get the list of features that we will sync
-  $sql = "
-    SELECT F.*, CVT.name as cvtname, O.genus, O.species 
-    FROM {feature} F 
-      INNER JOIN {cvterm} CVT ON F.type_id     = CVT.cvterm_id 
-      INNER JOIN {cv} CV      ON CV.cv_id      = CVT.cv_id
-      INNER JOIN {organism} O ON O.organism_id = F.organism_id 
-      LEFT JOIN public.chado_feature CF ON CF.feature_id = F.feature_ID
-    WHERE 
-     ($where_cvt) AND ($where_org) AND CV.name = 'sequence' AND
-     CF.feature_id IS NULL
-    ORDER BY feature_id";
-  
-  print_r($sql);
-  print_r($args);
-  $results = chado_query($sql, $args);
-  
-
-  // Iterate through features that need to be synced
-  $count = $results->rowCount();
-  $interval = intval($count * 0.01);
-  if ($interval < 1) {
-    $interval = 1;
-  }
-  $i = 0;  
-  $transaction = db_transaction();
-  try {
-    //  tripal_feature_set_vocabulary();
-    print "Loading feature $i of $count (0.00%). Memory: " . number_format(memory_get_usage()) . " bytes\r";
-    foreach ($results as $feature) {
-      // update the job status every 1% features
-      if ($job_id and $i % $interval == 0) {
-        $percent = sprintf("%.2f", ($i / $count) * 100);        
-        print "Parsing Line $line_num (" . $percent . "%). Memory: " . number_format(memory_get_usage()) . " bytes.\r";
-        tripal_job_set_progress($job_id, intval(($i/$count)*100));
-      }
-      $new_node = new stdClass();
-      $new_node->type = 'chado_feature';
-      $new_node->uid = $user->uid;
-      $new_node->feature_id = $feature->feature_id;
-      
-      // set these values as they are needed for constructing the title and
-      // the match the names of the fields in the feature form
-      $new_node->organism_id = $feature->organism_id;
-      $new_node->fname = $feature->name;
-      $new_node->uniquename = $feature->uniquename;
-      $new_node->feature_type = $feature->cvtname;
-      
-      $form = array(); // dummy variable
-      $form_state = array(); // dummy variable
-      node_validate($new_node, $form, $form_state);
-      if (!form_get_errors()) {
-        $node = node_submit($new_node);
-        node_save($node);
-      }
-      else {
-        watchdog('tfeature_sync', "Unable to create feature node. ID: %feature_id, Name: %name.",
-          array('%feature_id' => $feature->feature_id, '%name' => $feature->uniquename), WATCHDOG_WARNING);      
-      }
-      $i++;
-    }
-  }
-  catch (Exception $e) {
-    print "\n"; // make sure we start errors on new line
-    watchdog_exception('trp-fsync', $e);
-    $transaction->rollback();
-    print "FAILED: Rolling back database changes...\n";
-  }
-}
-
-
-
-/**
- *
- * Remove orphaned drupal nodes
- *
- * @param $dummy
- *   Not Used -kept for backwards compatibility
- * @param $job_id
- *   The id of the tripal job executing this function
- *
- * @ingroup tripal_feature
- */
-function tripal_features_cleanup($dummy = NULL, $job_id = NULL) {
-
-  return tripal_core_chado_node_cleanup_orphaned('feature', $job_id);
-
-}

+ 10 - 20
tripal_feature/tripal_feature.module

@@ -17,7 +17,6 @@ require_once "api/tripal_feature.api.inc";
 require_once "api/tripal_feature.schema.api.inc";
 require_once "theme/tripal_feature.theme.inc";
 require_once "includes/tripal_feature.admin.inc";
-require_once "includes/tripal_feature.sync_features.inc";
 require_once "includes/tripal_feature.fasta_loader.inc";
 require_once "includes/tripal_feature.gff_loader.inc";
 require_once "includes/tripal_feature.seq_extract.inc";
@@ -142,15 +141,7 @@ function tripal_feature_menu() {
     'access arguments' => array('administer tripal features'),
     'type' => MENU_NORMAL_ITEM,
   );
-  $items['admin/tripal/chado/tripal_feature/sync'] = array(
-    'title' => 'Sync',
-    'description' => 'Sync features from Chado with Drupal',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('tripal_feature_sync_form'),
-    'access arguments' => array('administer tripal features'),
-    'type' => MENU_LOCAL_TASK,
-    'weight' => 0
-  );
+
   $items['admin/tripal/chado/tripal_feature/delete'] = array(
     'title' => ' Delete',
     'description' => 'Delete multiple features from Chado',
@@ -160,6 +151,15 @@ function tripal_feature_menu() {
     'type' => MENU_LOCAL_TASK,
     'weight' => 2
   );
+  $items['admin/tripal/chado/tripal_feature/sync'] = array(
+    'title' => ' Sync',
+    'description' => 'Create pages on this site for features stored in Chado',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_core_chado_node_sync_form', 'tripal_feature', 'chado_feature'),
+    'access arguments' => array('administer tripal feature'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 1
+  );
   $items['admin/tripal/chado/tripal_feature/configuration'] = array(
     'title' => 'Settings',
     'description' => 'Configure the Tripal Feature module.',
@@ -1058,16 +1058,6 @@ function tripal_feature_job_describe_args($callback, $args) {
     $new_args['Alternate ID attribute'] = $args[13];
     $new_args['Create Organism'] = ($args[14] == 1) ? "Yes" : "No";
   }
-  if ($callback == 'tripal_feature_sync_features') {
-    if ($args[0]) {
-      $organism = tripal_core_chado_select('organism', array('genus', 'species'), array('organism_id' => $args[0]));
-      $new_args['Organism'] = $organism[0]->genus . " " . $organism[0]->species;
-    }
-    else {
-      $new_args['Organism'] = '';
-    }
-    $new_args['Feature Types'] = $args[1];
-  }
   return $new_args;
 }
 

+ 76 - 0
tripal_featuremap/includes/tripal_featuremap.chado_node.inc

@@ -1,4 +1,36 @@
 <?php
+/**
+ * Provide information to drupal about the node types that we're creating
+ * in this module
+ *
+ * @ingroup tripal_featuremap
+ */
+function tripal_featuremap_node_info() {
+  $nodes = array();
+  $nodes['chado_featuremap'] = array(
+    'name' => t('Feature Map'),
+    'base' => 'chado_featuremap',
+    'description' => t('A map of features from the chado database (e.g. genetic map)'),
+    'has_title' => FALSE,
+    'title_label' => t('Feature Map'),
+    'has_body' => FALSE,
+    'body_label' => t('Feature Map Description'),
+    'locked' => TRUE,
+    'chado_node_api' => array(
+      'base_table' => 'featuremap',
+      'hook_prefix' => 'chado_featuremap',
+      'record_type_title' => array(
+        'singular' => t('Feature Map'),
+        'plural' => t('Feature Maps')
+      ),
+      'sync_filters' => array(
+        'type_id' => FALSE,
+        'organism_id' => FALSE
+      ),
+    )
+  );
+  return $nodes;
+}
 /**
  *  When editing or creating a new node of type 'chado_featuremap' we need
  *  a form.  This function creates the form that will be used for this.
@@ -394,4 +426,48 @@ function chado_featuremap_delete(&$node) {
   chado_query("DELETE FROM {featuremap_dbxref} WHERE featuremap_id = :featuremap_id", array(':featuremap_id' => $featuremap_id));
   chado_query("DELETE FROM {featuremap}        WHERE featuremap_id = :featuremap_id", array(':featuremap_id' => $featuremap_id));
   
+}
+/**
+ *
+ * @param $node
+ */
+function tripal_featuremap_node_presave($node) {
+  // if this is a chado_featuremap and the $node->featuremap object is set then we
+  // are syncing and we want to set the node title to be the same as the node name
+  if ($node->type == 'chado_featuremap' and property_exists($node, 'featuremap')) {
+    $node->title = $node->featuremap->name;
+  }
+}
+/**
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_featuremap_node_view($node, $view_mode, $langcode) {
+  switch ($node->type) {
+  	case 'chado_featuremap':
+  	  // Show feature browser and counts
+  	  if ($view_mode == 'full') {
+  	    $node->content['tripal_featuremap_base'] = array(
+  	      '#value' => theme('tripal_featuremap_base', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_featuremap_featurepos'] = array(
+  	      '#value' => theme('tripal_featuremap_featurepos', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_featuremap_properties'] = array(
+  	      '#value' => theme('tripal_featuremap_properties', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_featuremap_publication'] = array(
+  	      '#value' => theme('tripal_featuremap_publication', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_featuremap_references'] = array(
+  	      '#value' => theme('tripal_featuremap_references', array('node' => $node)),
+  	    );
+  	  }
+  	  if ($view_mode == 'teaser') {
+  	    $node->content['tripal_featuremap_teaser'] = array(
+  	      '#value' => theme('tripal_featuremap_teaser', array('node' => $node)),
+  	    );
+  	  }
+  	  break;
+  }
 }

+ 2 - 76
tripal_featuremap/tripal_featuremap.module

@@ -44,38 +44,7 @@ function tripal_featuremap_help($path, $arg) {
   return $output;
 }
 
-/**
- * Provide information to drupal about the node types that we're creating
- * in this module
- *
- * @ingroup tripal_featuremap
- */
-function tripal_featuremap_node_info() {
-  $nodes = array();
-  $nodes['chado_featuremap'] = array(
-    'name' => t('Feature Map'),
-    'base' => 'chado_featuremap',
-    'description' => t('A map of features from the chado database (e.g. genetic map)'),
-    'has_title' => FALSE,
-    'title_label' => t('Feature Map'),
-    'has_body' => FALSE,
-    'body_label' => t('Feature Map Description'),
-    'locked' => TRUE,
-    'chado_node_api' => array(
-      'base_table' => 'featuremap',
-      'hook_prefix' => 'chado_featuremap',
-      'record_type_title' => array(
-        'singular' => t('Feature Map'),
-        'plural' => t('Feature Maps')
-      ),
-      'sync_filters' => array(
-        'type_id' => FALSE,
-        'organism_id' => FALSE
-      ),
-    )
-  );
-  return $nodes;
-}
+
 
 /**
  * Set the permission types that the chado module uses.  Essentially we
@@ -264,39 +233,7 @@ function tripal_featuremap_theme($existing, $type, $theme, $path) {
   );
   return $items;
 }
-/**
- *
- * @ingroup tripal_feature
- */
-function tripal_featuremap_node_view($node, $view_mode, $langcode) {
-  switch ($node->type) {
-    case 'chado_featuremap':
-      // Show feature browser and counts
-      if ($view_mode == 'full') {
-        $node->content['tripal_featuremap_base'] = array(
-          '#value' => theme('tripal_featuremap_base', array('node' => $node)),
-        );
-        $node->content['tripal_featuremap_featurepos'] = array(
-          '#value' => theme('tripal_featuremap_featurepos', array('node' => $node)),
-        );
-        $node->content['tripal_featuremap_properties'] = array(
-          '#value' => theme('tripal_featuremap_properties', array('node' => $node)),
-        );
-        $node->content['tripal_featuremap_publication'] = array(
-          '#value' => theme('tripal_featuremap_publication', array('node' => $node)),
-        );
-        $node->content['tripal_featuremap_references'] = array(
-          '#value' => theme('tripal_featuremap_references', array('node' => $node)),
-        );
-      }
-      if ($view_mode == 'teaser') {
-        $node->content['tripal_featuremap_teaser'] = array(
-          '#value' => theme('tripal_featuremap_teaser', array('node' => $node)),
-        );
-      }
-      break;
-  }
-}
+
 /**
  * @ingroup tripal_library
  */
@@ -379,14 +316,3 @@ function tripal_featuremap_form_alter(&$form, &$form_state, $form_id) {
   }
 }
 
-/**
- *
- * @param $node
- */
-function tripal_featuremap_node_presave($node) {
-  // if this is a chado_featuremap and the $node->featuremap object is set then we
-  // are syncing and we want to set the node title to be the same as the node name
-  if ($node->type == 'chado_featuremap' and property_exists($node, 'featuremap')) {
-    $node->title = $node->featuremap->name;
-  }
-}

+ 94 - 0
tripal_library/includes/tripal_library.chado_node.inc

@@ -1,4 +1,37 @@
 <?php
+
+/**
+ * Provide information to drupal about the node types that we're creating
+ * in this module
+ *
+ * @ingroup tripal_library
+ */
+function tripal_library_node_info() {
+  $nodes = array();
+  $nodes['chado_library'] = array(
+    'name' => t('Library'),
+    'base' => 'chado_library',
+    'description' => t('A library from the chado database'),
+    'has_title' => FALSE,
+    'title_label' => t('Library'),
+    'has_body' => FALSE,
+    'locked' => TRUE,
+    'chado_node_api' => array(
+      'base_table' => 'library',
+      'hook_prefix' => 'chado_library',
+      'record_type_title' => array(
+        'singular' => t('Library'),
+        'plural' => t('Libraries')
+      ),
+      'sync_filters' => array(
+        'type_id' => TRUE,
+        'organism_id' => TRUE
+      ),
+    )
+  );
+  return $nodes;
+}
+
 /**
  *  When editing or creating a new node of type 'chado_library' we need
  *  a form.  This function creates the form that will be used for this.
@@ -347,4 +380,65 @@ function chado_library_node_access($node, $op, $account) {
     }
   }
   return NULL;
+}
+/**
+ * @ingroup tripal_library
+ */
+function tripal_library_node_view($node, $view_mode, $langcode) {
+
+  switch ($node->type) {
+    case 'chado_library':
+      if ($view_mode == 'full') {
+        $node->content['tripal_library_base'] = array(
+          '#value' => theme('tripal_library_base', array('node' => $node)),
+        );
+        $node->content['tripal_library_properties'] = array(
+          '#value' => theme('tripal_library_properties', array('node' => $node)),
+        );
+        $node->content['tripal_library_publications'] = array(
+          '#value' => theme('tripal_library_publications', array('node' => $node)),
+        );
+        $node->content['tripal_library_references'] = array(
+          '#value' => theme('tripal_library_references', array('node' => $node)),
+        );
+        $node->content['tripal_library_synonyms'] = array(
+          '#value' => theme('tripal_library_synonyms', array('node' => $node)),
+        );
+        $node->content['tripal_library_terms'] = array(
+          '#value' => theme('tripal_library_terms', array('node' => $node)),
+        );
+      }
+      if ($view_mode == 'teaser') {
+        $node->content['tripal_library_teaser'] = array(
+          '#value' => theme('tripal_library_teaser', array('node' => $node)),
+        );
+      }
+      break;
+    case 'chado_organism':
+      if ($view_mode == 'full') {
+        $node->content['tripal_organism.libraries'] = array(
+          '#value' => theme('tripal_organism.libraries', array('node' => $node)),
+        );
+      }
+      break;
+    case 'chado_feature':
+      if ($view_mode == 'full') {
+        $node->content['tripal_feature.libraries'] = array(
+          '#value' => theme('tripal_feature.libraries', array('node' => $node)),
+        );
+      }
+      break;
+  }
+}
+
+/**
+ *
+ * @param $node
+ */
+function tripal_library_node_presave($node) {
+  // if this is a chado_library and the $node->library object is set then we
+  // are syncing and we want to set the node title to be the same as the node name
+  if ($node->type == 'chado_library' and property_exists($node, 'library')) {
+    $node->title = $node->library->name;
+  }
 }

+ 3 - 102
tripal_library/tripal_library.module

@@ -13,37 +13,7 @@ require('theme/tripal_library.theme.inc');
 require('includes/tripal_library.admin.inc');
 require('includes/tripal_library.chado_node.inc');
 
-/**
- * Provide information to drupal about the node types that we're creating
- * in this module
- *
- * @ingroup tripal_library
- */
-function tripal_library_node_info() {
-  $nodes = array();
-  $nodes['chado_library'] = array(
-    'name' => t('Library'),
-    'base' => 'chado_library',
-    'description' => t('A library from the chado database'),
-    'has_title' => FALSE,
-    'title_label' => t('Library'),
-    'has_body' => FALSE,
-    'locked' => TRUE,
-    'chado_node_api' => array(
-      'base_table' => 'library',
-      'hook_prefix' => 'chado_library',
-      'record_type_title' => array(
-        'singular' => t('Library'),
-        'plural' => t('Libraries')
-      ),
-      'sync_filters' => array(
-        'type_id' => TRUE,
-        'organism_id' => TRUE
-      ),
-    )
-  );
-  return $nodes;
-}
+
 
 
 /**
@@ -120,18 +90,9 @@ function tripal_library_menu() {
     'description' => 'Create pages on this site for libraries stored in Chado',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('tripal_core_chado_node_sync_form', 'tripal_library', 'chado_library'),
-    'access arguments' => array('administer tripal libraries'),
+    'access arguments' => array('administer tripal library'),
     'type' => MENU_LOCAL_TASK,
-    'weight' => 0
-  );
-  return $items;
-
-  // Synchronizing libraries from Chado to Drupal
-  $items['chado_sync_libraries'] = array(
-    'title' => 'Sync Library Data',
-    'page callback' => 'tripal_library_sync_libraries',
-    'access arguments' => array('administer tripal libraries'),
-    'type' => MENU_CALLBACK
+    'weight' => 2
   );
 
   $items['admin/tripal/chado/tripal_library/views/libraries/enable'] = array(
@@ -159,55 +120,7 @@ function tripal_library_views_api() {
   );
 }
 
-/**
- * @ingroup tripal_library
- */
-function tripal_library_node_view($node, $view_mode, $langcode) {
 
-  switch ($node->type) {
-    case 'chado_library':
-      if ($view_mode == 'full') {
-        $node->content['tripal_library_base'] = array(
-          '#value' => theme('tripal_library_base', array('node' => $node)),
-        );      
-        $node->content['tripal_library_properties'] = array(
-          '#value' => theme('tripal_library_properties', array('node' => $node)),
-        );
-        $node->content['tripal_library_publications'] = array(
-          '#value' => theme('tripal_library_publications', array('node' => $node)),
-        );
-        $node->content['tripal_library_references'] = array(
-          '#value' => theme('tripal_library_references', array('node' => $node)),
-        );      
-        $node->content['tripal_library_synonyms'] = array(
-          '#value' => theme('tripal_library_synonyms', array('node' => $node)),
-        );
-        $node->content['tripal_library_terms'] = array(
-          '#value' => theme('tripal_library_terms', array('node' => $node)),
-        );
-      }
-      if ($view_mode == 'teaser') {
-        $node->content['tripal_library_teaser'] = array(
-          '#value' => theme('tripal_library_teaser', array('node' => $node)),
-        );
-      }
-      break;
-    case 'chado_organism':
-      if ($view_mode == 'full') {
-        $node->content['tripal_organism.libraries'] = array(
-          '#value' => theme('tripal_organism.libraries', array('node' => $node)),
-        );
-      }
-      break;
-    case 'chado_feature':
-      if ($view_mode == 'full') {
-        $node->content['tripal_feature.libraries'] = array(
-          '#value' => theme('tripal_feature.libraries', array('node' => $node)),
-        );
-      }
-      break;
-  }
-}
 /**
  *  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
@@ -392,15 +305,3 @@ function tripal_library_form_alter(&$form, &$form_state, $form_id) {
     $form['actions']['preview']['#access'] = FALSE;
   }
 }
-
-/**
- *
- * @param $node
- */
-function tripal_library_node_presave($node) {
-  // if this is a chado_library and the $node->library object is set then we
-  // are syncing and we want to set the node title to be the same as the node name
-  if ($node->type == 'chado_library' and property_exists($node, 'library')) {
-    $node->title = $node->library->name;
-  }
-}

+ 0 - 211
tripal_organism/includes/organism_sync.inc

@@ -1,211 +0,0 @@
-<?php 
-
-/**
- * 
- */
-function tripal_organism_sync () {
-  $form = array();
-  
-  get_tripal_organism_admin_form_sync_set($form);
-  get_tripal_organism_admin_form_cleanup_set($form);
-  
-  return $form;
-}
-
-/**
- *
- *
- * @ingroup tripal_organism
- */
-function get_tripal_organism_admin_form_cleanup_set(&$form) {
-  $form['cleanup'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Clean Up'),
-    '#description' => t("With Drupal and chado residing in different databases or database schemas " .
-        "it is possible that nodes in Drupal and organisms in Chado become " .
-        "\"orphaned\".  This can occur if an organism node in Drupal is " .
-        "deleted but the corresponding chado organism is not and/or vice " .
-        "versa. Click the button below to resolve these discrepancies."),
-  );
-  $form['cleanup']['button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Clean up orphaned organisms'),
-  );
-}
-/**
- *
- * @ingroup tripal_organism
- */
-function get_tripal_organism_admin_form_sync_set(&$form) {
-  // define the fieldsets
-  $form['sync'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Sync Organisms')
-  );
-
-  // get the list of organisms
-  $sql = "SELECT * FROM {Organism} ORDER BY genus,species";
-  $org_rset = chado_query($sql);
-
-  // if we've added any organisms to the list that can be synced
-  // then we want to build the form components to allow the user
-  // to select one or all of them.  Otherwise, just present
-  // a message stating that all organisms are currently synced.
-  $org_boxes = array();
-  $added = 0;
-  foreach ($org_rset as $organism) {
-    // check to see if the organism is already present as a node in drupal.
-    // if so, then skip it.
-    $sql = "SELECT * FROM {chado_organism} WHERE organism_id = :organism_id";
-    if (!db_query($sql, array(':organism_id' => $organism->organism_id))->fetchObject()) {
-      $org_boxes[$organism->organism_id] = "$organism->genus $organism->species ($organism->common_name)";
-      $added++;
-    }
-  }
-
-  // if we have organisms we need to add to the checkbox then
-  // build that form element
-  if ($added > 0) {
-    $org_boxes['all'] = "All Organisms";
-
-    $form['sync']['organisms'] = array(
-      '#title'       => t('Available Organisms'),
-      '#type'        => t('checkboxes'),
-      '#description' => t("Check the organisms you want to sync.  Drupal content will be created for each of the organisms listed above.  Select 'All Organisms' to sync all of them."),
-      '#required'    => FALSE,
-      '#prefix'      => '<div id="org_boxes">',
-      '#suffix'      => '</div>',
-      '#options'     => $org_boxes,
-    );
-    $form['sync']['button'] = array(
-      '#type' => 'submit',
-      '#value' => t('Submit Sync Job')
-    );
-  }
-  // we don't have any organisms to select from
-  else {
-    $form['sync']['value'] = array(
-      '#markup' => t('All organisms in Chado are currently synced with Drupal.')
-    );
-  }
-}
-
-/**
- *
- * @ingroup tripal_organism
- */
-function tripal_organism_sync_submit($form, &$form_state) {
-  global $user;  // we need access to the user info
-  $job_args = array();
-
-  if ($form_state['values']['op'] == t('Submit Sync Job')) {
-
-    // check to see if the user wants to sync chado and drupal.  If
-    // so then we need to register a job to do so with tripal
-    $organisms = $form_state['values']['organisms'];
-    $do_all = FALSE;
-    $to_sync = array();
-
-    foreach ($organisms as $organism_id) {
-      if (preg_match("/^all$/i" , $organism_id)) {
-        $do_all = TRUE;
-      }
-      if ($organism_id and preg_match("/^\d+$/i" , $organism_id)) {
-        // get the list of organisms
-        $sql = "SELECT * FROM {organism} WHERE organism_id = :organism_id";
-        $organism = chado_query($sql, array(':organism_id' => $organism_id))->fetchObject();
-        $to_sync[$organism_id] = "$organism->genus $organism->species";
-      }
-    }
-
-    // submit the job the tripal job manager
-    if ($do_all) {
-      tripal_add_job('Sync all organisms' , 'tripal_organism',
-      'tripal_organism_sync_organisms' , $job_args , $user->uid);
-    }
-    else{
-      foreach ($to_sync as $organism_id => $name) {
-        $job_args[0] = $organism_id;
-        tripal_add_job("Sync organism: $name" , 'tripal_organism',
-        'tripal_organism_sync_organisms' , $job_args , $user->uid);
-      }
-    }
-  }
-
-  // -------------------------------------
-  // Submit the Cleanup Job if selected
-  if ($form_state['values']['op'] == t('Clean up orphaned organisms')) {
-    tripal_add_job('Cleanup orphaned organisms', 'tripal_organism',
-    'tripal_organism_cleanup', $job_args, $user->uid);
-  }
-}
-/**
- * Synchronize organisms from chado to drupal
- *
- * @ingroup tripal_organism
- */
-function tripal_organism_sync_organisms($organism_id = NULL, $job_id = NULL) {
-  global $user;
-  $page_content = '';
-
-  if (!$organism_id) {
-    $sql = "SELECT * FROM {organism} O";
-    $results = chado_query($sql);
-  }
-  else {
-    $sql = "SELECT * FROM {organism} WHERE organism_id = :organism_id";
-    $results = chado_query($sql, array(':organism_id' => $organism_id));
-  }
-
-  // We'll use the following SQL statement for checking if the organism
-  // already exists as a drupal node.
-  $sql = "SELECT * FROM {chado_organism} WHERE organism_id = :organism_id";
-
-  foreach ($results as $organism) {
-
-    // check if this organism already exists in the drupal database. if it
-    // does then skip this organism and go to the next one.
-    if (!db_query($sql, array(':organism_id' => $organism->organism_id))->fetchObject()) {
-
-      $new_node = new stdClass();
-      $new_node->type = 'chado_organism';
-      $new_node->uid = $user->uid;
-      $new_node->title = "$organism->genus $organism->species";
-      $new_node->organism_id = $organism->organism_id;
-      $new_node->genus = $organism->genus;
-      $new_node->species = $organism->species;
-      $new_node->description = '';
-      
-      $form = array(); // dummy variable
-      $form_state = array(); // dummy variable
-      node_validate($new_node, $form, $form_state);
-      if (!form_get_errors()) {
-        $node = node_submit($new_node);
-        node_save($node);
-        if ($node->nid) {
-          print "Added $organism->common_name\n";
-        }
-      }
-      else {
-        watchdog('torg_sync', "Unable to create organism node. ID: %org_id, Name: %name.",
-          array('%org_id' => $organism->organism_id, '%name' => $organism->genus . ' ' . $organism->species), 
-          WATCHDOG_WARNING);
-      }
-    }
-  }
-  return $page_content;
-}
-/**
- * Remove orphaned drupal nodes
- *
- * @param $dummy
- *   Not Used -kept for backwards compatibility
- * @param $job_id
- *   The id of the tripal job executing this function
- *
- * @ingroup tripal_organism
- */
-function tripal_organism_cleanup($dummy = NULL, $job_id = NULL) {
-
-  return tripal_core_chado_node_cleanup_orphaned('organism', $job_id);
-}

+ 440 - 0
tripal_organism/includes/tripal_organism.chado_node.inc

@@ -0,0 +1,440 @@
+<?php
+/**
+ *  Provide information to drupal about the node types that we're creating
+ *  in this module
+ *
+ * @ingroup tripal_organism
+ */
+function tripal_organism_node_info() {
+  $nodes = array();
+  $nodes['chado_organism'] = array(
+    'name' => t('Organism'),
+    'base' => 'chado_organism',
+    'description' => t('An organism'),
+    'has_title' => FALSE,
+    'title_label' => t('Organism'),
+    'locked' => TRUE,
+    'chado_node_api' => array(
+      'base_table' => 'organism',
+      'hook_prefix' => 'chado_organism',
+      'record_type_title' => array(
+        'singular' => t('Organism'),
+        'plural' => t('Organisms')
+      ),
+      'sync_filters' => array(
+        'type_id' => FALSE,
+        'organism_id' => FALSE,
+        'checkboxes' => array('genus', 'species'),
+      ),
+    )
+  );
+  return $nodes;
+}
+/**
+ * Implement hook_access().
+ *
+ * This hook allows node modules to limit access to the node types they define.
+ *
+ *  @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 $op
+ *  The operation to be performed
+ *
+ *
+ *  @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
+ */
+function chado_organism_node_access($node, $op, $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)) {
+      return FALSE;
+    }
+  }
+  if ($op == 'delete') {
+    if (!user_access('delete chado_organism content', $account)) {
+      return FALSE;
+    }
+  }
+  if ($op == 'view') {
+    if (!user_access('access chado_organism content', $account)) {
+      return FALSE;
+    }
+  }
+  return NULL;
+}
+/**
+ * Implementation of hook_validate
+ *
+ * @param $node
+ * @param $form
+ * @param $form_state
+ *
+ *  @ingroup tripal_organism
+ */
+function chado_organism_validate($node, $form, &$form_state) {
+  // remove any white space around values
+  $node->genus        = trim($node->genus);
+  $node->species      = trim($node->species);
+  $node->abbreviation = trim($node->abbreviation);
+  $node->common_name  = trim($node->common_name);
+  $node->description  = trim($node->description);
+
+
+  // if this is a delete then don't validate
+  if($node->op == 'Delete') {
+    return;
+  }
+
+  // we are syncing if we do not have a node ID but we do have a organism_id. We don't
+  // need to validate during syncing so just skip it.
+  if (is_null($node->nid) and property_exists($node, 'organism_id') and $node->organism_id != 0) {
+    return;
+  }
+
+  // Validating for an update
+  if (property_exists($node, 'organism_id')) {
+    $sql = "
+      SELECT *
+      FROM {organism} O
+      WHERE
+        genus = :genus AND
+        species = :species AND NOT
+        organism_id = :organism_id
+    ";
+    $args = array(':genus' => $node->genus, ':species' => $node->species, ':organism_id' => $node->organism_id);
+    $result = chado_query($sql, $args)->fetchObject();
+    if ($result) {
+      form_set_error('genus', t("Update cannot proceed. The organism genus
+      '$node->genus' and species '$node->species' is already present in the database."));
+      watchdog('tripal_organism',
+      'Update organism: genus and species already exists: %values',
+      array('%values' => "genus = $node->genus, species = $node->species"),
+      WATCHDOG_WARNING);
+    }
+  }
+  // Validating for an insert
+  else {
+    $values = array(
+      'genus' => $node->genus,
+      'species' => $node->species,
+    );
+    $organism = tripal_core_chado_select('organism', array('organism_id'), $values);
+    if (sizeof($organism) > 0) {
+      form_set_error('genus', 'Cannot add the organism with this genus and species.
+        The organism already exists.');
+      watchdog('tripal_organism',
+      'Insert organism: genus and species already exists: %values',
+      array('%values' => "genus = $node->genus, species = $node->species"),
+      WATCHDOG_WARNING);
+    }
+  }
+}
+/**
+ *  When a new chado_organism node is created we also need to add information
+ *  to our chado_organism table.  This function is called on insert of a new node
+ *  of type 'chado_organism' and inserts the necessary information.
+ *
+ * @ingroup tripal_organism
+ */
+function chado_organism_insert($node) {
+  // remove any white space around values
+  $node->genus        = trim($node->genus);
+  $node->species      = trim($node->species);
+  $node->abbreviation = trim($node->abbreviation);
+  $node->common_name  = trim($node->common_name);
+  $node->description  = trim($node->description);
+
+  // if there is an organism_id in the $node object then this must be a sync so
+  // we can skip adding the organism as it is already there, although
+  // we do need to proceed with the rest of the insert
+  if (!property_exists($node,'organism_id')) {
+    $values = array(
+      'genus'        => $node->genus,
+      'species'      => $node->species,
+      'abbreviation' => $node->abbreviation,
+      'common_name'  => $node->common_name,
+      'comment'      => $node->description
+    );
+    $organism = tripal_core_chado_insert('organism', $values);
+    if (!$organism) {
+      drupal_set_message(t('Unable to add organism.', 'warning'));
+      watchdog('tripal_organism', 'Insert Organism: Unable to create organism where values:%values',
+      array('%values' => print_r($values, TRUE)), WATCHDOG_ERROR);
+      return;
+    }
+    $organism_id = $organism['organism_id'];
+  }
+  else {
+    $organism_id = $node->organism_id;
+  }
+
+  // Make sure the entry for this organism doesn't already exist in the
+  // chado_organism table if it doesn't exist then we want to add it.
+  $check_org_id = chado_get_id_for_node('organism', $node->nid);
+  if (!$check_org_id) {
+    $record = new stdClass();
+    $record->nid = $node->nid;
+    $record->vid = $node->vid;
+    $record->organism_id = $organism_id;
+    drupal_write_record('chado_organism', $record);
+  }
+
+  // add the image
+  chado_organism_add_image($node);
+}
+/**
+ * Update organisms
+ *
+ * @ingroup tripal_organism
+ */
+function chado_organism_update($node) {
+  // remove any white space around values
+  $node->genus        = trim($node->genus);
+  $node->species      = trim($node->species);
+  $node->abbreviation = trim($node->abbreviation);
+  $node->common_name  = trim($node->common_name);
+  $node->description  = trim($node->description);
+
+  if ($node->revision) {
+    // there is no way to handle revisions in Chado but leave
+    // this here just to make not we've addressed it.
+  }
+  $match = array(
+    'organism_id' => chado_get_id_for_node('organism', $node->nid),
+  );
+  $values = array(
+    'genus' => $node->genus,
+    'species' => $node->species,
+    'abbreviation' => $node->abbreviation,
+    'common_name' => $node->common_name,
+    'comment' => $node->description
+  );
+  $org_status = tripal_core_chado_update('organism', $match, $values);
+
+  // add the image
+  chado_organism_add_image($node);
+}
+/**
+ * Delete organism from both drupal and chado databases. Check dependency before
+ * deleting from chado.
+ *
+ * @ingroup tripal_organism
+ */
+function chado_organism_delete($node) {
+  $organism_id = chado_get_id_for_node('organism', $node->nid);
+
+  // if we don't have an organism id for this node then this isn't a node of
+  // type chado_organism or the entry in the chado_organism table was lost.
+  if (!$organism_id) {
+    return;
+  }
+
+  // Remove data from the {chado_organism}, {node}, and {node_revisions} tables
+  $sql_del = "DELETE FROM {chado_organism} WHERE nid = :nid AND vid = :vid";
+  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
+  $sql_del = "DELETE FROM {node} WHERE nid = :nid AND vid = :vid";
+  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
+  $sql_del = "DELETE FROM {node_revision} WHERE nid = ':nid' AND vid = ':vid'";
+  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
+
+  // Test dependency before deleting from chado database. If a library or
+  // feature depends on this organism, don't delete it
+
+  $sql = "SELECT feature_id FROM {feature} WHERE organism_id = :organism_id";
+  $check_feature = chado_query($sql, array(':organism_id' => $organism_id))->fetchObject();
+  $sql = "SELECT library_id FROM {library} WHERE organism_id = :organism_id";
+  $check_lib = chado_query($sql, array(':organism_id' => $organism_id))->fetchObject();
+
+  if (!$check_lib && !$check_feature) {
+    tripal_core_chado_delete('organism', array('organism_id' => $organism_id));
+  }
+  else {
+    drupal_set_message(t("Organism deleted from drupal. Warning: at least one " .
+        "library or feature depends on this organism. It was not removed from chado."));
+  }
+}
+
+/**
+ *
+ *
+ * @ingroup tripal_organism
+ */
+function chado_organism_add_image($node) {
+  // check to see if a file was uploaded. If so then copy it to the images
+  // directory for display with the organism
+  if (isset($_FILES['files']) &&
+  $_FILES['files']['name']['organism_image'] &&
+  is_uploaded_file($_FILES['files']['tmp_name']['organism_image'])) {
+
+    // make sure the destination directory exists
+    $dest = tripal_file_directory_path() . "/tripal_organism/images";
+    file_prepare_directory($dest, FILE_CREATE_DIRECTORY);
+
+    // now move the file
+    $validators = array('file_validate_is_image' => array());
+    $destination = "public://tripal/tripal_organism/images/";
+    $file = file_save_upload('organism_image', $validators, $destination);
+    if (!$file) {
+      drupal_set_message(t("Organism image was not uploaded."));
+    }
+    else {
+      file_move($file, $destination . "/" . $node->nid . ".jpg", FILE_EXISTS_REPLACE);
+    }
+  }
+}
+
+
+/**
+ *  When editing or creating a new node of type 'chado_organism' we need
+ *  a form.  This function creates the form that will be used for this.
+ *
+ * @ingroup tripal_organism
+ */
+function chado_organism_form($node, $form_state) {
+  $form = array();
+
+  // we have a file upload element on the form soe we need the multipart encoding type
+  $form['#attributes']['enctype'] = 'multipart/form-data';
+
+  // if the organism is part of the node object then we are editing. If not we are inserting
+  if (property_exists($node, 'organism')) {
+    $organism = $node->organism;
+
+    // add in the comment since it is a text field and may not be included if too big
+    $organism = tripal_core_expand_chado_vars($organism, 'field', 'organism.comment');
+
+    // get form defaults
+    $abbreviation   = property_exists($node, 'abbreviation')   ? property_exists($node, 'abbreviation')   : $organism->abbreviation;
+    $genus          = property_exists($node, 'genus')          ? property_exists($node, 'genus')          : $organism->genus;
+    $species        = property_exists($node, 'species')        ? property_exists($node, 'species')        : $organism->species;
+    $common_name    = property_exists($node, 'common_name')    ? property_exists($node, 'common_name')    : $organism->common_name;
+    $description    = property_exists($node, 'description')    ? property_exists($node, 'description')    : $organism->comment;
+    $organism_image = property_exists($node, 'organism_image') ? property_exists($node, 'organism_image') : '';
+
+    // set the organism_id in the form
+    $form['organism_id'] = array(
+      '#type' => 'value',
+      '#value' => $organism->organism_id,
+    );
+  }
+  else {
+    // get form defaults
+    $abbreviation   = property_exists($node, 'abbreviation')   ? property_exists($node, 'abbreviation')   : '';
+    $genus          = property_exists($node, 'genus')          ? property_exists($node, 'genus')          : '';
+    $species        = property_exists($node, 'species')        ? property_exists($node, 'species')        : '';
+    $common_name    = property_exists($node, 'common_name')    ? property_exists($node, 'common_name')    : '';
+    $description    = property_exists($node, 'description')    ? property_exists($node, 'description')    : '';
+    $organism_image = property_exists($node, 'organism_image') ? property_exists($node, 'organism_image') : '';
+  }
+
+  $form['genus']= array(
+    '#type' => 'textfield',
+    '#title' => t('Genus'),
+    '#required' => TRUE,
+    '#default_value' => $genus,
+  );
+  $form['species']= array(
+    '#type' => 'textfield',
+    '#title' => t('Species'),
+    '#required' => TRUE,
+    '#default_value' => $species,
+  );
+  $form['abbreviation']= array(
+    '#type' => 'textfield',
+    '#title' => t('Abbreviation'),
+    '#required' => TRUE,
+    '#default_value' => $abbreviation,
+  );
+  $form['common_name']= array(
+    '#type' => 'textfield',
+    '#title' => t('Common Name'),
+    '#required' => TRUE,
+    '#default_value' => $common_name,
+  );
+  $form['description']= array(
+    '#type' => 'textarea',
+    '#rows' => 15,
+    '#title' => t('Description'),
+    '#default_value' => $description,
+  );
+  $form['organism_image']= array(
+    '#type' => 'file',
+    '#title' => t('Organism Image'),
+    '#description' => 'Add an image for this organism',
+    '#progress_indicator' => 'bar',
+  );
+  return $form;
+}
+
+/**
+ *  When a node is requested by the user this function is called to allow us
+ *  to add auxiliary data to the node object.
+ *
+ * @ingroup tripal_organism
+ */
+function chado_organism_load($nodes) {
+
+  foreach ($nodes as $nid => $node) {
+    // find the organism and add in the details
+    $organism_id = chado_get_id_for_node('organism', $nid);
+
+    // build the organism variable
+    $values = array('organism_id' => $organism_id);
+    $organism = tripal_core_generate_chado_var('organism', $values);
+
+
+    // add in the description field
+    $organism = tripal_core_expand_chado_vars($organism, 'field', 'organism.comment');
+    $nodes[$nid]->organism = $organism;
+  }
+}
+
+/**
+ *
+ * @param $node
+ */
+function tripal_organism_node_presave($node) {
+  switch ($node->type) {
+    case 'chado_organism':
+      // set the title for the node
+      $node->title = "$node->genus $node->species";
+      break;
+  }
+}
+/**
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_organism_node_view($node, $view_mode, $langcode) {
+  switch ($node->type) {
+    case 'chado_organism':
+      // Show feature browser and counts
+      if ($view_mode == 'full') {
+        $node->content['tripal_organism_base'] = array(
+          '#value' => theme('tripal_organism_base', array('node' => $node)),
+        );
+      }
+      if ($view_mode == 'teaser') {
+        $node->content['tripal_organism_teaser'] = array(
+          '#value' => theme('tripal_organism_teaser', array('node' => $node)),
+        );
+      }
+      break;
+  }
+}

+ 9 - 431
tripal_organism/tripal_organism.module

@@ -2,7 +2,7 @@
 
 require_once "api/tripal_organism.api.inc";
 require_once "includes/tripal_organism.admin.inc";
-require_once "includes/organism_sync.inc";
+require_once "includes/tripal_organism.chado_node.inc";
 
 /**
  * @file
@@ -21,24 +21,7 @@ function tripal_organism_init() {
   drupal_add_js(drupal_get_path('module', 'tripal_organism') . '/theme/js/tripal_organism.js');
 }
 
-/**
- *  Provide information to drupal about the node types that we're creating
- *  in this module
- *
- * @ingroup tripal_organism
- */
-function tripal_organism_node_info() {
-  $nodes = array();
-  $nodes['chado_organism'] = array(
-    'name' => t('Organism'),
-    'base' => 'chado_organism',
-    'description' => t('An organism'),
-    'has_title' => FALSE,
-    'title_label' => t('Organism'),
-    'locked' => TRUE
-  );
-  return $nodes;
-}
+
 
 /**
  *
@@ -125,17 +108,17 @@ function tripal_organism_menu() {
     'type' => MENU_LOCAL_TASK,
     'weight' => 5
   );
-  
+
   $items['admin/tripal/chado/tripal_organism/sync'] = array(
-    'title' => 'Sync',
-    'description' => 'Sync Chado organisms with Drupal',
+    'title' => ' Sync',
+    'description' => 'Create pages on this site for organisms stored in Chado',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('tripal_organism_sync'),
-    'access arguments' => array('adminster tripal organism'),
+    'page arguments' => array('tripal_core_chado_node_sync_form', 'tripal_organism', 'chado_organism'),
+    'access arguments' => array('administer tripal organism'),
     'type' => MENU_LOCAL_TASK,
     'weight' => 2
   );
-
+  
   $items['admin/tripal/chado/tripal_organism/views/organisms/enable'] = array(
     'title' => 'Enable Organism Administrative View',
     'page callback' => 'tripal_views_admin_enable_view',
@@ -203,39 +186,7 @@ function tripal_organism_theme($existing, $type, $theme, $path) {
   );
   return $items;
 }
-/**
- * 
- * @param $node
- */
-function tripal_organism_node_presave($node) {
-  switch ($node->type) {
-    case 'chado_organism':
-      // set the title for the node
-      $node->title = "$node->genus $node->species";
-      break;
-  }
-}
-/**
- *
- * @ingroup tripal_feature
- */
-function tripal_organism_node_view($node, $view_mode, $langcode) {
-  switch ($node->type) {
-    case 'chado_organism':
-      // Show feature browser and counts
-      if ($view_mode == 'full') {
-        $node->content['tripal_organism_base'] = array(
-          '#value' => theme('tripal_organism_base', array('node' => $node)),
-        );
-      }
-      if ($view_mode == 'teaser') {
-        $node->content['tripal_organism_teaser'] = array(
-          '#value' => theme('tripal_organism_teaser', array('node' => $node)),
-        );
-      }
-      break;
-  }
-}
+
 /**
   *  Set the permission types that the chado module uses.  Essentially we
   *  want permissionis that protect creation, editing and deleting of chado
@@ -295,380 +246,7 @@ function tripal_organism_job_describe_args($callback, $args) {
   }
   return $new_args;
 }
-/**
- * Implement hook_access().
- *
- * This hook allows node modules to limit access to the node types they define.
- *
- *  @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 $op
- *  The operation to be performed
- *
- *
- *  @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
- */
-function chado_organism_node_access($node, $op, $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)) {
-      return FALSE;
-    }
-  }
-  if ($op == 'delete') {
-    if (!user_access('delete chado_organism content', $account)) {
-      return FALSE;
-    }
-  }
-  if ($op == 'view') {
-    if (!user_access('access chado_organism content', $account)) {
-      return FALSE;
-    }
-  }
-  return NULL;
-}
-/**
- * Implementation of hook_validate
- *
- * @param $node
- * @param $form
- * @param $form_state
- *
- *  @ingroup tripal_organism
- */
-function chado_organism_validate($node, $form, &$form_state) {
-  // remove any white space around values
-  $node->genus        = trim($node->genus);
-  $node->species      = trim($node->species);
-  $node->abbreviation = trim($node->abbreviation);
-  $node->common_name  = trim($node->common_name);
-  $node->description  = trim($node->description);
-  
-  
-  // if this is a delete then don't validate
-  if($node->op == 'Delete') {
-    return;
-  }
-  
-  // we are syncing if we do not have a node ID but we do have a organism_id. We don't
-  // need to validate during syncing so just skip it.
-  if (is_null($node->nid) and property_exists($node, 'organism_id') and $node->organism_id != 0) {
-    return;
-  }
-
-  // Validating for an update
-  if (property_exists($node, 'organism_id')) {
-    $sql = "
-      SELECT *
-      FROM {organism} O
-      WHERE
-        genus = :genus AND
-        species = :species AND NOT
-        organism_id = :organism_id
-    ";
-    $args = array(':genus' => $node->genus, ':species' => $node->species, ':organism_id' => $node->organism_id);
-    $result = chado_query($sql, $args)->fetchObject();
-    if ($result) {
-      form_set_error('genus', t("Update cannot proceed. The organism genus
-        '$node->genus' and species '$node->species' is already present in the database."));
-      watchdog('tripal_organism',
-        'Update organism: genus and species already exists: %values',
-        array('%values' => "genus = $node->genus, species = $node->species"),
-        WATCHDOG_WARNING);
-    }
-  }
-  // Validating for an insert
-  else {
-    $values = array(
-      'genus' => $node->genus,
-      'species' => $node->species,
-    );
-    $organism = tripal_core_chado_select('organism', array('organism_id'), $values);
-    if (sizeof($organism) > 0) {
-      form_set_error('genus', 'Cannot add the organism with this genus and species.
-        The organism already exists.');
-      watchdog('tripal_organism',
-        'Insert organism: genus and species already exists: %values',
-        array('%values' => "genus = $node->genus, species = $node->species"),
-        WATCHDOG_WARNING);
-    }
-  }
-}
-/**
- *  When a new chado_organism node is created we also need to add information
- *  to our chado_organism table.  This function is called on insert of a new node
- *  of type 'chado_organism' and inserts the necessary information.
- *
- * @ingroup tripal_organism
- */
-function chado_organism_insert($node) {
-  // remove any white space around values
-  $node->genus        = trim($node->genus);
-  $node->species      = trim($node->species);
-  $node->abbreviation = trim($node->abbreviation);
-  $node->common_name  = trim($node->common_name);
-  $node->description  = trim($node->description);
-
-  // if there is an organism_id in the $node object then this must be a sync so
-  // we can skip adding the organism as it is already there, although
-  // we do need to proceed with the rest of the insert
-  if (!property_exists($node,'organism_id')) {
-    $values = array(
-      'genus'        => $node->genus,
-      'species'      => $node->species,
-      'abbreviation' => $node->abbreviation,
-      'common_name'  => $node->common_name,
-      'comment'      => $node->description
-    );
-    $organism = tripal_core_chado_insert('organism', $values);
-    if (!$organism) {
-      drupal_set_message(t('Unable to add organism.', 'warning'));
-      watchdog('tripal_organism', 'Insert Organism: Unable to create organism where values:%values',
-        array('%values' => print_r($values, TRUE)), WATCHDOG_ERROR);
-      return;
-    }
-    $organism_id = $organism['organism_id'];
-  }
-  else {
-    $organism_id = $node->organism_id;
-  }
-
-  // Make sure the entry for this organism doesn't already exist in the
-  // chado_organism table if it doesn't exist then we want to add it.
-  $check_org_id = chado_get_id_for_node('organism', $node->nid);
-  if (!$check_org_id) {
-    $record = new stdClass();
-    $record->nid = $node->nid;
-    $record->vid = $node->vid;
-    $record->organism_id = $organism_id;
-    drupal_write_record('chado_organism', $record);
-  }
 
-  // add the image
-  chado_organism_add_image($node);
-}
-/**
- * Update organisms
- *
- * @ingroup tripal_organism
- */
-function chado_organism_update($node) {
-  // remove any white space around values
-  $node->genus        = trim($node->genus);
-  $node->species      = trim($node->species);
-  $node->abbreviation = trim($node->abbreviation);
-  $node->common_name  = trim($node->common_name);
-  $node->description  = trim($node->description);
-
-  if ($node->revision) {
-    // there is no way to handle revisions in Chado but leave
-    // this here just to make not we've addressed it.
-  }
-  $match = array(
-    'organism_id' => chado_get_id_for_node('organism', $node->nid),
-  );
-  $values = array(
-    'genus' => $node->genus,
-    'species' => $node->species,
-    'abbreviation' => $node->abbreviation,
-    'common_name' => $node->common_name,
-    'comment' => $node->description
-  );
-  $org_status = tripal_core_chado_update('organism', $match, $values);
-
-  // add the image
-  chado_organism_add_image($node);
-}
-/**
- * Delete organism from both drupal and chado databases. Check dependency before
- * deleting from chado.
- *
- * @ingroup tripal_organism
- */
-function chado_organism_delete($node) {
-  $organism_id = chado_get_id_for_node('organism', $node->nid);
-
-  // if we don't have an organism id for this node then this isn't a node of
-  // type chado_organism or the entry in the chado_organism table was lost.
-  if (!$organism_id) {
-    return;
-  }
-
-  // Remove data from the {chado_organism}, {node}, and {node_revisions} tables
-  $sql_del = "DELETE FROM {chado_organism} WHERE nid = :nid AND vid = :vid";
-  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
-  $sql_del = "DELETE FROM {node} WHERE nid = :nid AND vid = :vid";
-  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
-  $sql_del = "DELETE FROM {node_revision} WHERE nid = ':nid' AND vid = ':vid'";
-  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
-
-  // Test dependency before deleting from chado database. If a library or
-  // feature depends on this organism, don't delete it
-
-  $sql = "SELECT feature_id FROM {feature} WHERE organism_id = :organism_id";
-  $check_feature = chado_query($sql, array(':organism_id' => $organism_id))->fetchObject();
-  $sql = "SELECT library_id FROM {library} WHERE organism_id = :organism_id";
-  $check_lib = chado_query($sql, array(':organism_id' => $organism_id))->fetchObject();
-
-  if (!$check_lib && !$check_feature) {
-    tripal_core_chado_delete('organism', array('organism_id' => $organism_id));
-  }
-  else {
-    drupal_set_message(t("Organism deleted from drupal. Warning: at least one " .
-      "library or feature depends on this organism. It was not removed from chado."));
-  }
-}
-
-/**
- *
- *
- * @ingroup tripal_organism
- */
-function chado_organism_add_image($node) {
-  // check to see if a file was uploaded. If so then copy it to the images
-  // directory for display with the organism
-  if (isset($_FILES['files']) &&
-      $_FILES['files']['name']['organism_image'] &&
-      is_uploaded_file($_FILES['files']['tmp_name']['organism_image'])) {
-
-    // make sure the destination directory exists
-    $dest = tripal_file_directory_path() . "/tripal_organism/images";
-    file_prepare_directory($dest, FILE_CREATE_DIRECTORY);
-
-    // now move the file
-    $validators = array('file_validate_is_image' => array());
-    $destination = "public://tripal/tripal_organism/images/";
-    $file = file_save_upload('organism_image', $validators, $destination);
-    if (!$file) {
-      drupal_set_message(t("Organism image was not uploaded."));
-    }
-    else {
-      file_move($file, $destination . "/" . $node->nid . ".jpg", FILE_EXISTS_REPLACE);
-    }
-  }
-}
-
-
-/**
- *  When editing or creating a new node of type 'chado_organism' we need
- *  a form.  This function creates the form that will be used for this.
- *
- * @ingroup tripal_organism
- */
-function chado_organism_form($node, $form_state) {
-  $form = array();
-
-  // we have a file upload element on the form soe we need the multipart encoding type
-  $form['#attributes']['enctype'] = 'multipart/form-data';
-
-  // if the organism is part of the node object then we are editing. If not we are inserting
-  if (property_exists($node, 'organism')) {
-    $organism = $node->organism;
-
-    // add in the comment since it is a text field and may not be included if too big
-    $organism = tripal_core_expand_chado_vars($organism, 'field', 'organism.comment');
-
-    // get form defaults
-    $abbreviation   = property_exists($node, 'abbreviation')   ? property_exists($node, 'abbreviation')   : $organism->abbreviation;
-    $genus          = property_exists($node, 'genus')          ? property_exists($node, 'genus')          : $organism->genus;
-    $species        = property_exists($node, 'species')        ? property_exists($node, 'species')        : $organism->species;
-    $common_name    = property_exists($node, 'common_name')    ? property_exists($node, 'common_name')    : $organism->common_name;
-    $description    = property_exists($node, 'description')    ? property_exists($node, 'description')    : $organism->comment;
-    $organism_image = property_exists($node, 'organism_image') ? property_exists($node, 'organism_image') : '';
-
-    // set the organism_id in the form
-    $form['organism_id'] = array(
-      '#type' => 'value',
-      '#value' => $organism->organism_id,
-    );
-  }
-  else {
-    // get form defaults
-    $abbreviation   = property_exists($node, 'abbreviation')   ? property_exists($node, 'abbreviation')   : '';
-    $genus          = property_exists($node, 'genus')          ? property_exists($node, 'genus')          : '';
-    $species        = property_exists($node, 'species')        ? property_exists($node, 'species')        : '';
-    $common_name    = property_exists($node, 'common_name')    ? property_exists($node, 'common_name')    : '';
-    $description    = property_exists($node, 'description')    ? property_exists($node, 'description')    : '';
-    $organism_image = property_exists($node, 'organism_image') ? property_exists($node, 'organism_image') : '';
-  }
-
-  $form['genus']= array(
-    '#type' => 'textfield',
-    '#title' => t('Genus'),
-    '#required' => TRUE,
-    '#default_value' => $genus,
-  );
-  $form['species']= array(
-    '#type' => 'textfield',
-    '#title' => t('Species'),
-    '#required' => TRUE,
-    '#default_value' => $species,
-  );
-  $form['abbreviation']= array(
-    '#type' => 'textfield',
-    '#title' => t('Abbreviation'),
-    '#required' => TRUE,
-    '#default_value' => $abbreviation,
-  );
-  $form['common_name']= array(
-    '#type' => 'textfield',
-    '#title' => t('Common Name'),
-    '#required' => TRUE,
-    '#default_value' => $common_name,
-  );
-  $form['description']= array(
-    '#type' => 'textarea',
-    '#rows' => 15,
-    '#title' => t('Description'),
-    '#default_value' => $description,
-  );
-  $form['organism_image']= array(
-    '#type' => 'file',
-    '#title' => t('Organism Image'),
-    '#description' => 'Add an image for this organism',
-    '#progress_indicator' => 'bar',
-  );
-  return $form;
-}
-
-/**
- *  When a node is requested by the user this function is called to allow us
- *  to add auxiliary data to the node object.
- *
- * @ingroup tripal_organism
- */
-function chado_organism_load($nodes) {
-
-  foreach ($nodes as $nid => $node) {
-    // find the organism and add in the details
-    $organism_id = chado_get_id_for_node('organism', $nid);
-
-    // build the organism variable
-    $values = array('organism_id' => $organism_id);
-    $organism = tripal_core_generate_chado_var('organism', $values);
-
-
-    // add in the description field
-    $organism = tripal_core_expand_chado_vars($organism, 'field', 'organism.comment');
-    $nodes[$nid]->organism = $organism;
-  }
-}
 
 /**
  * Implementation of hook_form_alter()

+ 68 - 0
tripal_project/includes/tripal_project.chado_node.inc

@@ -1,5 +1,40 @@
 <?php
 
+/**
+ * Implementation of hook_node_info().
+ *
+ * This node_info, is a simple node that describes the functionallity of the module. It specifies
+ * that the title(Project Name) and body(Description) set to true so that they information can be
+ * entered
+ *
+ *
+ * @ingroup tripal_project
+ */
+function tripal_project_node_info() {
+  return array(
+    'chado_project' => array(
+      'name' => t('Project'),
+      'base' => 'chado_project',
+      'description' => t('A project from the Chado database'),
+      'has_title' => TRUE,
+      'title_label' => t('Project Name'),
+      'had_body' => TRUE,
+      'body_label' => t('Full Description'),
+      'chado_node_api' => array(
+        'base_table' => 'project',
+        'hook_prefix' => 'chado_project',
+        'record_type_title' => array(
+          'singular' => t('Project'),
+          'plural' => t('Projects')
+        ),
+        'sync_filters' => array(
+          'type_id' => FALSE,
+          'organism_id' => FALSE
+        ),
+      ),
+    ),
+  );
+}
 /**
  * Implementation of hook_form().
  *
@@ -392,4 +427,37 @@ function chado_project_node_access($node, $op, $account) {
     }
   }
   return NULL;
+}
+/**
+ *
+ * @ingroup tripal_feature
+ */
+function tripal_project_node_view($node, $view_mode, $langcode) {
+  switch ($node->type) {
+  	case 'chado_project':
+  	  // Show feature browser and counts
+  	  if ($view_mode == 'full') {
+  	    $node->content['tripal_project_base'] = array(
+  	      '#value' => theme('tripal_project_base', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_project_contact'] = array(
+  	      '#value' => theme('tripal_project_contact', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_project_properties'] = array(
+  	      '#value' => theme('tripal_project_properties', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_project_publications'] = array(
+  	      '#value' => theme('tripal_project_publications', array('node' => $node)),
+  	    );
+  	    $node->content['tripal_project_relationships'] = array(
+  	      '#value' => theme('tripal_project_relationships', array('node' => $node)),
+  	    );
+  	  }
+  	  if ($view_mode == 'teaser') {
+  	    $node->content['tripal_project_teaser'] = array(
+  	      '#value' => theme('tripal_project_teaser', array('node' => $node)),
+  	    );
+  	  }
+  	  break;
+  }
 }

+ 0 - 69
tripal_project/tripal_project.module

@@ -16,42 +16,6 @@ require('includes/tripal_project.chado_node.inc');
  * @ingroup tripal_modules
  */
 
-/**
- * Implementation of hook_node_info().
- *
- * This node_info, is a simple node that describes the functionallity of the module. It specifies
- * that the title(Project Name) and body(Description) set to true so that they information can be
- * entered
- *
- *
- * @ingroup tripal_project
- */
-function tripal_project_node_info() {
-  return array(
-    'chado_project' => array(
-      'name' => t('Project'),
-      'base' => 'chado_project',
-      'description' => t('A project from the Chado database'),
-      'has_title' => TRUE,
-      'title_label' => t('Project Name'),
-      'had_body' => TRUE,
-      'body_label' => t('Full Description'),
-      'chado_node_api' => array(
-        'base_table' => 'project',
-        'hook_prefix' => 'chado_project',
-        'record_type_title' => array(
-          'singular' => t('Project'),
-          'plural' => t('Projects')
-        ),
-        'sync_filters' => array(
-          'type_id' => FALSE,
-          'organism_id' => FALSE
-        ),
-      ),
-    ),
-  );
-}
-
 /**
  * Implements hook_views_api()
  *
@@ -224,39 +188,6 @@ function tripal_project_theme($existing, $type, $theme, $path) {
   return $items;
 }
 
-/**
- *
- * @ingroup tripal_feature
- */
-function tripal_project_node_view($node, $view_mode, $langcode) {
-  switch ($node->type) {
-    case 'chado_project':
-      // Show feature browser and counts
-      if ($view_mode == 'full') {
-        $node->content['tripal_project_base'] = array(
-          '#value' => theme('tripal_project_base', array('node' => $node)),
-        );
-        $node->content['tripal_project_contact'] = array(
-          '#value' => theme('tripal_project_contact', array('node' => $node)),
-        );
-        $node->content['tripal_project_properties'] = array(
-          '#value' => theme('tripal_project_properties', array('node' => $node)),
-        );
-        $node->content['tripal_project_publications'] = array(
-          '#value' => theme('tripal_project_publications', array('node' => $node)),
-        );
-        $node->content['tripal_project_relationships'] = array(
-          '#value' => theme('tripal_project_relationships', array('node' => $node)),
-        );
-      }
-      if ($view_mode == 'teaser') {
-        $node->content['tripal_project_teaser'] = array(
-          '#value' => theme('tripal_project_teaser', array('node' => $node)),
-        );
-      }
-      break;
-  }
-}
 /**
  *
  * @ingroup tripal_project

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

@@ -1,5 +1,38 @@
 <?php
 
+/**
+ * Implementation of hook_tripal_pub_node_info().
+ *
+ * This node_info, is a simple node that describes the functionallity of the module.
+ *
+ */
+function tripal_pub_node_info() {
+
+  return array(
+    'chado_pub' => array(
+      'name' => t('Publication'),
+      'base' => 'chado_pub',
+      'description' => t('A publication from the Chado database'),
+      'title_label' => t('Article Title'),
+      'body_label' => t('Abstract'),
+      'has_title' => TRUE,
+      'has_body' => FALSE,
+      'chado_node_api' => array(
+        'base_table' => 'pub',
+        'hook_prefix' => 'chado_pub',
+        'record_type_title' => array(
+          'singular' => t('Publication'),
+          'plural' => t('Publications')
+        ),
+        'sync_filters' => array(
+          'type_id' => FALSE,
+          'organism_id' => FALSE
+        ),
+      ),
+    ),
+  );
+}
+
 /**
  * This is the chado_pub node form callback. The arguments
  * are out of order from a typical form because it's a defined callback
@@ -889,26 +922,7 @@ function chado_pub_delete(&$node) {
   chado_query("DELETE FROM {pub} WHERE pub_id = :pub_id", array(':pub_id' => $pub_id));
 }
 
-/**
- * Implementation of hook_tripal_pub_node_info().
- *
- * This node_info, is a simple node that describes the functionallity of the module.
- *
- */
-function tripal_pub_node_info() {
 
-  return array(
-    'chado_pub' => array(
-      'name' => t('Publication'),
-      'base' => 'chado_pub',
-      'description' => t('A publication from the Chado database'),
-      'title_label' => t('Article Title'),
-      'body_label' => t('Abstract'),
-      'has_title' => TRUE,
-      'has_body' => FALSE,
-    ),
-  );
-}
 
 /**
  *

+ 0 - 137
tripal_pub/includes/tripal_pub.pub_sync.inc

@@ -1,137 +0,0 @@
-<?php
-/*
- *
- */
-function tripal_pub_sync_form() {
-  $form['sync'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Sync')
-  );
-  $form['sync']['sync_all'] = array(
-    '#markup' => t('<p>Syncing a publication will create a Drupal page for every publicatoin record in the Chado database. Click the button below to sync all publications in Chado that currently are not already synced with Drupal.</p>'),
-  );
-
-  $form['sync']['submit'] = array(
-    '#type' => 'submit',
-    '#weight' => 10,
-    '#value' => t('Sync Publications')
-  );
-
-  $form['cleanup'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Clean Up')
-  );
-  $form['cleanup']['description'] = array(
-    '#markup' => t("<p>With Drupal and chado residing in different databases ".
-        "it is possible that nodes in Drupal and publications in Chado become ".
-        "\"orphaned\".  This can occur if an pub node in Drupal is ".
-        "deleted but the corresponding chado pub is not and/or vice ".
-        "versa. Click the button below to resolve these discrepancies.</p>"),
-    '#weight' => 1,
-  );
-  $form['cleanup']['button'] = array(
-    '#type' => 'submit',
-    '#value' => t('Clean up orphaned publications'),
-    '#weight' => 2,
-  );
-  
-  return $form;
-}
-
-/*
- *
- */
-function tripal_pub_sync_form_submit($form, $form_state) {
-  global $user;    //needed to make the current users details available so access of user id is available
-  if ($form_state['values']['op'] == t('Sync Publications')) {
-    $job_args = array();
-    $job_id = tripal_add_job('Sync Publications', 'tripal_pub', 'tripal_pub_sync_pubs', $job_args, $user->uid);
-    
-  }
-  // -------------------------------------
-  // Submit the Cleanup Job if selected
-  if ($form_state['values']['op'] == t('Clean up orphaned publications')) {
-    $job_args = array();
-    tripal_add_job('Cleanup orphaned publications', 'tripal_pub',
-    'tripal_pub_cleanup', $job_args, $user->uid);
-  }
-}
-/**
- *
- *
- * @ingroup tripal_pub
- */
-function tripal_pub_sync_pubs($job_id = NULL) {
-  global $user;
-  
-  // get the list of pubs that have not yet been synced
-  // and ignore the default 'NULL' pub. we don't want
-  // to sync that one.
-  $sql = "
-    SELECT P.*
-    FROM {pub} P
-      LEFT JOIN public.chado_pub CP ON CP.pub_id = P.pub_id
-    WHERE CP.pub_id IS NULL and NOT P.title = 'NULL'
-  ";
-  $results = chado_query($sql);
-
-  // We'll use the following SQL statement for checking if the pub
-  // already exists as a drupal node.
-  $sql = "SELECT * FROM {chado_pub} WHERE pub_id = :pub_id";
-  
-  while ($pub = $results->fetchObject()) {
-
-    // check if this pub already exists in the drupal database. if it
-    // does then skip this pub and go to the next one.
-    if (!db_query($sql, array(':pub_id' => $pub->pub_id))->fetchObject()) {
-      
-      if(!$pub->pyear) {
-        watchdog('tpub_sync', "Skipping pub without published year: %title.", 
-          array('%title' => $pub->title), WATCHDOG_WARNING);
-        return FALSE;
-      }
-    
-      $new_node = new stdClass();
-      $new_node->pub_id      = $pub->pub_id;
-      $new_node->type        = 'chado_pub';
-      $new_node->uid         = $user->uid;
-      $new_node->title       = substr($pub->title, 0 ,255); // node titles can't be longer than 255 characters
-      $new_node->pubtitle    = $pub->title;
-      $new_node->pyear       = $pub->pyear;
-      $new_node->uniquename  = $pub->uniquename;
-      $new_node->type_id     = $pub->type_id;
-      $new_node->series_name = $pub->series_name;
-    
-      $form = array(); // dummy variable
-      $form_state = array(); // dummy variable
-      node_validate($new_node, $form, $form_state);
-      if (!form_get_errors()) {
-        $node = node_submit($new_node);
-        node_save($node);
-        if ($node->nid) {
-          print "Added $new_node->title\n";
-        }
-      }
-      else {
-        watchdog('tpub_sync', "Unable to create publication node. ID: %pub_id, Title: %title",
-          array('%pub_id' => $pub->pub_id, '%title' => $pub->title), WATCHDOG_WARNING);
-      }
-    }
-  }
-}
-
-/**
- * Remove orphaned drupal nodes
- *
- * @param $dummy
- *   Not Used -kept for backwards compatibility
- * @param $job_id
- *   The id of the tripal job executing this function
- *
- * @ingroup tripal_pub
- */
-function tripal_pub_cleanup($dummy = NULL, $job_id = NULL) {
-
-  return tripal_core_chado_node_cleanup_orphaned('pub', $job_id);
-
-}

+ 5 - 5
tripal_pub/tripal_pub.module

@@ -3,7 +3,6 @@
 require_once "api/tripal_pub.api.inc";
 require_once "theme/tripal_pub.theme.inc";
 require_once "includes/tripal_pub.admin.inc";
-require_once "includes/tripal_pub.pub_sync.inc";
 require_once "includes/tripal_pub.chado_node.inc";
 require_once "includes/tripal_pub.pub_importers.inc";
 require_once "includes/tripal_pub.pub_search.inc";
@@ -89,14 +88,15 @@ function tripal_pub_menu() {
 
   $items['admin/tripal/chado/tripal_pub/sync'] = array(
     'title' => ' Sync',
-    'description' => 'Sync publications in Chado with Drupal',
+    'description' => 'Create pages on this site for libraries stored in Chado',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('tripal_pub_sync_form'),
-    'access arguments' => array('administer tripal pubs'),
+    'page arguments' => array('tripal_core_chado_node_sync_form', 'tripal_pub', 'chado_pub'),
+    'access arguments' => array('administer tripal pub'),
     'type' => MENU_LOCAL_TASK,
     'weight' => 2
   );
-
+  return $items;
+  
   $items['admin/tripal/chado/tripal_pub/citation'] = array(
     'title' => 'Citations',
     'description' => 'Update publication citations',