Browse Source

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

Stephen Ficklin 11 years ago
parent
commit
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',