Index: feedback/feedback.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedback/feedback.admin.inc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 feedback.admin.inc
--- feedback/feedback.admin.inc 20 Feb 2010 22:30:53 -0000 1.1.2.2
+++ feedback/feedback.admin.inc 12 Apr 2010 18:52:03 -0000
@@ -7,116 +7,59 @@
*/
/**
- * Build a (sortable) form containing a checkbox for each feedback entry.
+ * Manage feedback module settings.
*/
-function feedback_admin_view_form() {
+function feedback_admin_settings_form() {
$form = array();
- $status_headings = array(
- 0 => t('Open feedback messages'),
- 1 => t('Processed feedback messages'),
- );
- $form['#feedback_header'] = array(
- array(),
- array('data' => t('Location'), 'field' => 'f.location_masked', 'sort' => 'asc'),
- array('data' => t('Date'), 'field' => 'f.timestamp'),
- array('data' => t('User'), 'field' => 'u.name'),
- t('Message'),
- );
- // Hack to prevent pager_query() from issuing PHP notices.
- if (!isset($_GET['page'])) {
- $_GET['page'] = '';
- }
- 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);
+ $implementations = array();
+ $options = array();
+ // Get available storage options.
+ $implementations = module_invoke_all('feedback_info');
- $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));
+ // Build options for the storage selector.
+ if (is_array($implementations['module'])) {
+ foreach ($implementations['module'] as $key => $module) {
+ // Check module implements the correct API version.
+ if ($implementations['api version'][$key] == 2) {
+ $options[$module] = $implementations['name'][$key];
+ }
+ else {
+ drupal_set_message(t('Warning: the %module module does not use the correct API for this version of Feedback.', array('%module' => $module)), 'error', FALSE);
+ }
}
}
- $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
- return $form;
-}
-
-/**
- * Output a sortable table containing all feedback entries.
- */
-function theme_feedback_admin_view_form($form) {
- $output = '';
- foreach (element_children($form['feedback-messages']) as $status) {
- $item = &$form['feedback-messages'][$status];
- if (!isset($item['#type']) || $item['#type'] != 'fieldset') {
- continue;
+ // Returned elements are not an array.
+ else {
+ // Check module implements the correct API version.
+ if ($implementations['api version'] == 2) {
+ $options[$implementations['module']] = $implementations['name'];
}
- // Build the table.
- $rows = array();
- foreach (element_children($item) as $element_entry) {
- $entry = &$item[$element_entry];
- // Render the data first.
- $rows[] = array(
- 0,
- drupal_render($entry['location']),
- drupal_render($entry['date']),
- drupal_render($entry['user']),
- drupal_render($entry['message']),
- );
- // Render the checkbox.
- $rows[count($rows) - 1][0] = drupal_render($entry);
- }
- if (empty($rows)) {
- $rows[] = array(array('data' => t('No feedback entries available.'), 'colspan' => 5));
- }
- // Inject the table.
- $item['messages'] = array(
- '#value' => theme('table', $form['#feedback_header'], $rows) . theme('pager', array(), 50, $status),
- '#weight' => -1,
- );
- // Render the fieldset.
- $output .= drupal_render($item);
}
- // Render internal FAPI and potential extra form elements.
- $output .= drupal_render($form);
- return $output;
+
+ // 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;
+ }
+ // Call the submit function for clearing the menu cache.
+ $form['#submit'][] = 'feedback_admin_settings_form_submit';
+ return system_settings_form($form);
}
/**
- * Form submit callback for admin view form.
+ * Form submit callback for admin settings 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);
- }
- }
- // Update status of entries in database.
- foreach ($update as $fid => $value) {
- db_query("UPDATE {feedback} SET status = %d WHERE fid = %d", $value, $fid);
- }
+function feedback_admin_settings_form_submit($form, &$form_state) {
+ // Re-build menus after saving settings.
+ module_invoke('menu', 'rebuild');
+ drupal_set_message(t('Menus have been re-built.'));
}
-
Index: feedback/feedback.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedback/feedback.module,v
retrieving revision 1.75.2.4
diff -u -r1.75.2.4 feedback.module
--- feedback/feedback.module 20 Feb 2010 23:59:32 -0000 1.75.2.4
+++ feedback/feedback.module 12 Apr 2010 18:52:04 -0000
@@ -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');
}
/**
@@ -28,12 +28,36 @@
* Implementation of hook_menu().
*/
function feedback_menu() {
- $items['admin/reports/feedback'] = array(
- 'title' => 'Feedback messages',
- 'description' => 'View feedback messages.',
+ // Check the module being used for storage.
+ $module = variable_get('feedback_storage_settings', 'feedback');
+ // Get module info.
+ $module_info = module_invoke($module, 'feedback_info');
+ // If there are arguments, use them.
+ if ($module_info['report callback'] && $module_info['report arguments']) {
+ $items['admin/reports/feedback'] = array(
+ 'title' => 'Feedback messages',
+ 'description' => 'View feedback messages.',
+ 'page callback' => $module_info['report callback'],
+ 'page arguments' => $module_info['report arguments'],
+ 'access arguments' => array('view feedback messages'),
+ );
+ }
+ // If there are no arguments, just call the callback function.
+ elseif ($module_info['report callback']) {
+ $items['admin/reports/feedback'] = array(
+ 'title' => 'Feedback messages',
+ 'description' => 'View feedback messages.',
+ 'page callback' => $module_info['report callback'],
+ 'access arguments' => array('view feedback messages'),
+ );
+ }
+
+ $items['admin/settings/feedback'] = array(
+ 'title' => 'Feedback settings',
+ 'description' => 'Administer feedback settings.',
'page callback' => 'drupal_get_form',
- 'page arguments' => array('feedback_admin_view_form'),
- 'access arguments' => array('view feedback messages'),
+ 'page arguments' => array('feedback_admin_settings_form'),
+ 'access arguments' => array('administer feedback'),
'file' => 'feedback.admin.inc',
);
return $items;
@@ -90,59 +114,15 @@
* Form builder function for a user feedback form.
*/
function feedback_form() {
- $form['#attributes']['class'] = 'feedback-form';
-
- // Store the path on which this form is displayed.
- $form['location'] = array('#type' => 'value', '#value' => $_GET['q']);
- // Allow the form to be submitted via AJAX.
- $form['ajax'] = array('#type' => 'hidden', '#default_value' => 0);
+ $form = array();
- $form['help'] = array(
- '#prefix' => '
',
- '#value' => t('If you experience a bug or would like to see an addition on the current page, feel free to leave us a message.'),
- '#suffix' => '
',
- );
- if (user_access('view feedback messages')) {
- if (arg(0) != 'node') {
- $feedbacks = feedback_load(array('status' => 0, 'location_masked' => feedback_mask_path($_GET['q'])));
- }
- else {
- $feedbacks = feedback_load(array('status' => 0, 'location' => $_GET['q']));
- }
- if ($feedbacks) {
- $rows = '';
- foreach ($feedbacks as $feedback) {
- $rows .= ''. theme('username', $feedback) .' '. format_date($feedback->timestamp, 'small') .':
';
- $rows .= ''. feedback_format_message($feedback) .'
';
- }
- $form['messages'] = array(
- '#prefix' => '',
- '#value' => $rows,
- '#suffix' => '
',
- );
- }
- }
- $form['message'] = array(
- '#type' => 'textarea',
- '#attributes' => array('class' => 'feedback-message'),
- '#cols' => 20,
- '#title' => t('Message'),
- '#required' => TRUE,
- '#wysiwyg' => FALSE,
- );
- $form['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Send'),
- '#id' => 'feedback-submit',
- '#prefix' => '',
- '#suffix' => '
',
- );
-
- return $form;
+ // Go fetch the feedback data entry fields.
+ return feedback_fields($form);
}
function feedback_form_submit($form, &$form_state) {
- feedback_add_entry($form_state['values']['message'], $form_state['values']['location']);
+ // Pass all the form values because we don't know what they will be.
+ feedback_add_entry($form_state['values']);
$message = t('Thanks for your feedback!');
if ($form_state['values']['ajax']) {
echo drupal_to_js(array('message' => $message));
@@ -154,6 +134,17 @@
}
/**
+ * Build the form fields for the feedback form.
+ */
+function feedback_fields($form) {
+ // Check the module being used for storage.
+ $module = variable_get('feedback_storage_settings', 'feedback');
+ // Pass building the feedback form to the appropriate module.
+ $form = module_invoke($module, 'feedback_form', $form);
+ return $form;
+}
+
+/**
* Format a feedback entry.
*
* @param $entry
@@ -181,6 +172,58 @@
* A keyed array of optional where clause conditions.
*/
function feedback_load($array) {
+ // Check the module being used for storage.
+ $module = variable_get('feedback_storage_settings', 'feedback');
+ // Pass the act of loading feedback to the appropriate module.
+ return module_invoke($module, 'feedback_load', $array);
+}
+
+/**
+ * '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
+ * replaced.
+ *
+ * @param $path
+ * An internal Drupal path, f.e. 'user/123/edit'.
+ * @return
+ * A 'masked' path, for above example 'user/%/edit'.
+ */
+function feedback_mask_path($path) {
+ return preg_replace('@/\d+@', '/%', $path);
+}
+
+/**
+ * Store a new feedback entry in the database.
+ *
+ * @param string $form_values
+ * The posted form values from feedback_form.
+ * In default 'basic storage' mode the main values are:
+ * $form_values['message']
+ * $form_values['location']
+ */
+function feedback_add_entry($form_values) {
+ 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.
+ module_invoke($module, 'feedback_save', $form_values, $user);
+}
+
+/**
+ * Implementation of hook_feedback_save().
+ */
+function feedback_feedback_save($form_values, $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($form_values['message']), $form_values['location'], feedback_mask_path($form_values['location']), url($form_values['location'], array('absolute' => TRUE)), time(), $_SERVER['HTTP_USER_AGENT']);
+}
+
+/**
+ * Implementation of hook_feedback_load().
+ */
+function feedback_feedback_load($array) {
+ // Was the feedback_load() function.
+ // Load feedback for use in the feedback form.
$where = $args = array();
if (!empty($array)) {
foreach ($array as $column => $value) {
@@ -201,32 +244,73 @@
}
/**
- * '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
- * replaced.
- *
- * @param $path
- * An internal Drupal path, f.e. 'user/123/edit'.
- * @return
- * A 'masked' path, for above example 'user/%/edit'.
+ * Implementation of hook_feedback_form().
*/
-function feedback_mask_path($path) {
- return preg_replace('@/\d+@', '/%', $path);
+function feedback_feedback_form($form) {
+ // Build the feedback form fields.
+ $form['#attributes']['class'] = 'feedback-form';
+
+ // Store the path on which this form is displayed.
+ $form['location'] = array('#type' => 'value', '#value' => $_GET['q']);
+ // Allow the form to be submitted via AJAX.
+ $form['ajax'] = array('#type' => 'hidden', '#default_value' => 0);
+
+ $form['help'] = array(
+ '#prefix' => '',
+ '#value' => t('If you experience a bug or would like to see an addition on the current page, feel free to leave us a message.'),
+ '#suffix' => '
',
+ );
+ if (user_access('view feedback messages')) {
+ if (arg(0) != 'node') {
+ $feedbacks = feedback_load(array('status' => 0, 'location_masked' => feedback_mask_path($_GET['q'])));
+ }
+ else {
+ $feedbacks = feedback_load(array('status' => 0, 'location' => $_GET['q']));
+ }
+ if ($feedbacks) {
+ $rows = '';
+ foreach ($feedbacks as $feedback) {
+ $rows .= ''. theme('username', $feedback) .' '. format_date($feedback->timestamp, 'small') .':
';
+ $rows .= ''. feedback_format_message($feedback) .'
';
+ }
+ $form['messages'] = array(
+ '#prefix' => '',
+ '#value' => $rows,
+ '#suffix' => '
',
+ );
+ }
+ }
+
+ // The actual message field.
+ $form['message'] = array(
+ '#type' => 'textarea',
+ '#attributes' => array('class' => 'feedback-message'),
+ '#title' => t('Message'),
+ '#required' => TRUE,
+ '#wysiwyg' => FALSE,
+ );
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Send'),
+ '#id' => 'feedback-submit',
+ '#prefix' => '',
+ '#suffix' => '
',
+ );
+ return $form;
}
/**
- * 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.
+ * Implementation of hook_feedback_info().
*/
-function feedback_add_entry($message, $location) {
- global $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']);
+function feedback_feedback_info() {
+ // Return information required for Feedback settings.
+ return array(
+ 'name' => 'basic storage',
+ 'module' => 'feedback',
+ 'api version' => 2,
+ 'report callback' => 'drupal_get_form',
+ 'report arguments' => array('feedback_admin_view_form'),
+ );
}
/**
@@ -237,3 +321,121 @@
db_query('UPDATE {feedback} SET uid = 0 WHERE uid = %d', $account->uid);
}
}
+
+/**
+ * Build a (sortable) form containing a checkbox for each feedback entry.
+ */
+function feedback_admin_view_form() {
+ $form = array();
+ $status_headings = array(
+ 0 => t('Open feedback messages'),
+ 1 => t('Processed feedback messages'),
+ );
+ $form['#feedback_header'] = array(
+ array(),
+ array('data' => t('Location'), 'field' => 'f.location_masked', 'sort' => 'asc'),
+ array('data' => t('Date'), 'field' => 'f.timestamp'),
+ array('data' => t('User'), 'field' => 'u.name'),
+ t('Message'),
+ );
+ // Hack to prevent pager_query() from issuing PHP notices.
+ if (!isset($_GET['page'])) {
+ $_GET['page'] = '';
+ }
+ if (count(explode(',', $_GET['page'])) < 2) {
+ $_GET['page'] .= ',0';
+ }
+ $tablesort = tablesort_sql($form['#feedback_header']);
+
+ // Fetch the actual messages to display.
+ $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 . $tablesort, 50, $status, $count_query, $status);
+
+ $messages[$status] = array(
+ '#type' => 'fieldset',
+ '#title' => $status_headings[$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));
+ }
+ }
+ $form['feedback-messages'] = $messages;
+
+ $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
+ return $form;
+}
+
+/**
+ * Output a sortable table containing all feedback entries.
+ */
+function theme_feedback_admin_view_form($form) {
+ $output = '';
+ foreach (element_children($form['feedback-messages']) as $status) {
+ $item = &$form['feedback-messages'][$status];
+ if (!isset($item['#type']) || $item['#type'] != 'fieldset') {
+ continue;
+ }
+ // Build the table.
+ $rows = array();
+ foreach (element_children($item) as $element_entry) {
+ $entry = &$item[$element_entry];
+ // Render the data first.
+ $rows[] = array(
+ 0,
+ drupal_render($entry['location']),
+ drupal_render($entry['date']),
+ drupal_render($entry['user']),
+ drupal_render($entry['message']),
+ );
+ // Render the checkbox.
+ $rows[count($rows) - 1][0] = drupal_render($entry);
+ }
+ if (empty($rows)) {
+ $rows[] = array(array('data' => t('No feedback entries available.'), 'colspan' => 5));
+ }
+ // Inject the table.
+ $item['messages'] = array(
+ '#value' => theme('table', $form['#feedback_header'], $rows) . theme('pager', array(), 50, $status),
+ '#weight' => -1,
+ );
+ // Render the fieldset.
+ $output .= drupal_render($item);
+ }
+ // Render internal FAPI and potential extra form elements.
+ $output .= drupal_render($form);
+ return $output;
+}
+
+/**
+ * Form submit callback for 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);
+ }
+ }
+ // Update status of entries in database.
+ foreach ($update as $fid => $value) {
+ db_query("UPDATE {feedback} SET status = %d WHERE fid = %d", $value, $fid);
+ }
+}