Index: feedback.admin.inc
===================================================================
--- feedback.admin.inc	(revision 35)
+++ feedback.admin.inc	(working copy)
@@ -29,33 +29,10 @@
   if (count(explode(',', $_GET['page'])) < 2) {
     $_GET['page'] .= ',0';
   }
-
-  $form['feedback-messages'] = array('#tree' => TRUE);
-  foreach (array(0, 1) as $status) {
-    $sql = "SELECT f.*, u.name FROM {feedback} f INNER JOIN {users} u ON f.uid = u.uid WHERE f.status = %d";
-    $count_query = "SELECT COUNT(fid) FROM {feedback} WHERE status = %d";
-    $tablesort = tablesort_sql($form['#feedback_header']);
-    $result = pager_query($sql . $tablesort, 50, $status, $count_query, $status);
-
-    $form['feedback-messages'][$status] = array(
-      '#type' => 'fieldset',
-      '#title' => $status_headings[$status],
-      '#collapsible' => TRUE,
-      '#collapsed' => $status,
-      '#attributes' => array('class' => 'feedback-messages'),
-    );
-    while ($entry = db_fetch_object($result)) {
-      $form['feedback-messages'][$status][$entry->fid] = array(
-        '#type' => 'checkbox',
-        '#return_value' => 1,
-        '#default_value' => FALSE,
-      );
-      $form['feedback-messages'][$status][$entry->fid]['location'] = array('#value' => l(truncate_utf8($entry->location, 32, FALSE, TRUE), $entry->url));
-      $form['feedback-messages'][$status][$entry->fid]['date'] = array('#value' => format_date($entry->timestamp, 'small'));
-      $form['feedback-messages'][$status][$entry->fid]['user'] = array('#value' => theme('username', $entry));
-      $form['feedback-messages'][$status][$entry->fid]['message'] = array('#value' => feedback_format_message($entry));
-    }
-  }
+  $tablesort = tablesort_sql($form['#feedback_header']);
+  // Fetch the actual messages to display.
+  $form['feedback-messages'] = feedback_admin_view_feedback($tablesort, $status_headings);
+  
   $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
   return $form;
 }
@@ -120,3 +97,51 @@
   }
 }
 
+/**
+ * Manage feedback module settings.
+ */
+function feedback_admin_settings_form() {
+  $form = array();
+  
+  $op = 'type';
+  $implementations = array();
+  $options = array();
+  
+  // Invoke the hook_feedback_storage 'type' op to get available storage options.
+  $implementations = module_invoke_all('feedback_storage', $op);
+  // Build options for the storage selector.
+  foreach ($implementations['module'] as $key => $module) {
+    $options[$module] = $implementations['name'][$key];
+  }
+  
+  // Build the storage type selector.
+  $form['feedback_storage_settings'] = array(
+    '#title' => t('Storage settings'),
+    '#description' => t('Select where the Feedback module should save data.'),
+    '#type' => 'select',
+    // Disable by default, enable later if there's more than one option.
+    '#disabled' => TRUE,
+    '#options' => $options,
+    // Value is the module name to be used for storage.
+    '#default_value' => variable_get('feedback_storage_settings', 'feedback'),
+  );
+  
+  if (count($options) > 1) {
+    $form['feedback_storage_settings']['#disabled'] = FALSE;
+  }
+  
+  return system_settings_form($form);
+}
+
+/**
+ * Build the entries on the Feedback messages page.
+ */
+function feedback_admin_view_feedback($tablesort, $status_headings) {
+  
+  // Check the module being used for storage.
+  $module = variable_get('feedback_storage_settings', 'feedback');
+  // Pass the act of fetching the entries off to the appropriate module.
+  $op = 'view';
+  return module_invoke($module, 'feedback_storage', $op, $tablesort, $status_headings);
+  
+}
Index: feedback.module
===================================================================
--- feedback.module	(revision 35)
+++ feedback.module	(working copy)
@@ -10,7 +10,7 @@
  * Implementation of hook_perm().
  */
 function feedback_perm() {
-  return array('access feedback form', 'view feedback messages');
+  return array('access feedback form', 'view feedback messages', 'administer feedback');
 }
 
 /**
@@ -25,6 +25,30 @@
 }
 
 /**
+ * Implementation of hook_hook_info().
+ */
+function feedback_hook_info() {
+  return array(
+    'feedback' => array(
+      'feedback_storage' => array(
+        'insert' => array(
+          'runs when' => t('Before saving a new feedback entry'),
+        ),
+        'load' => array(
+          'runs when' => t('Before feedback is loaded in context'),
+        ),
+        'view' => array(
+          'runs when' => t('Before feedback is viewed on the admin reports page'),
+        ),
+        'type' => array(
+          'runs when' => t('When the admin settings form is built'),
+        ),
+      ),
+    ),
+  );
+}
+
+/**
  * Implementation of hook_menu().
  */
 function feedback_menu() {
@@ -36,6 +60,14 @@
     'access arguments' => array('view feedback messages'),
     'file' => 'feedback.admin.inc',
   );
+  $items['admin/settings/feedback'] = array(
+    'title' => 'Feedback settings',
+    'description' => 'Administer feedback settings.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('feedback_admin_settings_form'),
+    'access arguments' => array('administer feedback'),
+    'file' => 'feedback.admin.inc',
+  );
   return $items;
 }
 
