Index: feedback.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedback/feedback.admin.inc,v
retrieving revision 1.3
diff -u -p -r1.3 feedback.admin.inc
--- feedback.admin.inc	12 Nov 2010 01:26:01 -0000	1.3
+++ feedback.admin.inc	12 Jan 2011 20:15:37 -0000
@@ -33,14 +33,12 @@ function feedback_admin_view_form($form,
   $query = db_select('feedback', 'f')->extend('PagerDefault')->extend('TableSort');
   $query->join('users', 'u', 'f.uid = u.uid');
   $query->fields('f')
-    ->fields('u', array('name'))
     ->limit(50);
   foreach (array(0, 1) as $status) {
     $status_query = clone $query;
-    $result = $status_query->element($status)
+    $fids = $status_query->element($status)
       ->condition('f.status', $status)
-      ->execute()->fetchAllAssoc('fid');
-
+      ->execute()->fetchCol();
     $form['feedback-messages'][$status] = array(
       '#type' => 'fieldset',
       '#title' => $status_headings[$status],
@@ -48,16 +46,19 @@ function feedback_admin_view_form($form,
       '#collapsed' => $status,
       '#attributes' => array('class' => array('feedback-messages')),
     );
-    foreach ($result as $fid => $entry) {
-      $form['feedback-messages'][$status][$fid] = array(
-        '#type' => 'checkbox',
-        '#return_value' => 1,
-        '#default_value' => FALSE,
-      );
-      $form['feedback-messages'][$status][$fid]['location'] = array('#markup' => l(truncate_utf8($entry->location, 32, FALSE, TRUE), $entry->url));
-      $form['feedback-messages'][$status][$fid]['date'] = array('#markup' => format_date($entry->timestamp, 'small'));
-      $form['feedback-messages'][$status][$fid]['user'] = array('#markup' => format_username($entry));
-      $form['feedback-messages'][$status][$fid]['message'] = array('#markup' => feedback_format_message($entry));
+    if (!empty($fids)) {
+      $entries = feedback_load_multiple($fids);
+      foreach ($entries as $fid => $entry) {
+        $form['feedback-messages'][$status][$fid] = array(
+          '#type' => 'checkbox',
+          '#return_value' => 1,
+          '#default_value' => FALSE,
+        );
+        $form['feedback-messages'][$status][$fid]['location'] = array('#markup' => l(truncate_utf8($entry->location, 32, FALSE, TRUE), $entry->url));
+        $form['feedback-messages'][$status][$fid]['date'] = array('#markup' => format_date($entry->timestamp, 'small'));
+        $form['feedback-messages'][$status][$fid]['user'] = array('#markup' => format_username($entry));
+        $form['feedback-messages'][$status][$fid]['message'] = array('#markup' => feedback_format_message($entry));
+      }
     }
   }
   $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
@@ -113,21 +114,15 @@ function theme_feedback_admin_view_form(
 function feedback_admin_view_form_submit($form, &$form_state) {
   $update = array();
   // Determine feedback entries to update.
-  foreach ($form_state['values']['feedback-messages'] as $status => $entries) {
-    $entries = array_filter($entries);
-    foreach ($entries as $fid => $value) {
-      // Lame for now. :(
-      $update[$fid] = ($status == 0 ? 1 : 0);
+  foreach ($form_state['values']['feedback-messages'] as $status => $values) {
+    $values = array_filter($values);
+    if (!empty($values)) {
+      $entries = feedback_load_multiple(array_keys($values));
+      foreach ($entries as $fid => $entry) {
+        $entry->status = ($status == 0 ? 1 : 0);
+        feedback_save($entry);
+      }
     }
   }
-  // Update status of entries in database.
-  foreach ($update as $fid => $value) {
-    db_update('feedback')
-      ->fields(array(
-        'status' => $value,
-      ))
-      ->condition('fid', $fid)
-      ->execute();
-  }
 }
 
Index: feedback.api.php
===================================================================
RCS file: feedback.api.php
diff -N feedback.api.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ feedback.api.php	12 Jan 2011 20:15:37 -0000
@@ -0,0 +1,75 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Hooks provided by the Feedback module.
+ */
+
+/**
+ * @addtogroup hooks
+ * @{
+ */
+
+/**
+ * Act on an array of feedback entry objects when loaded from the database.
+ *
+ * @param $entries
+ *   An array of feedback entry objects, indexed by fid.
+ */
+function hook_feedback_load($entries) {
+  $result = db_query('SELECT * FROM {my_table} WHERE fid IN (:fids)', array(':fids' => array_keys($entries)));
+  foreach ($result as $record) {
+    $entries[$record->fid]->foo = $result->foo;
+  }
+}
+
+/**
+ * Respond to creation of a new feedback entry.
+ *
+ * @param $entry
+ *   The feedback entry object.
+ *
+ * @see hook_feedback_update()
+ */
+function hook_feedback_insert($entry) {
+  db_insert('mytable')
+    ->fields(array(
+      'fid' => $entry->fid,
+      'extra' => $entry->extra,
+    ))
+    ->execute();
+}
+
+/**
+ * Respond to updates to a feedback entry.
+ *
+ * @param $entry
+ *   The feedback entry object.
+ *
+ * @see hook_feedback_insert()
+ */
+function hook_feedback_update($entry) {
+  db_update('mytable')
+    ->fields(array('extra' => $entry->extra))
+    ->condition('fid', $entry->fid)
+    ->execute();
+}
+
+/**
+ * Respond to deletion of a feedback entry.
+ *
+ * @param $entry
+ *   The feedback entry object.
+ *
+ * @see feedback_delete_multiple()
+ */
+function hook_feedback_delete($entry) {
+  db_delete('mytable')
+    ->condition('fid', $entry->fid)
+    ->execute();
+}
+
+/**
+ * @} End of "addtogroup hooks".
+ */
Index: feedback.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedback/feedback.module,v
retrieving revision 1.80
diff -u -p -r1.80 feedback.module
--- feedback.module	12 Nov 2010 01:26:01 -0000	1.80
+++ feedback.module	12 Jan 2011 20:15:37 -0000
@@ -126,10 +126,10 @@ function feedback_form($form, &$form_sta
   );
   if (user_access('view feedback messages')) {
     if (arg(0) != 'node') {
-      $feedbacks = feedback_load(array('f.status' => 0, 'f.location_masked' => feedback_mask_path($_GET['q'])));
+      $feedbacks = feedback_load_multiple(array(), array('f.status' => 0, 'f.location_masked' => feedback_mask_path($_GET['q'])));
     }
     else {
-      $feedbacks = feedback_load(array('f.status' => 0, 'f.location' => $_GET['q']));
+      $feedbacks = feedback_load_multiple(array(), array('f.status' => 0, 'f.location' => $_GET['q']));
     }
     if ($feedbacks) {
       $rows = '';
@@ -164,7 +164,10 @@ function feedback_form($form, &$form_sta
 }
 
 function feedback_form_submit($form, &$form_state) {
-  feedback_add_entry($form_state['values']['message'], $form_state['values']['location']);
+  $entry = new stdClass();
+  $entry->message = $form_state['values']['message'];
+  $entry->location = $form_state['values']['location'];
+  feedback_save($entry);
   $message = t('Thanks for your feedback!');
   if ($form_state['values']['ajax']) {
     drupal_json_output(array('message' => $message));
@@ -197,26 +200,111 @@ function feedback_format_message($entry)
 }
 
 /**
- * Load feedback entries from the database.
+ * Loads feedback entries from the database.
  *
+ * @param $fids
+ *   An array of feedback entry IDs.
  * @param $conditions
- *   A keyed array of optional query conditions.
+ *   An associative array of conditions on the {feedback} table, where the keys
+ *   are the database fields and the values are the values those fields 
+ *   must have.
+ *
+ * @return
+ *   An array of feedback entry objects indexed by fid.
  */
-function feedback_load($conditions) {
+function feedback_load_multiple($fids = array(), $conditions = array()) {
   $query = db_select('feedback', 'f')->fields('f');
   $query->join('users', 'u', 'f.uid = u.uid');
   $query->fields('u', array('name'));
 
+  if (!empty($fids)) {
+    $query->condition('fid', $fids, 'IN');
+  }
   if (!empty($conditions)) {
     foreach ($conditions as $key => $value) {
       $query->condition($key, $value);
     }
   }
   $entries = $query->execute()->fetchAllAssoc('fid');
+  module_invoke_all('feedback_load', $entries);
   return $entries;
 }
 
 /**
+ * Loads a feedback entry object.
+ *
+ * @param $fid
+ *   Integer specifying the feedback ID to load.
+ *
+ * @return
+ *   A loaded feedback entry object upon successful load, or FALSE if the entry
+ *   cannot be loaded.
+ *
+ * @see feedback_load_multiple()
+ */
+function feedback_load($fid) {
+  $entries = feedback_load_multiple(array($fid));
+  return (isset($entries[$fid]) ? $entries[$fid] : FALSE);
+}
+
+/**
+ * Saves changes to a feedback entry or adds a new feedback entry.
+ *
+ * @param $entry
+ *   The feedback entry object to modify or add. If $entry->fid is omitted, a
+ *   new entry will be added.
+ *
+ * @see hook_feedback_insert()
+ * @see hook_feedback_update()
+ */
+function feedback_save($entry) {
+  global $user;
+
+  if (empty($entry->fid)) {
+    $entry->uid = isset($entry->uid) ? $entry->uid : $user->uid;
+    $entry->message = trim($entry->message);
+    $entry->location_masked = isset($entry->location_masked) ? $entry->location_masked : feedback_mask_path($entry->location);
+    $entry->url = isset($entry->url) ? $entry->url : url($entry->location, array('absolute' => TRUE));
+    $entry->timestamp = isset($entry->timestamp) ? $entry->timestamp : REQUEST_TIME;
+    $entry->useragent = isset($entry->useragent) ? $entry->useragent : $_SERVER['HTTP_USER_AGENT'];
+    drupal_write_record('feedback', $entry);
+    module_invoke_all('feedback_insert', $entry);
+  }
+  else {
+    drupal_write_record('feedback', $entry, 'fid');
+    module_invoke_all('feedback_update', $entry);
+  }
+}
+
+/**
+ * Deletes multiple feedback entries.
+ *
+ * @param $fids
+ *   An array of feedback entry IDs.
+ */
+function feedback_delete_multiple($fids) {
+  if (!empty($fids)) {
+    $entries = feedback_load_multiple($fids);
+    foreach ($entries as $fid => $entry) {
+      module_invoke_all('feedback_delete', $entry);
+    }
+    db_delete('feedback')
+      ->condition('fid', $fids, 'IN')
+      ->execute();
+  }
+}
+
+/**
+ * Deletes a feedback entry.
+ *
+ * @param $fid
+ *   A feedback entry ID.
+ */
+function feedback_delete() {
+  feedback_delete_multiple(array($fid));
+}
+
+/**
  * 'Mask' a path, i.e. replace all numeric arguments in a path with '%' placeholders.
  *
  * Please note that only numeric arguments with a preceding slash will be
@@ -232,31 +320,7 @@ function feedback_mask_path($path) {
 }
 
 /**
- * Store a new feedback entry in the database.
- *
- * @param string $message
- *   A feedback message text entered by an user.
- * @param string $location
- *   The path on which the feedback message was entered.
- */
-function feedback_add_entry($message, $location) {
-  global $user;
-
-  return db_insert('feedback')
-    ->fields(array(
-      'uid' => $user->uid,
-      'message' => trim($message),
-      'location' => $location,
-      'location_masked' => feedback_mask_path($location),
-      'url' => url($location, array('absolute' => TRUE)),
-      'timestamp' => REQUEST_TIME,
-      'useragent' => $_SERVER['HTTP_USER_AGENT'],
-    ))
-    ->execute();
-}
-
-/**
- * Implementation of hook_user_cancel().
+ * Implements hook_user_cancel().
  */
 function feedback_user_cancel($edit, $account, $method) {
   switch ($method) {
@@ -266,12 +330,14 @@ function feedback_user_cancel($edit, $ac
         ->condition('uid', $account->uid)
         ->execute();
       break;
-
-    case 'user_cancel_delete':
-      db_delete('feedback')
-        ->condition('uid', $account->uid)
-        ->execute();
-      break;
   }
 }
 
+/**
+ * Implements hook_user_delete().
+ */
+function feedback_user_delete($account) {
+  $fids = db_query('SELECT fid FROM {feedback} WHERE uid = :uid', array(':uid' => $account->uid))->fetchCol();
+  feedback_delete_multiple($fids);
+}
+
