Index: library.actions.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/library/library.actions.inc,v
retrieving revision 1.7
diff -u -r1.7 library.actions.inc
--- library.actions.inc	23 Nov 2009 19:06:53 -0000	1.7
+++ library.actions.inc	4 Nov 2010 23:43:48 -0000
@@ -74,8 +74,8 @@
   $patron = $context['patron'];
   $item = $context['item'];
   $item_obj = library_load($item['id']);
-  if ($item_obj && !empty($item_obj->last_transaction_id) && !empty($item_obj->last_transaction_name) && !empty($item_obj->last_patron_id) && !empty($item_obj->last_due_date) && 
-      $item_obj->last_patron_id == $patron['nid'] && $item_obj->in_circulation == LIBRARY_CIRCULATION && $item_obj->library_status == LIBRARY_ITEM_UNAVAILABLE) {
+  if ($item_obj && !empty($item_obj->last_transaction_id) && !empty($item_obj->last_transaction_name) && !empty($item_obj->last_patron_uid) && !empty($item_obj->last_due_date) && 
+      $item_obj->last_patron_uid == $patron['uid'] && $item_obj->in_circulation == LIBRARY_CIRCULATION && $item_obj->library_status == LIBRARY_ITEM_UNAVAILABLE) {
 
     $type = $item_obj->type;
     $clean = library_clean_action_name($item_obj->last_transaction_name);
@@ -106,8 +106,8 @@
       $variables = array(
         '%site_name' => variable_get('site_name', 'Drupal'),
         '%patron_name' => $context['patron']['name'],
-        '%patron_email' => $context['patron']['email'],
-        '%patron_id' => $context['patron']['nid'], 
+        '%patron_email' => $context['patron']['mail'],
+        '%patron_uid' => $context['patron']['uid'], 
         '%node_url' => url('node/'. $context['item']['nid'], array('absolute' => TRUE)),  
         '%node_type' => $context['item']['node_type'],
         '%title' => $context['item']['title'],
@@ -167,7 +167,7 @@
     '#default_value' => $context['message'],
     '#cols' => '80',
     '#rows' => '20',
-    '#description' => t('The message that should be sent. You may include the following variables: %site_name, %patron_name, %patron_email, %node_url, %item_id, %node_type, %title, %barcode, %transaction_name, %notes. Not all variables will be available in all contexts.'),
+    '#description' => t('The message that should be sent. You may include the following variables: %site_name, %patron_name, %patron_mail, %patron_uid, %node_url, %item_id, %node_type, %title, %barcode, %transaction_name, %notes. Not all variables will be available in all contexts.'),
   );
   return $form;
 }
@@ -178,9 +178,9 @@
 function library_send_email_action_validate($form, $form_state) {
   $form_values = $form_state['values'];
   // Validate the configuration form.
-  if (!valid_email_address($form_values['recipient']) && $form_values['recipient'] != '%patron_email') {
-    // We want the literal %patron_email placeholder to be emphasized in the error message.
-    form_set_error('recipient', t('Please enter a valid email address or %patron_email.', array('%patron_email' => '%patron_email')));
+  if (!valid_email_address($form_values['recipient']) && $form_values['recipient'] != '%patron_mail') {
+    // We want the literal %patron_mail placeholder to be emphasized in the error message.
+    form_set_error('recipient', t('Please enter a valid email address or %patron_mail.', array('%patron_mail' => '%patron_mail')));
   }
 }
 
@@ -206,14 +206,12 @@
 
   $recipient = $context['recipient'];
   $patron = $context['patron'];
-  $language = language_default();
-  if (!empty($patron->uid)) {
-    $account = user_load($patron->uid);
-    $language = user_preferred_language($account);
-  }
 
-  if ($recipient == '%patron_email') {
-      $recipient = $context['patron']['email'];
+  $account = user_load($patron->uid);
+  $language = user_preferred_language($account);
+
+  if ($recipient == '%patron_mail') {
+      $recipient = $context['patron']['mail'];
   }
   
   $params = array('context' => $context);
Index: library.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/library/library.admin.inc,v
retrieving revision 1.6
diff -u -r1.6 library.admin.inc
--- library.admin.inc	23 Nov 2009 19:06:53 -0000	1.6
+++ library.admin.inc	4 Nov 2010 23:43:48 -0000
@@ -18,6 +18,13 @@
     '#return_value' => 1,
     '#description' => t('This is recommended if you have multiple copies of an item. However, you must have unique identifiers for every instance.  If you have multiple copies but do not use barcodes, library management will be against whether any copy is available and will not track any specific copy.'),
   );
+  $form['library_disable_patron_autocomplete'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Disable Patron Autocomplete on Transactions'),
+    '#default_value' => variable_get('library_disable_patron_autocomplete', 0),
+    '#return_value' => 1,
+    '#description' => t('This allows patron for a transaction to be selected without autocompletion. Will only work with Drupal username, so make sure the username is the barcode if using a barcode scanner.'),
+  );
   $form['library_unique_titles'] = array(
     '#type' => 'checkbox',
     '#title' => t('Check that Library Item Titles are Unique (Within a Given Content Type)'),
@@ -138,6 +145,24 @@
     '#size' => 20,
     '#maxlength' => 20,
   );
+  
+  if (module_exists('profile')) {
+    $form['library_profile'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Core Profile Fields'),
+      '#description' => t('Choose profile fields to be used when using autocomplete to select a patron. Note: since profile fields do not allow for unique values, whatever unique identifier you are using (such as a barcode) should be the Drupal username. Barcode values below are included only to prevent data loss from previous versions of this module.'),
+    );
+    $profile_fields = db_query("select title, name from {profile_fields} where type = 'textfield'");
+    while ($field = db_fetch_object($profile_fields)) {
+      $form['library_profile']['library_profile_' . $field->name] = array(
+        '#type' => 'checkbox',
+        '#title' => t($field->title . ' (' . $field->name . ')'),
+        '#default_value' => variable_get('library_profile_' . $field->name, 0),
+        '#return_value' => 1,
+      );
+    }
+  }
+
   return system_settings_form($form);
 }
 
@@ -382,13 +407,13 @@
 function library_autocomplete($string) {
   $matches = array();
   if (variable_get('library_item_barcodes', LIBRARY_NO_BARCODES) == LIBRARY_BARCODES) {
-    $result = db_query_range("SELECT l.id, l.barcode, n.title FROM {node} n INNER JOIN {library} l ON n.nid = l.nid WHERE n.status = 1 AND n.type <> 'patron' AND l.barcode <> '' AND LOWER(l.barcode) LIKE LOWER('%s%%')", check_plain($string), 0, 10);
+    $result = db_query_range("SELECT l.id, l.barcode, n.title FROM {node} n INNER JOIN {library} l ON n.nid = l.nid WHERE n.status = 1 AND l.barcode <> '' AND LOWER(l.barcode) LIKE LOWER('%s%%')", check_plain($string), 0, 10);
     while ($item = db_fetch_object($result)) {
       $matches[$item->barcode .' [title:'. $item->title .'] [id:'. $item->id .']'] = check_plain($item->barcode);
     }
   }
   else {
-    $result = db_query_range("SELECT DISTINCT l.id, n.title FROM {node} n INNER JOIN {library} l ON n.nid = l.nid WHERE n.status = 1 AND n.type <> 'patron' AND LOWER(n.title) LIKE LOWER('%s%%')", check_plain($string), 0, 10);
+    $result = db_query_range("SELECT DISTINCT l.id, n.title FROM {node} n INNER JOIN {library} l ON n.nid = l.nid WHERE n.status = 1 AND LOWER(n.title) LIKE LOWER('%s%%')", check_plain($string), 0, 10);
     while ($item = db_fetch_object($result)) {
       $my_key = $item->title .' [id:'. $item->id .']';
       $matches[$my_key] = check_plain($my_key);
@@ -409,9 +434,10 @@
     }
     else {
       $num_emails = 0;
-      foreach ($records as $patron_id => $record) {
+      foreach ($records as $patron_uid => $record) {
         $params = $record;
         drupal_mail('library', 'notify_overdue', $params['patron']['patron_email'], language_default(), $params);
+        watchdog('library', 'Overdue notice sent to %email', array('%email' => $params['patron']['patron_email']));
         $num_emails++;
       }
       drupal_set_message(t($num_emails .' email(s) sent successfully.'));
Index: library.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/library/library.info,v
retrieving revision 1.4
diff -u -r1.4 library.info
--- library.info	12 Sep 2008 20:25:01 -0000	1.4
+++ library.info	4 Nov 2010 23:43:48 -0000
@@ -1,7 +1,6 @@
 ; $Id: library.info,v 1.4 2008/09/12 20:25:01 jastraat Exp $
 name 		= "Library"
-description 	= "Include content types in a library. CCK, Trigger, and Views are recommended."
-dependencies[] = patron
+description 	= "Include content types in a library. CCK, Trigger, Core Profile, and Views are recommended."
 package 	= Library
 core 		= "6.x"
 
Index: library.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/library/library.install,v
retrieving revision 1.5
diff -u -r1.5 library.install
--- library.install	23 Nov 2009 19:06:53 -0000	1.5
+++ library.install	4 Nov 2010 23:43:48 -0000
@@ -73,11 +73,12 @@
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE),
-      'patron_id' => array(
-        'description' => t('The associated customer.'),
+      'uid' => array(
+        'description' => t('The associated patron user.'),
         'type' => 'int',
         'unsigned' => TRUE,
-        'not null' => TRUE),
+        'not null' => TRUE,
+        'default' => 0),
       'action_aid' => array(
         'description' => t('The action performed.'),
         'type' => 'int',
@@ -102,12 +103,12 @@
     ),
     'indexes' => array(
       'item_id'     => array('item_id'),
-      'patron_id'     => array('patron_id'),
+      'uid'     => array('uid'),
       'action_aid'  => array('action_aid'),
       ),
     'primary key' => array('tid'),
-    );
- $schema['library_actions'] = array(
+  );
+  $schema['library_actions'] = array(
     'description' => t('The table where library transactions are stored.'),
     'fields' => array(
       'aid' => array(
@@ -142,7 +143,7 @@
   db_query("INSERT INTO {library_actions} (name, status_change) VALUES ('%s', %d)", 'Check In', 2);
   global $base_url;
   // Notify of changes
-  drupal_set_message(t('Library module successfully installed. You can configure library settings <a href="@link">here</a>. To start creating library items, edit one or more content types to be included in the library.', array('@link' => $base_url .'/admin/settings/library')));
+  drupal_set_message(st('Library module successfully installed. You can configure library settings <a href="@link">here</a>. To start creating library items, edit one or more content types to be included in the library.', array('@link' => $base_url .'/admin/settings/library')));
 
 }
 
@@ -191,6 +192,80 @@
   cache_clear_all(null, 'cache_menu');
   cache_clear_all(null, 'cache_page');
 
-  drupal_set_message(t('Library module successfully uninstalled'));
+  drupal_set_message(st('Library module successfully uninstalled'));
+}
+
+function library_update_6201() {
+  $ret = array();
+  $empty_patrons = db_result(db_query("SELECT COUNT(*) FROM {library_patrons} WHERE patron_uid IS NULL OR patron_uid = 0"));
+  
+  //don't attempt to do the upgrade if patrons aren't users
+  if (variable_get('patron_is_user', 0) == 0 || $empty_patrons > 0) {
+    drupal_set_message(t('This module update eliminates the patron module and replaces patrons with Drupal users. Please return to <a href="@patron-settings">patron settings</a> and check Associate Library Patrons with Drupal Users. Then, create associated users for all existing patrons with the same e-mail address used in the patron node. After resaving the associated patrons, try this update again.', array('@patron-settings' => base_path() .'admin/settings/library/patrons')), 'warning', FALSE);
+    $ret['#abort'] = array('success' => FALSE, 'query' => t('Library module has updates, but updating would currently result in data loss.'));
+    return $ret;
+  }
+  $uids = db_result(db_query("SELECT COUNT(*) FROM {library_patrons} WHERE patron_uid IS NOT NULL"));
+
+  // only import patron data if patrons exist
+  if ($uids > 0 ) {
+    if (!module_exists('profile')) {
+      //enable the core profile module to store the patron information
+      drupal_install_modules(array('profile'));
+    }
+    $ret[] = update_sql("INSERT INTO {profile_fields} (title, name, explanation, category, type, page, visibility) VALUES ('First name','profile_patron_name_first','Imported from the patron module.', 'Library', 'textfield', '', 1)");
+    $ret[] = update_sql("INSERT INTO {profile_fields} (title, name, explanation, category, type, page, visibility) VALUES ('Last name','profile_patron_name_last','Imported from the patron module.', 'Library', 'textfield', '', 1)");
+    $ret[] = update_sql("INSERT INTO {profile_fields} (title, name, explanation, category, type, page, visibility) VALUES ('Barcode','profile_patron_barcode', 'Imported from the patron module.', 'Library', 'textfield', '', 1)");
+  }
+  cache_clear_all();
+  menu_rebuild();
+  return $ret;
+}
+
+function library_update_6202() {
+  $ret = array();
+  
+  //Transfer patron info associated with users to profile fields
+  $patrons = db_query("SELECT * FROM {library_patrons} p, {users} u WHERE p.patron_uid = u.uid AND p.patron_uid IS NOT NULL");
+  if (module_exists('profile')) {
+    while ($patron = db_fetch_object($patrons)) {
+      $patron_user = user_load(array('uid' => $patron->patron_uid)); 
+      $data=array(
+        'profile_patron_name_last' => $patron->name_last,
+        'profile_patron_name_first' => $patron->name_first,
+        'profile_patron_barcode' => $patron->barcode
+      );
+
+      $successful = user_save($patron_user, $data, 'Library');
+      if (!$successful) {
+        watchdog('Library','Patron conversion of @name failed', array('@name' => $patron->name_first .' '. $patron->name_last));
+      }
+      else {
+        watchdog('Library','Patron @name converted to profile fields.', array('@name' => $patron->name_first .' '. $patron->name_last));
+      }
+    }
+  }
+  return $ret;
+}
+
+function library_update_6203() {
+  $ret = array();
+  //Insert patron uids into transactions table
+  $ret[] = update_sql("UPDATE {library_transactions} lt JOIN {library_patrons} lp on lt.patron_id = lp.nid SET lt.patron_id = lp.patron_uid");
+  
+  //Schema update to transactions table
+  db_drop_index($ret, 'library_transactions', 'patron_id');
+  $spec = array('description' => t('The associated patron user.'), 'type' => 'int','unsigned' => TRUE,'not null' => TRUE, 'default' => 0);
+  db_change_field($ret, 'library_transactions', 'patron_id', 'uid', $spec);
+  db_add_index($ret, 'library_transactions', 'uid', array('uid'));
+  return $ret;
+}
+
+function library_update_6204() {
+  module_disable(array('patron'));
+  drupal_uninstall_module('patron');
+  cache_clear_all();
+  menu_rebuild();
+  return array();
 }
 
Index: library.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/library/library.module,v
retrieving revision 1.12
diff -u -r1.12 library.module
--- library.module	1 Nov 2010 22:49:04 -0000	1.12
+++ library.module	4 Nov 2010 23:43:49 -0000
@@ -88,37 +88,26 @@
  * Determine whether a user may perform any library action
  */
 function library_action_access($aid) {
-  $may_view_patron = FALSE;
-  if (user_access('view patron content')) {
-    $may_view_patron = TRUE;
-  }
-  else {
-    global $user;
-    $user_patron = patron_load_by_uid($user->uid);
-    if (is_object($user_patron)) {
-      $may_view_patron = TRUE;
-    }
-  }
-  if (user_access('administer transactions') && $may_view_patron) {
+  global $user;
+  if (user_access('administer transactions', $user)) {
     return TRUE;
   }
-  elseif ($aid && $may_view_patron) {
+  elseif ($aid) {
     $action = library_get_action($aid);
     if ($action->name) {
-      return user_access('submit library '. $action->name);
+      return user_access('submit library '. $action->name, $user);
     }
   }
   return FALSE;
 }
 
-function library_history_access($node) {
+function library_history_user_access($patron_user) {
+  global $user;
   if (user_access('view library history')) {
     return TRUE;
   }
-  elseif (user_access('view own library history')) {
-    global $user;
-    $user_patron = patron_load_by_uid($user->uid);
-    if (is_object($user_patron) && $user_patron->nid == $node->nid) {
+  elseif (user_access('view own library history', $user)) {
+    if ($patron_user->uid == $user->uid) {
       return TRUE;
     }
   }
@@ -450,7 +439,7 @@
     if ($item->in_circulation == LIBRARY_CIRCULATION && $item->library_status == LIBRARY_ITEM_UNAVAILABLE) {
       $last = library_get_last_transaction_by_item($item, LIBRARY_ACTION_TYPE_UNAVAILABLE);
       if ($last) {
-        $item->last_patron_id = $last->patron_id;
+        $item->last_patron_uid = $last->uid;
         $item->last_transaction_id = $last->tid;
         $item->last_transaction_name = $last->action_name;
         if (!empty($last->duedate)) {
@@ -477,7 +466,16 @@
     'title' => 'History',
     'page callback' => 'library_history',
     'page arguments' => array(1),
-    'access callback' => 'library_history_access',
+    'access arguments' => array('view library history'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 2,
+    'file' => 'library.pages.inc',
+  );
+  $items['user/%user/library/history'] = array(
+    'title' => 'History',
+    'page callback' => 'library_history_user',
+    'page arguments' => array(1),
+    'access callback' => 'library_history_user_access',
     'access arguments' => array(1),
     'type' => MENU_LOCAL_TASK,
     'weight' => 2,
@@ -572,6 +570,12 @@
     'access arguments' => array('access content'),
     'type' => MENU_CALLBACK,
   );
+  $items['patrons/autocomplete'] = array(
+    'title' => 'Patron Autocomplete',
+    'page callback' => 'library_patron_autocomplete',
+    'access arguments' => array('access user profiles'),
+    'type' => MENU_CALLBACK
+  );
   return $items;
 }
 
@@ -843,7 +847,7 @@
     while ($item = db_fetch_object($result)) {
       $library_item = library_load($item->id);
       $items[$row]['library_status'] = ($library_item->library_status ? $library_item->library_status : LIBRARY_ITEM_AVAILABLE);
-      $items[$row]['last_patron_id'] = ($library_item->last_patron_id ? $library_item->last_patron_id : '');
+      $items[$row]['last_patron_uid'] = ($library_item->last_patron_uid ? $library_item->last_patron_uid : '');
       $items[$row]['last_due_date'] = ($library_item->last_due_date ? $library_item->last_due_date : '');
       $items[$row]['last_transaction_id'] = ($library_item->last_transaction_id ? $library_item->last_transaction_id : '');
       $items[$row]['last_transaction_name'] = ($library_item->last_transaction_name ? $library_item->last_transaction_name : '');
@@ -935,13 +939,13 @@
   $overdueitems = array();
   while ($result = db_fetch_object($items)) {
     $item = library_load($result->id);
-    if (!empty($item->last_patron_id) && !empty($item->last_due_date) && (time() > $item->last_due_date)) {
-      $patron = node_load($item->last_patron_id);
-      if (!isset($overdueitems[$item->last_patron_id]['patron']['patron_email'])) {
-        $overdueitems[$item->last_patron_id]['patron']['patron_email'] = $patron->email;
-        $overdueitems[$item->last_patron_id]['patron']['patron_name'] = $patron->name_first .' '. $patron->name_last;
+    if (!empty($item->last_patron_uid) && !empty($item->last_due_date) && (time() > $item->last_due_date)) {
+      $patron = user_load($item->last_patron_uid);
+      if (!isset($overdueitems[$item->last_patron_uid]['patron']['patron_email'])) {
+        $overdueitems[$item->last_patron_uid]['patron']['patron_email'] = $patron->mail;
+        $overdueitems[$item->last_patron_uid]['patron']['patron_name'] = $patron->name;
       }
-      $overdueitems[$item->last_patron_id]['items'][$item->id] = array('item_name' => $item->title, 'nid' => $item->nid, 'due_date' => $item->last_due_date, 'in_circulation' => $item->in_circulation);
+      $overdueitems[$item->last_patron_uid]['items'][$item->id] = array('item_name' => $item->title, 'nid' => $item->nid, 'due_date' => $item->last_due_date, 'in_circulation' => $item->in_circulation);
     }
   }
   return $overdueitems;
@@ -1000,11 +1004,13 @@
 
 function library_get_transactions_by_item($item) {
   $result = db_query('SELECT lt.created, lt.tid, la.aid, la.name as "action_name", 
-                      la.status_change, lt.patron_id, lt.item_id, lt.duedate, lt.notes, l.in_circulation, l.barcode, n.title as "item_name", n.nid
+                      la.status_change, lt.uid, lt.item_id, lt.duedate, lt.notes, l.in_circulation, l.barcode, n.title as "item_name", n.nid
                       FROM {library_transactions} lt, {library_actions} la, {library} l, {node} n 
                       WHERE la.aid = lt.action_aid AND n.nid = l.nid AND lt.item_id = l.id AND l.id = %d 
                       ORDER BY lt.created DESC', $item->id);
   while ($transaction = db_fetch_object($result)) {
+    $patron = user_load($transaction->uid);
+    $transaction->username = $patron->name;
     $transaction->library_status = isset($item->library_status) ? $item->library_status : LIBRARY_ITEM_AVAILABLE;
     $transactions[] = $transaction;
   }
@@ -1017,28 +1023,20 @@
 }
 
 function library_get_transactions_by_node($node) {
-  if ($node->type == 'patron') {
-    $temp_transactions = library_get_transactions_by_patron($node);
-    if (!empty($temp_transactions)) {
-      $transactions[] = $temp_transactions;
-    }
-  }
-  else {
-    foreach ($node->items as $instance) {
-      $item = (object) $instance;
-      $temp_transactions = library_get_transactions_by_item($item);
-      if (!empty($temp_transactions)) { 
-        $transactions[] = library_get_transactions_by_item($item);
-      }
+  foreach ($node->items as $instance) {
+    $item = (object) $instance;
+    $temp_transactions = library_get_transactions_by_item($item);
+    if (!empty($temp_transactions)) { 
+      $transactions[] = library_get_transactions_by_item($item);
     }
   }
   return $transactions;
 }
 
-function library_get_transactions_by_patron($node) {
-  $result = db_query('SELECT lt.created, lt.tid, la.aid, la.name as "action_name", la.status_change, lt.patron_id, lt.item_id, lt.duedate, lt.notes, n.title as "item_name", n.nid FROM {library_transactions} lt, {library_actions} la, {node} n WHERE la.aid = lt.action_aid AND n.nid = lt.nid AND lt.patron_id = %d ORDER BY lt.created DESC', $node->nid);
+function library_get_transactions_by_user($user) {
+  $result = db_query('SELECT lt.created, lt.tid, la.aid, la.name as "action_name", la.status_change, lt.uid, lt.item_id, lt.duedate, lt.notes, n.title as "item_name", n.nid FROM {library_transactions} lt, {library_actions} la, {node} n WHERE la.aid = lt.action_aid AND n.nid = lt.nid AND lt.uid = %d ORDER BY lt.created DESC', $user->uid);
   
-  $items_result = db_query('SELECT DISTINCT item_id FROM {library_transactions} WHERE patron_id = %d', $node->nid);
+  $items_result = db_query('SELECT DISTINCT item_id FROM {library_transactions} WHERE uid = %d', $user->uid);
   $statuses = array();
   $barcodes = array();
   $circulation = array();
@@ -1053,6 +1051,7 @@
     $transaction->library_status = $statuses[$transaction->item_id];
     $transaction->barcode = $barcodes[$transaction->item_id];
     $transaction->in_circulation = $circulation[$transaction->item_id];
+    $transaction->username = $user->name;
     $transactions[] = $transaction;
   }
   if (!empty($transactions)) {
@@ -1065,7 +1064,7 @@
 
 function library_get_transaction_by_tid($tid) {
   if (isset($tid) && is_numeric($tid)) {
-    $result = db_fetch_object(db_query('SELECT lt.created, la.name as "action_name", la.status_change, lp.nid as "patron_id", lp.name_last, lp.name_first, n.title as "item_name", n.type as "item_type", lt.item_id as "item_id", lt.nid as "nid", lt.duedate, lt.notes FROM {library_transactions} lt, {library_actions} la, {library_patrons} lp, {node} n WHERE la.aid = lt.action_aid AND lp.nid = lt.patron_id AND n.nid = lt.nid AND lt.tid = %d', $tid));
+    $result = db_fetch_object(db_query('SELECT lt.created, la.name as "action_name", la.status_change, u.uid, u.name as "username", n.title as "item_name", n.type as "item_type", lt.item_id as "item_id", lt.nid as "nid", lt.duedate, lt.notes FROM {library_transactions} lt, {library_actions} la, {users} u, {node} n WHERE la.aid = lt.action_aid AND u.uid = lt.uid AND n.nid = lt.nid AND lt.tid = %d', $tid));
     return $result;
   }
   else {
@@ -1176,18 +1175,17 @@
   $actions = library_actions($aids, $user);
   $action_links = array();
   
-  $patron_id = '';
-  if (!user_access('view patron content')) {
-    $user_patron = patron_load_by_uid($user->uid);
-    if (is_object($user_patron)) {
-      $patron_id = $user_patron->nid;
-    }
+  $patron_uid = '';
+  global $user;
+  $librarian = user_access('administer transactions', $user) && user_access('access user profiles', $user);
+  if (!$librarian) {
+    $patron_uid = $user->uid;
   }
 
   foreach ($actions as $aid => $action) {
-    if (($action['status_change'] == LIBRARY_ACTION_TYPE_AVAILABLE || $item['library_status'] == LIBRARY_ITEM_UNAVAILABLE) && !empty($item['last_patron_id']) ) {
-      if (empty($patron_id) || ($item['last_patron_id'] == $patron_id)) {
-        $action_links[] = l($action['name'], 'library-items/transaction/'. $aid .'/'. $item['id'] .'/'. $item['last_patron_id']);
+    if (($action['status_change'] == LIBRARY_ACTION_TYPE_AVAILABLE || $item['library_status'] == LIBRARY_ITEM_UNAVAILABLE) && !empty($item['last_patron_uid']) ) {
+      if (empty($patron_uid) || ($item['last_patron_uid'] == $patron_uid)) {
+        $action_links[] = l($action['name'], 'library-items/transaction/'. $aid .'/'. $item['id'] .'/'. $item['last_patron_uid']);
       }
     }
     else {
@@ -1524,4 +1522,45 @@
     $text = variable_get('library_unavailable_noduedates_text', 'UNAVAILABLE');
   }
   return $text;
+}
+
+/**
+ * Retrieve a pipe delimited string of autocomplete suggestions for existing patron.
+ */
+function library_patron_autocomplete($string) {
+  $matches = array();
+  $result = NULL;
+  if (module_exists('profile')) {
+    $profile_fields = db_query("SELECT fid, name FROM {profile_fields} WHERE type='textfield'"); 
+    $fids = array();
+    while ($field = db_fetch_object($profile_fields)) {
+      if (variable_get('library_profile_' . $field->name, 0) == 1) {
+        $fids[] = $field->fid;
+        /*
+        if (!empty($fids)) {
+          $fids .= "OR fid='" . $field->fid . "'";
+        }
+        else {
+          $fids = "fid='" . $field->fid . "'";
+        }
+        */
+      }
+    }
+    if (!empty($fids)) {
+      $fid_string = implode(',', $fids);
+      if(!empty($fid_string)){
+        $result = db_query_range("SELECT u.uid, CONCAT(pv.value,' (', u.name, ')') as name FROM {users} u JOIN (SELECT uid, GROUP_CONCAT(value SEPARATOR ', ' ) as value FROM {profile_values} WHERE fid IN (%s) GROUP BY (uid)) AS pv ON u.uid = pv.uid WHERE (LOWER(u.name) LIKE LOWER('%s%%') or LOWER(pv.value) LIKE LOWER('%%%s%%'))", $fid_string, check_plain($string), check_plain($string), 0, 10);
+      }
+    }
+  }
+  if (empty($result)) {
+    $result = db_query_range("SELECT uid, name FROM {users} WHERE LOWER(name) LIKE LOWER('%%%s%%')", check_plain($string), 0, 10);
+  }
+
+  while ($patron = db_fetch_object($result)) {
+        $matches[$patron->name .' [uid:'. $patron->uid .']'] = check_plain($patron->name);
+  }
+
+  print drupal_to_js($matches);
+  exit();
 }
\ No newline at end of file
Index: library.pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/library/library.pages.inc,v
retrieving revision 1.9
diff -u -r1.9 library.pages.inc
--- library.pages.inc	23 Nov 2009 19:06:53 -0000	1.9
+++ library.pages.inc	4 Nov 2010 23:43:49 -0000
@@ -7,21 +7,18 @@
  */
 
 function library_transaction_form(&$form_state, $aid, $item = NULL) {
-  $patron_id = arg(4);
+  $patron_uid = arg(4);
+  global $user;
+  $librarian = user_access('access user profiles', $user) && user_access('administer transactions', $user);
 
-  if ($patron_id) {
-    $patron = node_load($patron_id);
+  if ($patron_uid && $patron_uid == $user->uid) {
+    $patron = $user;
   }
-  elseif (!user_access('view patron content')) {
-    global $user;
-    $user_patron = patron_load_by_uid($user->uid);
-    if (is_object($user_patron)) {
-      $patron = $user_patron;
-    }
-    else {
-      drupal_set_message('You do not have sufficient permissions.', 'error');
-      drupal_goto('/');
-    }
+  elseif ($patron_uid && is_numeric($patron_uid) && $librarian) {
+    $patron = user_load($patron_uid);
+  }
+  elseif ($librarian == FALSE) {
+    $patron = $user;
   }
   
   if ($aid) {
@@ -74,20 +71,20 @@
   }
   
   if ($patron) {
-    $form['patron_id'] = array(
+    $form['patron_uid'] = array(
       '#type' => 'value',
-      '#value' => $patron->nid,
+      '#value' => $patron->uid,
     );
-    $form['patron_id_set'] = array(
+    $form['patron_uid_set'] = array(
       '#type' => 'value',
-      '#value' => $patron->nid,
+      '#value' => $patron->uid,
     );
     $form['patron_display'] = array(
       '#type' => 'item',
-      '#value' => $patron->name_first .' '. $patron->name_last,
+      '#value' => $patron->name,
       '#title' => t('Patron'),
     );
-    if (user_access('view patron content') && $action->status_change == LIBRARY_ACTION_NO_CHANGE) {
+    if ($librarian && $action->status_change == LIBRARY_ACTION_NO_CHANGE) {
       $link = 'library-items/transaction/'. $action->aid;
       if ($item) {
         $link .= '/'. $item->id;
@@ -100,11 +97,19 @@
       );
     }
   }
+  elseif (variable_get('library_disable_patron_autocomplete', 0) == 1){
+    $form['patron_uid'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Patron'),
+      '#default_value' => '',
+      '#required' => TRUE
+    );    
+  }
   else {
-    $form['patron_id'] = array(
+    $form['patron_uid'] = array(
       '#type' => 'textfield',
       '#title' => t('Patron'),
-      '#default_value' => ($patron ? $patron->title .' [nid:'. $patron->nid .']' : ''),
+      '#default_value' => ($patron ? $patron->name .' [uid:'. $patron->uid .']' : ''),
       '#autocomplete_path' => 'patrons/autocomplete',
       '#required' => TRUE
     );
@@ -135,42 +140,44 @@
  */
 function library_transaction_form_validate($form, &$form_state) {
   $barcodes = variable_get('library_item_barcodes', LIBRARY_NO_BARCODES) == LIBRARY_BARCODES;
-
+  $autocomplete_disabled = variable_get('library_disable_patron_autocomplete', 0) == 1;
   //Validate patron information
-  if ($form_state['values']['patron_id']) {
-    if ($form_state['values']['patron_id_set'] && is_numeric($form_state['values']['patron_id'])) {
-      $nid = $form_state['values']['patron_id'];
-      $n_patron = node_load($nid);
-      if (empty($n_patron)) {
-        form_set_error('patron_id', t('Invalid Patron ID.'));
+  if ($form_state['values']['patron_uid']) {
+    if ($form_state['values']['patron_uid_set'] && is_numeric($form_state['values']['patron_uid'])) {
+      $uid = $form_state['values']['patron_uid'];
+      $patron = user_load($uid);
+      if (empty($patron)) {
+        form_set_error('patron_uid', t('Invalid Patron User ID.'));
+      }
+    }
+    elseif ($autocomplete_disabled && !empty($form_state['values']['patron_uid'])) {
+      $patron = user_load(array('name' => $form_state['values']['patron_uid']));
+      if (empty($patron)) {
+        form_set_error('patron_uid', t('Library Patron: Could not find a corresponding Drupal user.'));
       }
     }
     else {
-      preg_match('/^(?:\s*|(.*) )?\[\s*nid\s*:\s*(\d+)\s*\]$/', $form_state['values']['patron_id'], $matches);
+      preg_match('/^(?:\s*|(.*) )?\[\s*uid\s*:\s*(\d+)\s*\]$/', $form_state['values']['patron_uid'], $matches);
       if (!empty($matches)) {
-        // explicit nid
-        list($temp, $title, $nid) = $matches;
-        if (!empty($title) && ($n_patron = node_load($nid))) {
-          if ($title != $n_patron->title) {
-            form_set_error('patron_id', t('Library Patron: Name mismatch. Please check your selection.'));
-          }
+        // explicit uid
+        list($temp, $name, $uid) = $matches;
+        $patron = user_load($uid);
+        if (empty($patron)) {
+          form_set_error('patron_uid', t('Library Patron: Could not find a corresponding Drupal user.'));
         }
       }
     }
-    if (!empty($n_patron)) {
-      $form_state['values']['patron_email'] = $n_patron->email;
-      $form_state['values']['patron_uid'] = $n_patron->patron_uid;
-      $form_state['values']['patron_id'] = $n_patron->nid;
-      $form_state['values']['patron_name'] = $n_patron->title;
-      $form_state['values']['patron_name_last'] = $n_patron->name_last;
-      $form_state['values']['patron_name_first'] = $n_patron->name_first;
+    if (!empty($patron)) {
+      $form_state['values']['patron_email'] = $patron->mail;
+      $form_state['values']['patron_uid'] = $patron->uid;
+      $form_state['values']['patron_name'] = $patron->name;
     }
     else {
-      form_set_error('patron_id', t('You must specify a library patron.'));
+      form_set_error('patron_uid', t('You must specify a library patron.'));
     }
   }
   else {
-    form_set_error('patron_id', t('You must specify a library patron.'));
+    form_set_error('patron_uid', t('You must specify a library patron.'));
   }
   
   if ($form_state['values']['item_id']) {
@@ -210,8 +217,8 @@
       elseif ($item->library_status == LIBRARY_ITEM_UNAVAILABLE &&  $action->status_change == LIBRARY_ITEM_TYPE_UNAVAILABLE) {
         form_set_error('action_aid', t('This item is not currently available.'));
       }
-      elseif ($item->library_status == LIBRARY_ITEM_UNAVAILABLE && $n_patron->nid <> $item->last_patron_id) {
-        form_set_error('patron_id', t('This item was made unavailable by a different patron.  Only that patron can perform actions on it.'));
+      elseif ($item->library_status == LIBRARY_ITEM_UNAVAILABLE && $patron->uid <> $item->last_patron_uid) {
+        form_set_error('patron_uid', t('This item was made unavailable by a different patron.  That patron must release the item first.'));
       }
     }  
   }
@@ -237,7 +244,7 @@
   elseif ($form_state['values']['action_status_change'] == LIBRARY_ACTION_TYPE_AVAILABLE) {
     $new_status = LIBRARY_ITEM_AVAILABLE;   
   }
-  db_query("INSERT {library_transactions} (nid, item_id, patron_id, action_aid, duedate, notes, created) VALUES (%d, %d, %d, %d, %d, '%s', %d)", $form_state['values']['nid'], $form_state['values']['item_id'], $form_state['values']['patron_id'], $form_state['values']['action_aid'], $duedate, check_plain($form_state['values']['notes']), $now);
+  db_query("INSERT {library_transactions} (nid, item_id, uid, action_aid, duedate, notes, created) VALUES (%d, %d, %d, %d, %d, '%s', %d)", $form_state['values']['nid'], $form_state['values']['item_id'], $form_state['values']['patron_uid'], $form_state['values']['action_aid'], $duedate, check_plain($form_state['values']['notes']), $now);
   if ($form_state['values']['action_status_change'] > LIBRARY_ACTION_NO_CHANGE) {
     db_query("UPDATE {library} set library_status = %d WHERE id = %d", $new_status, $form_state['values']['item_id']);
   }
@@ -251,7 +258,7 @@
       'id' => $form_state['values']['item_id'], 'nid' => $form_state['values']['nid'], 'title' => $form_state['values']['item_name'], 'barcode' => $form_state['values']['barcode'], 'node_type' => $form_state['values']['node_type']
     );
     $context['transaction'] = array('id' => $transaction_id, 'action_name' => $form_state['values']['action_name'], 'aid' => $form_state['values']['action_aid'], 'notes' => check_plain($form_state['values']['notes']), 'duedate' => $duedate, 'created' => $now);
-    $context['patron'] = array('nid' => $form_state['values']['patron_id'], 'name' => $form_state['values']['patron_name_first'] .' '. $form_state['values']['patron_name_last'], 'email' => $form_state['values']['patron_email'], 'uid' => $form_state['values']['patron_uid']);
+    $context['patron'] = array('name' => $form_state['values']['patron_name'], 'mail' => $form_state['values']['patron_email'], 'uid' => $form_state['values']['patron_uid']);
     $actions = _library_get_hook_aids('library', 'after_'. $clean);
     if (!empty($actions)) {
       actions_do($actions, $object, $context);
@@ -262,12 +269,18 @@
 }
 
 function library_transaction_view($tid) {
+  global $user;
   $transaction = library_get_transaction_by_tid($tid);
   if (isset($transaction)) {
     $list[] = t("Date: @action_date", array('@action_date' => format_date($transaction->created, 'custom', 'M j, Y')));
     $list[] = t("Item: ". l($transaction->item_name, 'node/'. $transaction->nid));
     $list[] = t("Action: @action", array('@action' => $transaction->action_name));
-    $list[] = t("Patron: ". l($transaction->name_first .' '. $transaction->name_last, 'node/'. $transaction->patron_id));
+    if (user_access('access user profiles', $user)) {
+      $list[] = t("Patron: ". l($transaction->username, 'user/'. $transaction->uid));
+    }
+    else {
+      $list[] = t("Patron: N/A");
+    }
     if (!empty($transaction->duedate)) {
       $list[] = t('Due Date: @due_date', array('@due_date' => format_date($transaction->duedate, 'custom', 'M j, Y')));
     }
@@ -286,17 +299,12 @@
  */
 function library_history($node) { 
   $duedate_enabled = library_duedates_enabled($node->type);  
-  global $user;
 
-  if ($node->type == 'patron') {
-    $is_patron = TRUE;
-  }
-  else {
-    $is_patron = FALSE;
-  }
-
-  if (library_item_in_library($node) || $is_patron) {
+  if (library_item_in_library($node)) {
     $header = array(t('Date'), t('Transaction'), t('Notes'));
+    if (user_access('access user profiles')) {
+      $header[] = t('Patron');
+    }
     if ($duedate_enabled) {
       $header[] = t('Due Date');
     }
@@ -323,13 +331,17 @@
             $detail_link = l('View Details', 'library-items/transaction/view/'. $transaction->tid);
           }
           if ($cur_item <> $last_item) {
-            $item = array('id' => $transaction->item_id, 'library_status' => $transaction->library_status, 'last_patron_id' => $transaction->patron_id, 'in_circulation' => $transaction->in_circulation);
+            $item = array('id' => $transaction->item_id, 'library_status' => $transaction->library_status, 'last_patron_uid' => $transaction->uid, 'in_circulation' => $transaction->in_circulation);
             $links = library_get_action_links($item);
             if (!empty($links)) {
               $action_link = implode(" | ", $links);
             }
           } 
           $temp_array = array($created, $transaction->action_name, $transaction->notes);
+          if (user_access('access user profiles')) {
+            $patron_link = l($transaction->username, 'user/'. $transaction->uid);
+            $temp_array[] = $patron_link;
+          }
           if (isset($duedate)) { 
             $temp_array[] = $duedate; 
           }
@@ -352,16 +364,75 @@
       return theme('table', $header, $rows);
     }
     else {
-      if ($is_patron) {
-        return "<p>This patron has not performed any actions.</p>";
+      return "<p>No actions have been performed on this item.</p>";
+    }
+  }
+  else {
+    return "<p>This item type is not part of the library.</p>";
+  }
+}
+
+/**
+ * Menu callback; show the transaction history of a single user.
+ */
+function library_history_user($patron) { 
+  $duedate_enabled = library_duedates_enabled($node->type);  
+
+  $header = array(t('Date'), t('Item'), t('Transaction'), t('Notes'));
+  if ($duedate_enabled) {
+    $header[] = t('Due Date');
+  }
+  $header[] = t('Actions');
+  $rows = array();
+
+  $transactions = library_get_transactions_by_user($patron);
+
+  if (!empty($transactions)) {
+    $last_item = '';
+    foreach ($transactions as $transaction) {
+      $detail_link = '';
+      $action_link = '';
+      $cur_item = $transaction->item_id;
+      $created = format_date($transaction->created, 'small');
+      if ($duedate_enabled && $cur_item <> $last_item && !empty($transaction->duedate)) {
+        $duedate = format_date($transaction->duedate, 'small');
+      }
+      elseif ($duedate_enabled) {
+        $duedate = '';
+      }
+      if (user_access('administer transactions', $user)) {
+        $detail_link = l('View Details', 'library-items/transaction/view/'. $transaction->tid);
+      }
+      if ($cur_item <> $last_item) {
+        $item = array('id' => $transaction->item_id, 'library_status' => $transaction->library_status, 'last_patron_uid' => $transaction->uid, 'in_circulation' => $transaction->in_circulation);
+        $links = library_get_action_links($item);
+        if (!empty($links)) {
+          $action_link = implode(" | ", $links);
+        }
+      } 
+      $temp_array = array($created, l($transaction->item_name, 'node/'. $transaction->nid), $transaction->action_name, $transaction->notes);
+      if (isset($duedate)) { 
+        $temp_array[] = $duedate; 
+      }
+      if (!empty($detail_link) && !empty($action_link)) {
+        $temp_array[] = $detail_link .' | '. $action_link;
+      }
+      elseif (!empty($action_link)) {
+        $temp_array[] = $action_link;
+      }
+      elseif (!empty($detail_link)) {
+        $temp_array[] = $detail_link;
       }
       else {
-        return "<p>No actions have been performed on this item.</p>";
+        $temp_array[] = '';
       }
+      $rows[] = $temp_array;
+      $last_item = $cur_item;
     }
+    return theme('table', $header, $rows);
   }
   else {
-    return "<p>This item type is not part of the library.</p>";
+    return "<p>This user has not performed any library actions.</p>";
   }
 }
 
@@ -395,7 +466,7 @@
         $patron_name = $record['patron']['patron_name'];
         $patron_email = $record['patron']['patron_email'];
         foreach ($record['items'] as $id => $values) {
-          $item = array('library_status' => LIBRARY_ITEM_UNAVAILABLE, 'id' => $id, 'last_patron_id' => $patron_id, 'in_circulation' => $values['in_circulation']);
+          $item = array('library_status' => LIBRARY_ITEM_UNAVAILABLE, 'id' => $id, 'last_patron_uid' => $patron_id, 'in_circulation' => $values['in_circulation']);
           $links = implode(" | ", library_get_action_links($item));
 
           $rows[] = array($values['item_name'], $patron_name, format_date($values['due_date'], 'small'), l('Item Details', 'node/'. $values['nid']) .' | '. $links);
Index: patron/patron.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/library/patron/patron.info,v
retrieving revision 1.3
diff -u -r1.3 patron.info
--- patron/patron.info	13 Aug 2008 23:20:16 -0000	1.3
+++ patron/patron.info	4 Nov 2010 23:43:49 -0000
@@ -1,6 +1,6 @@
 ; $Id: patron.info,v 1.3 2008/08/13 23:20:16 jastraat Exp $
 name 		= "Patron"
-description 	= "Create a patron content type for use with the library module.  This module must be enabled if you wish to use library."
+description 	= "DEPRECATED. Do not install."
 package 	= Library
 core 		= "6.x"
 
Index: patron/patron.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/library/patron/patron.install,v
retrieving revision 1.3
diff -u -r1.3 patron.install
--- patron/patron.install	24 May 2010 17:07:33 -0000	1.3
+++ patron/patron.install	4 Nov 2010 23:43:49 -0000
@@ -65,17 +65,6 @@
 }
 
 /**
- * Implementation of hook_install()
- */
-function patron_install() {
-  drupal_install_schema('patron');
-
-  // Notify of changes
-  drupal_set_message(t("Library patron module successfully installed."));
-
-}
-
-/**
  * Implementation of hook_uninstall().
  */
 function patron_uninstall() {
@@ -102,9 +91,3 @@
 
   drupal_set_message(t('Library patron module successfully uninstalled'));
 }
-
-function patron_update_1() {
-  $ret = array();
-  $ret[] = update_sql("UPDATE {library_patrons} SET patron_uid = NULL WHERE patron_uid = 0");
-  return $ret;
-}
Index: patron/patron.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/library/patron/patron.module,v
retrieving revision 1.8
diff -u -r1.8 patron.module
--- patron/patron.module	24 May 2010 17:07:33 -0000	1.8
+++ patron/patron.module	4 Nov 2010 23:43:49 -0000
@@ -1,619 +1,2 @@
 <?php
 // $Id: patron.module,v 1.8 2010/05/24 17:07:33 jastraat Exp $ 
-
-/**
- * Library patrons do not have barcodes.
- */
-define('PATRON_NO_BARCODES', 0);
-
-/**
- * Library Patrons have barcodes.
- */
-define('PATRON_BARCODES', 1);
-
-/**
- * Library Patrons are not users.
- */
-define('PATRON_NOT_USER', 0);
-
-/**
- * Library Patrons may be users.
- */
-define('PATRON_USER', 1);
-
-/**
- * Patron may use the library
- */
-define('PATRON_ENABLED', 0);
-
-/**
- * Patron may not currently use the library
- */
-define('PATRON_DISABLED', 1);
-
-/**
-* Valid permissions for this module
-* @return array An array of valid permissions for this module
-*/
-function patron_perm() {
-  return array(
-    'create patron content', 
-    'edit own patron content', 
-    'edit any patron content',
-    'delete patron content',
-    'view patron content',
-    'administer patrons');
-}
-
-/**
- * Implementation of hook_help()
- */
-function patron_help($path, $arg) {
-  switch ($path) {
-    case 'patrons/email':
-      if ($arg[2]) {
-        return t('<p>The form below will send an email to the patron specified. If no patron is specified, the email will be sent to all active patrons.</p>', array());
-      }
-      else {
-        return t('<p>The form below will send an email to all active patrons.</p>', array());
-      }
-  }
-}
-
-/**
- * Implementation of hook_node_info().
- */
-function patron_node_info() {
-  return array(
-    'patron' => array(
-      'name' => t('Library Patron'),
-      'module' => 'patron',
-      'description' => t('Library patrons are individuals with whom library items may be associated.'),
-      'has_title' => TRUE,
-      'title_label' => t('Complete Name'),
-      'has_body' => FALSE,
-    )
-  );
-}
-
-/**
- * Implemenation of hook_access().
- */
-function patron_access($op, $node, $account) {
-  if ($op == 'view') {
-    //Come back and change this to change patron_uid
-    if (user_access('view patron content', $account) || ((variable_get('patron_is_user', PATRON_NOT_USER) == PATRON_USER) && ($account->uid == $node->patron_uid))) {
-      return TRUE;
-    }
-    else {
-      return FALSE;
-    }
-  }
-  if ($op == 'create') {
-    return user_access('create patron content', $account);
-  }
-
-  if ($op == 'update') {
-    if (user_access('edit any patron content', $account) || (variable_get('patron_is_user', PATRON_NOT_USER) == PATRON_USER && user_access('edit own patron content', $account) && ($account->uid == $node->patron_uid))) {
-      return TRUE;
-    }
-  }
-  if ($op == 'delete') {
-    return user_access('delete patron content', $account);
-  }
-}
-
-/** 
- * Implementation of hook_db_rewrite_sql().
- */
-function patron_db_rewrite_sql($query, $primary_table, $primary_field, $args) {
-  if ($query == '' && $primary_table == 'n' && $primary_field = 'nid' && empty($args)) {
-    $excluded_types = array('patron');
-    if (!empty($excluded_types)) {
-      $where = " n.type NOT IN ('". join("','", $excluded_types) ."') ";
-      return array('where' => $where);
-    }
-  }
-}
-
-/**
- * Implemenation of hook_insert().
- */
-function patron_insert($node) {
-  if (empty($node->patron_uid)) {
-    db_query("INSERT INTO {library_patrons} (nid, name_last, name_first, email, patron_uid, barcode, disabled) VALUES (%d, '%s', '%s', '%s', NULL, '%s', %d)", $node->nid, $node->name_last, $node->name_first, $node->email, $node->barcode, $node->disabled);
-  }
-  else {
-    db_query("INSERT INTO {library_patrons} (nid, name_last, name_first, email, patron_uid, barcode, disabled) VALUES (%d, '%s', '%s', '%s', %d, '%s', %d)", $node->nid, $node->name_last, $node->name_first, $node->email, $node->patron_uid, $node->barcode, $node->disabled);
-  }
-}
-
-/**
- * Implemenation of hook_update().
- */
-function patron_update($node) {
-  if (empty($node->patron_uid)) {
-    db_query("UPDATE {library_patrons} SET name_last = '%s', name_first = '%s', email = '%s', patron_uid = NULL, barcode = '%s', disabled = %d WHERE nid = %d", $node->name_last, $node->name_first, $node->email, $node->barcode, $node->disabled, $node->nid); 
-  }
-  else {
-    db_query("UPDATE {library_patrons} SET name_last = '%s', name_first = '%s', email = '%s', patron_uid = %d, barcode = '%s', disabled = %d WHERE nid = %d", $node->name_last, $node->name_first, $node->email, $node->patron_uid, $node->barcode, $node->disabled, $node->nid); 
-  }
-}
-
-/**
- * Implemenation of hook_delete().
- */
-function patron_delete($node) {
-  if (module_exists('library')) {
-    db_query("DELETE FROM {library_transactions} WHERE patron_id = %d", $node->nid); 
-  }
-  db_query("DELETE FROM {library_patrons} WHERE nid = %d", $node->nid); 
-}
-
-/**
- * Implemenation of hook_nodeapi().
- */
-function patron_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
-  if ($node->type == 'patron') {
-    switch ($op) {
-      case 'view':
-        $node->title = $node->name_first .' '. $node->name_last;
-        if (user_access('view patron content')) {
-          $node->content['email'] = array(
-            '#value' => '<div class="field-patron-email">'. patron_email_link($node) .'</div>',
-            '#weight' => 0,
-          );
-        }
-        if ($node->disabled == PATRON_DISABLED) {
-          $node->content['disabled'] = array(
-            '#value' => '<div class="field-patron-disabled">Disabled</div>',
-            '#weight' => 2,
-          );
-        }
-        if (variable_get('patron_is_user', PATRON_NOT_USER) == PATRON_USER && !empty($node->patron_uid) && user_access('access user profiles')) {
-          $patron_user = user_load($node->patron_uid);
-          if ($patron_user) {
-            $node->content['patron_uid'] = array(
-              '#value' => '<div class="field-patron-user"><label>Drupal User: </label>'. l($patron_user->name, 'user/'. $patron_user->uid) .'</div>',
-              '#weight' => -3,
-            );
-          }
-        }
-        if (variable_get('patron_use_barcodes', PATRON_NO_BARCODES) == PATRON_BARCODES) {
-          $node->content['barcode'] = array(
-            '#value' => '<div class="field-patron-barcode"><label>Card Number: </label>'. $node->barcode .'</div>',
-            '#weight' => -1,
-          );
-        }
-        global $user;
-        watchdog('library', '%user viewed patron %name', array('%user' => $user->name, '%name' => $node->title));
-        break;
-
-      case 'presave':
-        if (!empty($node->email) && variable_get('patron_is_user', PATRON_NOT_USER) == PATRON_USER) {
-          $patron_uid = db_result(db_query_range("SELECT uid from {users} where mail= '%s'", $node->email, 0, 1));
-          if ($patron_uid) {
-            $node->patron_uid = $patron_uid;
-            $node->uid = $patron_uid;   
-          }
-          else {
-            $node->patron_uid = NULL;
-          }
-        } 
-        break;
-    }
-  }
-}
-
-/**
- * Implemenation of hook_load().
- */
-
-function patron_load($node) {
-  $additions = db_fetch_object(db_query("SELECT * FROM {library_patrons} WHERE nid = %d", $node->nid));
-  return $additions;
-}
-
-/**
- * Implementation of hook_form().
- */
-function patron_form(&$node) {
-  $type = node_get_types('type', $node);
-  $patrons_are_users = variable_get('patron_is_user', PATRON_NOT_USER) == PATRON_USER;
-  $patron_uid = NULL;
-  if ($patrons_are_users && !empty($node->email)) {
-    $exists = db_result(db_query_range("SELECT uid from {users} where mail= '%s'", $node->email, 0, 1));
-    if ($exists) {
-      $patron_uid = $exists;
-    }
-  }
-
-  // We need to define form elements for the node's title and body.
-  if ($type->has_title) {
-    $form['title'] = array(
-      '#type' => 'textfield',
-      '#title' => 'Patron Identifier (ID or Complete Name)',
-      '#required' => TRUE,
-      '#default_value' => $node->title,
-      '#description' => t('This must be unique.'),
-      '#weight' => -5
-    );
-  }
-  if ($type->has_body) {
-    $form['body_field'] = node_body_field($node, $type->body_label, $type->min_word_count);
-  }
-
-  $form['required_for_library'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Required Library Fields'),
-    '#collapsed' => FALSE,
-    '#weight' => -3
-  );
-  // Now we define the form elements specific to our node type.
-  $form['required_for_library']['name_first'] = array(
-    '#type' => 'textfield',
-    '#title' => t('First Name'),
-    '#default_value' => $node->name_first,
-    '#size' => 10,
-    '#maxlength' => 30,
-    '#weight' => -4,
-    '#required' => TRUE
-  );
-  $form['required_for_library']['name_last'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Last Name'),
-    '#default_value' => $node->name_last,
-    '#size' => 10,
-    '#maxlength' => 30,
-    '#weight' => -3,
-    '#required' => TRUE
-  );
-  $form['required_for_library']['email'] = array(
-    '#type' => 'textfield',
-    '#title' => t('E-mail'),
-    '#default_value' => $node->email,
-    '#size' => 20,
-    '#maxlength' => 30,
-    '#weight' => -1,
-    '#required' => TRUE,
-  );
-  if ($patrons_are_users) {
-    $form['required_for_library']['email']['#autocomplete_path'] = 'patrons/js/email';
-    if (!user_access('administer patrons') || !user_access('access user profiles')) {
-      $form['required_for_library']['email']['#access'] = FALSE;
-    }
-    $form['required_for_library']['email']['#description'] = t('If this email address matches an existing Drupal user, that user will be associated with this patron. Similar user emails will be suggested when you begin entering a value.');
-    $form['required_for_library']['patron_uid'] = array(
-      '#type' => 'value',
-      '#value' => $patron_uid,
-    );
-  }
-  if (variable_get('patron_use_barcodes', PATRON_NO_BARCODES) == PATRON_BARCODES) {
-    $form['required_for_library']['barcode'] = array(
-      '#type' => 'textfield',
-      '#size' => 30,
-      '#maxlength' => 60,
-      '#title' => t('Patron Card Number/Barcode'),
-      '#default_value' => $node->barcode,
-      '#weight' => 0,
-      '#required' => TRUE
-    );
-  }
-  $form['required_for_library']['disabled'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Disabled'),
-    '#default_value' => $node->disabled,
-    '#return_value' => PATRON_DISABLED,
-    '#description' => t('Disabled patrons will not appear in patron lists and may not use the library'),
-    '#weight' => 6,
-  );
-  return $form;
-}
-
-/**
- * Implementation of hook_validate().
- */
-function patron_validate(&$node) {
-  //Validate email
-  if (!empty($node->email)) {
-    if (!valid_email_address($node->email)) {
-      form_set_error('email', t('Invalid email address.'));
-    }
-    else {
-      $result = db_result(db_query_range("SELECT nid from {library_patrons} where email= '%s' and nid <> '%d'", $node->email, $node->nid, 0, 1));
-      if ($result) {
-        form_set_error('email', t("Duplicate email address. ". l('View existing entry with this email address.', 'node/'. $result)));
-      }
-    }
-  }
-  //Validate identifier
-  $dup_result = db_result(db_query_range("SELECT nid FROM {node} WHERE title= '%s' AND nid <> %d AND type='patron'", $node->title, $node->nid, 0, 1));
-  if ($dup_result) {
-    form_set_error('title', t("A Patron with that identifier already exists. ". l('View existing entry.', 'node/'. $dup_result)));
-  }
-  //Validate that barcode is unique
-  if (variable_get('patron_use_barcodes', PATRON_NO_BARCODES) == PATRON_BARCODES) {
-    if (!empty($node->barcode)) {
-      $node->barcode = check_plain($node->barcode);
-      $not_unique = db_result(db_query("SELECT COUNT(*) FROM {library_patrons} WHERE barcode = '%s' AND barcode <> '' AND nid <> %d", $node->barcode, $node->nid));
-      if ($result) {
-        form_set_error('barcode', t('The barcode %barcode already exists. Please enter a different barcode.', array('%barcode' => $node->barcode)));
-      }
-    }
-  }
-}
-
-/**
-* Retrieve a pipe delimited string of autocomplete suggestions for existing patron
-*/
-function patron_autocomplete($string) {
-  $matches = array();
-  $result = db_query_range("SELECT n.nid, lp.barcode, n.title FROM {node} n, {library_patrons} lp WHERE lp.nid = n.nid AND n.type = 'patron' AND lp.disabled = %d AND (LOWER(n.title) LIKE LOWER('%%%s%%') OR lp.barcode = '%s')", PATRON_ENABLED, check_plain($string), check_plain($string), 0, 10);
-  $barcodes = variable_get('patron_use_barcodes', PATRON_NO_BARCODES);
-  while ($patron = db_fetch_object($result)) {
-    if ($barcodes == PATRON_BARCODES && !empty($patron->barcode)) {
-      $matches[$patron->title .' [nid:'. $patron->nid .']'] = check_plain($patron->barcode) .' ('. check_plain($patron->title) .')';
-    }
-    else {
-      $matches[$patron->title .' [nid:'. $patron->nid .']'] = check_plain($patron->title);
-    }
-  }
-  print drupal_to_js($matches);
-  exit();
-}
-
-/**
-* Retrieve a pipe delimited string of autocomplete suggestions for existing patron
-*/
-function patron_email_autocomplete($string) {
-  $matches = array();
-  $result = db_query_range("SELECT mail from {users} where status = 1 AND LOWER(mail) LIKE LOWER('%s%%')", check_plain($string), 0, 10);
-  while ($patron = db_fetch_object($result)) {
-    $matches[$patron->mail] = check_plain($patron->mail);
-  }
-  print drupal_to_js($matches);
-  exit();
-}
-
-/**
- * Retrieve a list of patrons
- * @param $nid 
- *  If this is blank, only active patrons are returned.  If 'all', all are returned.  If a number, a specific patron is returned. 
- */
-function patron_get_patrons($nid = NULL) {
-  if (!$nid) {
-    $result = db_query("SELECT * FROM {node} n, {library_patrons} lp WHERE lp.nid = n.nid AND n.type = 'patron' AND lp.disabled = %d ORDER BY lp.name_last, lp.name_first", PATRON_ENABLED);
-  }
-  elseif (is_numeric($nid)) {
-    $result = db_query_range("SELECT * FROM {node} n, {library_patrons} lp WHERE lp.nid = n.nid AND n.type = 'patron' AND n.nid = %d ORDER BY lp.name_last, lp.name_first", $nid, 0, 1);
-  }
-  else {
-     $result = db_query("SELECT * FROM {node} n, {library_patrons} lp WHERE lp.nid = n.nid AND n.type = 'patron' ORDER BY lp.name_last, lp.name_first");
-  }
-  $patrons = array();
-  while ($patron = db_fetch_object($result)) {
-    $patrons[] = $patron;
-  }
-  return empty($patrons) ? FALSE : $patrons;
-}
-
-/**
- * Implementation of hook_menu()
- */
-function patron_menu() {
-  $items = array();
-  $items['patrons/autocomplete'] = array(
-    'title' => t('Patron Autocomplete'),
-    'page callback' => 'patron_autocomplete', 
-    'access arguments' => array('access content'), 
-    'type' => MENU_CALLBACK
-  );
-  $items['patrons'] = array(
-    'title' => 'Patrons',
-    'page callback' => 'patron_list_patrons',
-    'access arguments' => array('view patron content'),
-    'file' => 'patron.pages.inc',
-  );
-  $items['patrons/email'] = array(
-    'title' => 'Send Email',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('patron_email_form'),
-    'access arguments' => array('edit any patron content'),
-    'file' => 'patron.pages.inc',
-  );
-  $items['admin/settings/library/patrons'] = array(
-    'title' => 'Patron Settings',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('patron_admin_settings'),
-    'access arguments' => array('administer patrons'),
-  );
-  $items['patrons/js/email'] = array(
-    'page callback' => 'patron_email_autocomplete',
-    'type' => MENU_CALLBACK,
-    'access arguments' => array('access content'), 
-  );
-  return $items;
-}
-
-function patron_email_js() {
-  $email = $_POST['email'];
-  if ($email != '' && !is_null($email)) {
-    $exists = db_query_range("SELECT uid, name from {users} where mail= '%s'", $node->email, 0, 1);
-    if ($exists) {
-      while ($patron = db_fetch_object($exists)) {
-        // Build the new form.
-        $form_state = array('submitted' => FALSE);
-        $form_build_id = $_POST['form_build_id'];
-        
-        // We retreive the cached form, change the value, and resave.
-        $form = form_get_cache($form_build_id, $form_state);
-        form_set_value($form['required_for_library']['patron_uid'], $patron->uid, $form_state);
-        
-        $output = 'Matching Drupal user found. Username: '. $patron->name;
-        print drupal_json(array('data' => $output));
-      }
-    }
-  }
-}
-
-/**
- * Menu callback: Edit Patron Settings.
- */
-function patron_admin_settings() {
-  $form = array();
-  $form['patron_use_barcodes'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Use Library Cards (with Barcodes) for Library Patrons'),
-    '#default_value' => variable_get('patron_use_barcodes', 0),
-    '#return_value' => 1,
-    '#description' => t('This will allow you to use library cards.  However, you must have a unique barcode for every patron.'),
-  );
-  $form['user_settings'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('User Settings'),
-  );
-  $form['user_settings']['patron_is_user'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Associate Library Patrons with Drupal Users'),
-    '#default_value' => variable_get('patron_is_user', 0),
-    '#return_value' => 1,
-    '#description' => t('You must create the user account first, and the Drupal user and library patron must have the same email address.'),
-  );
-  /* Only allow if patrons do NOT have library cards!! */
-  if (variable_get('patron_use_barcodes', PATRON_NO_BARCODES) == PATRON_NO_BARCODES) {
-    $form['user_settings']['patron_autocreate'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Autocreate Library Patron on User Registration and Delete on User Deletion'),
-      '#default_value' => variable_get('patron_autocreate', 0),
-      '#return_value' => 1,
-      '#description' => t('You must associate library patrons with drupal users first.'),
-    );
-  }
-  return system_settings_form($form);
-}
-
-/**
- * Implementation of hook_mail()
- */
-function patron_mail($key, &$message, $params) {
-  $language = $message['language'];
-  switch ($key) {
-    case 'email_form':
-      $message['subject'] .= $params['subject'];
-      $message['body'][] = $params['message'];
-      break;
-  } 
-}
-
-function patron_email_link($patron) {
-  $output = '';
-  if ($patron->email) {
-    $output = l('E-mail', 'patrons/email/'. $patron->nid);
-  }
-  return $output;
-}
-
-/**
- * Implementation of hook_user().
- */
-function patron_user($op, &$edit, &$user, $category = NULL) {
-  if (variable_get('patron_is_user', PATRON_NOT_USER) == PATRON_USER) {
-    switch ($op) {
-      case 'load':
-        $user->patron = patron_load_by_uid($user->uid);
-        break;
-      case 'after_update':
-        //If the user email has changed, update the patron email to match
-        $node = patron_load_by_uid($user->uid);
-        if (!empty($node) && $node->email != $user->mail) {
-          $node->email = $user->mail;
-          node_save($node);
-        }
-        break;
-      case 'view':
-        $patron = patron_load_by_uid($user->uid);
-        $cur_user = $GLOBALS['user'];
-
-        if (variable_get('patron_is_user', PATRON_NOT_USER) == PATRON_USER && !empty($patron) && (node_access('view', 'patron') || $cur_user->uid == $user->uid)) {
-          $user->content['patron_name'] = array(
-            '#type' => 'user_profile_item',
-            '#title' => 'Patron Name',
-            '#value' => l($patron->name_first .' '. $patron->name_last, 'node/'. $patron->nid),
-            '#attributes' => array('class' => 'profile-patron'),
-          );
-        }
-        break;
-      case 'register':
-        if (variable_get('patron_autocreate', 0) == 1) {
-          return patron_register_form();
-        }
-        break;
-      case 'insert':
-        if (variable_get('patron_autocreate', 0) == 1 && isset($edit['name_last'])) {
-          return patron_create_patron($edit, $user);
-        }
-        break;
-      case 'delete':
-        //$patron = patron_load_by_uid($user->uid);
-        //if (variable_get('patron_autocreate', 0) == 1 && !empty($patron) && is_numeric($patron->nid)) {
-          //node_delete($patron->nid);
-        //}
-        break;
-    }
-  }
-}
-
-function patron_load_by_uid($uid) {
-  if (variable_get('patron_is_user', PATRON_NOT_USER) == PATRON_USER && is_numeric($uid)) {
-    $nid = db_result(db_query_range("SELECT nid FROM {library_patrons} WHERE patron_uid = %d", $uid, 0, 1));
-    if ($nid) {
-      $node = node_load($nid);
-      return $node;
-    }
-  }
-  return '';
-}
-
-function patron_register_form() {
-  $form = array();
-  $form['required_for_library'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Required Patron Fields'),
-    '#collapsed' => FALSE,
-    '#weight' => -3
-  );
-  $form['required_for_library']['name_first'] = array(
-    '#type' => 'textfield',
-    '#title' => t('First Name'),
-    '#default_value' => '',
-    '#size' => 10,
-    '#maxlength' => 30,
-    '#weight' => -4,
-    '#required' => TRUE
-  );
-  $form['required_for_library']['name_last'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Last Name'),
-    '#default_value' => '',
-    '#size' => 10,
-    '#maxlength' => 30,
-    '#weight' => -3,
-    '#required' => TRUE
-  );
-
-  return $form;
-}
-
-function patron_create_patron(&$edit, $user) {
-  $node = (object) array(
-    'type' => 'patron',
-    'title' => check_plain($edit['name_last']) .', '. check_plain($edit['name_first']),
-    'name' => $user->name,
-    'uid' => $user->uid,
-    'email' => $user->mail,
-    'name_last' => check_plain($edit['name_last']),
-    'name_first' => check_plain($edit['name_first']),
-    'patron_uid' => $user->uid,
-  );
-  node_save($node);
-}
\ No newline at end of file
Index: patron/patron.pages.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/library/patron/patron.pages.inc,v
retrieving revision 1.3
diff -u -r1.3 patron.pages.inc
--- patron/patron.pages.inc	23 Nov 2009 19:06:53 -0000	1.3
+++ patron/patron.pages.inc	4 Nov 2010 23:43:49 -0000
@@ -1,111 +1,2 @@
 <?php
-// $Id: patron.pages.inc,v 1.3 2009/11/23 19:06:53 jastraat Exp $
-
-/**
- * @file
- * Functions for generating page displays related to the patron module
- */
-
-
-function patron_list_patrons() {
-  $patrons = patron_get_patrons('all');
-  if ($patrons) {
-    $header = array(t('Name'), t('Status'));
-    $header[] = t('Actions');
-    $rows = array();
-    foreach ($patrons as $patron) {
-      if ($patron->disabled == PATRON_DISABLED) {
-        $patron->disabled = 'Disabled';
-      }
-      else {
-        $patron->disabled = 'Active';
-      }
-      $rows[] = array($patron->name_last .', '. $patron->name_first, $patron->disabled, l('View', 'node/'. $patron->nid) .' | '. patron_email_link($patron));
-    }
-    return theme('table', $header, $rows); 
-  }
-  else {
-    return "<p>No patrons found.</p>";
-  }
-}
-
-function patron_email_form(&$form_state) {
-  $form = array();
-
-  $patron_id = arg(2);
-  if ($patron_id) {
-    $patron = patron_get_patrons($patron_id);
-    $to = $patron[0]->email;
-    $name = $patron[0]->name_first .' '. $patron[0]->name_last;
-    if ($patron) {
-      $form['to'] = array(
-        '#type' => 'value',
-        '#value' => ($to ? $to : ''),
-        '#required' => FALSE,
-      );
-      $form['patron_name'] = array(
-        '#type' => 'item',
-        '#title' => t('To'),
-        '#value' => $name,
-        '#required' => FALSE,
-      );
-      $form['patron'] = array(
-        '#type' => 'value',
-        '#value' => $name,
-        '#required' => FALSE,
-      );
-    }
-  }
-
-  $form['subject'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Subject'),
-    '#maxlength' => 255,
-    '#required' => TRUE
-  );
-  $form['message'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Message'),
-    '#required' => TRUE,
-  );
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Send E-mail'),
-  );
-  
-  return $form;
-}
-
-function patron_email_form_validate($form, &$form_state) {
-  if ($form_state['values']['to'] && !valid_email_address($form_state['values']['to'])) {
-    form_set_error('to', t('Invalid patron email.'));
-  }
-}
-
-function patron_email_form_submit($form, &$form_state) {
-  $values = $form_state['values']; 
-  if ($values['to']) {
-    $to = $values['to'];
-    $recipients = $values['patron'];
-  }
-  else { 
-    $patrons = patron_get_patrons();
-
-    $to_array = array();
-    $recipient_array = array();
-    foreach ($patrons as $patron) {
-      $to_array[] = $patron->email;
-      $recipient_array[] = $patron->name_first .' '. $patron->name_last;
-    }
-    $to = implode(',', $to_array);
-    $recipients = implode(', ', $recipient_array);
-  }
-  if (drupal_mail('patron', 'email_form', $to, language_default(), $values)) {
-    watchdog('library', 'Sent email to %recipient', array('%recipient' => $recipients));
-    drupal_set_message(t('Your message has been sent to '. $recipients));
-  }
-  else {
-    watchdog('error', 'Unable to send email to %recipient', array('%recipient' => $recipients));
-  }
-  return;
-}
\ No newline at end of file
+// $Id: patron.pages.inc,v 1.3 2009/11/23 19:06:53 jastraat Exp $
\ No newline at end of file