@@ -180,23 +212,12 @@
  *   A keyed array of optional where clause conditions.
  */
 function feedback_load($array) {
-  $where = $args = array();
-  if (!empty($array)) {
-    foreach ($array as $column => $value) {
-      $where[] = 'f.'. $column .' = '. (is_numeric($value) ? '%d' : "'%s'");
-      $args[] = $value;
-    }
-  }
-  $sql = "SELECT f.*, u.name FROM {feedback} f INNER JOIN {users} u ON f.uid = u.uid";
-  if (!empty($where)) {
-    $sql .= ' WHERE '. implode(' AND ', $where);
-  }
-  $result = db_query($sql, $args);
-  $entries = array();
-  while ($entry = db_fetch_object($result)) {
-    $entries[$entry->fid] = $entry;
-  }
-  return $entries;
+  
+  // Check the module being used for storage.
+  $module = variable_get('feedback_storage_settings', 'feedback');
+  // Pass the act of loading off to the appropriate module.
+  $op = 'load';
+  return module_invoke($module, 'feedback_storage', $op, $array);
 }
 
 /**
@@ -224,8 +245,89 @@
  */
 function feedback_add_entry($message, $location) {
   global $user;
+  
+  // Check the module being used for storage.
+  $module = variable_get('feedback_storage_settings', 'feedback');
+  // Pass the act of storage off to the appropriate module.
+  $op = 'insert';
+  module_invoke($module, 'feedback_storage', $op, $message, $location, $user);
+}
 
-  db_query("INSERT INTO {feedback} (uid, message, location, location_masked, url, timestamp, useragent) VALUES (%d, '%s', '%s', '%s', '%s', %d, '%s')", $user->uid, trim($message), $location, feedback_mask_path($location), url($location, array('absolute' => TRUE)), time(), $_SERVER['HTTP_USER_AGENT']);
+/**
+ * Implementation of hook_feedback_storage().
+ */
+function feedback_feedback_storage($op, $a2 = NULL, $a3 = NULL, $a4 = NULL) {
+  
+  switch ($op) {
+    case 'insert':
+      // Store a feedback entry.
+      db_query("INSERT INTO {feedback} (uid, message, location, location_masked, url, timestamp, useragent) VALUES (%d, '%s', '%s', '%s', '%s', %d, '%s')", $a4->uid, trim($a2), $a3, feedback_mask_path($a3), url($a3, array('absolute' => TRUE)), time(), $_SERVER['HTTP_USER_AGENT']);
+    break;
+    
+    case 'load':
+      // Was the feedback_load() function.
+      // Load feedback for use in the feedback form.
+      $where = $args = array();
+      if (!empty($a2)) {
+        foreach ($a2 as $column => $value) {
+          $where[] = 'f.'. $column .' = '. (is_numeric($value) ? '%d' : "'%s'");
+          $args[] = $value;
+        }
+      }
+      $sql = "SELECT f.*, u.name FROM {feedback} f INNER JOIN {users} u ON f.uid = u.uid";
+      if (!empty($where)) {
+        $sql .= ' WHERE '. implode(' AND ', $where);
+      }
+      $result = db_query($sql, $args);
+      $entries = array();
+      while ($entry = db_fetch_object($result)) {
+        $entries[$entry->fid] = $entry;
+      }
+      return $entries;
+    break;
+    
+    case 'view':
+      // Was in feedback_admin_view_form().
+      // Load feedback for use on the Feedback messages page in admin.
+      $messages = array('#tree' => TRUE);
+      
+      foreach (array(0, 1) as $status) {
+        $sql = "SELECT f.*, u.name FROM {feedback} f INNER JOIN {users} u ON f.uid = u.uid WHERE f.status = %d";
+        $count_query = "SELECT COUNT(fid) FROM {feedback} WHERE status = %d";
+        $result = pager_query($sql . $a2, 50, $status, $count_query, $status);
+
+        $messages[$status] = array(
+          '#type' => 'fieldset',
+          '#title' => $a3[$status],
+          '#collapsible' => TRUE,
+          '#collapsed' => $status,
+          '#attributes' => array('class' => 'feedback-messages'),
+        );
+        while ($entry = db_fetch_object($result)) {
+          $messages[$status][$entry->fid] = array(
+            '#type' => 'checkbox',
+            '#return_value' => 1,
+            '#default_value' => FALSE,
+          );
+          $messages[$status][$entry->fid]['location'] = array('#value' => l(truncate_utf8($entry->location, 32, FALSE, TRUE), $entry->url));
+          $messages[$status][$entry->fid]['date'] = array('#value' => format_date($entry->timestamp, 'small'));
+          $messages[$status][$entry->fid]['user'] = array('#value' => theme('username', $entry));
+          $messages[$status][$entry->fid]['message'] = array('#value' => feedback_format_message($entry));
+        }
+      }
+      return $messages;
+      
+    break;
+    
+    case 'type':
+      // Return storage type name and module name for Feedback settings.
+      return array(
+        'name' => 'basic storage',
+        'module' => 'feedback',
+      );
+    break;
+  }
+  
 }
 
 /**

