feedback.module in Feedback 5
Same filename and directory in other branches
Enables a site-wide feedback page.
File
feedback.moduleView source
<?php
define('FEEDBACK_MAX_NAME', 64);
define('FEEDBACK_MAX_SUBJECT', 64);
define('FEEDBACK_MAX_BODY', 1000);
define('FEEDBACK_MAX_POSTAL', 200);
/**
* @file
* Enables a site-wide feedback page.
*/
/**
* Implementation of hook_menu().
*/
function feedback_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'feedback',
'title' => t('Feedback'),
'callback' => 'feedback_mail_page',
'access' => user_access('can send feedback'),
'type' => MENU_SUGGESTED_ITEM,
);
$items[] = array(
'path' => 'admin/settings/feedback',
'title' => t('Feedback'),
'description' => t('Configure the feedback page'),
'callback' => 'feedback_settings_page',
'access' => user_access('administer feedback'),
'type' => MENU_NORMAL_ITEM,
);
}
return $items;
}
/**
* Implementation of hook_perm().
*/
function feedback_perm() {
return array(
'can send feedback',
'administer feedback',
);
}
/**
* feedback admin center
*/
function feedback_settings_page() {
$page = arg(3);
if (empty($page)) {
$output = feedback_settings_overview($page);
}
else {
if (arg(4) == 'delete' && $page != 'default') {
$output = feedback_settings_delete($page);
}
else {
$output = drupal_get_form('feedback_settings_form', $page);
}
}
print theme('page', $output);
}
/**
* admin settings overview page
*/
function feedback_settings_overview($page) {
//show feedback pages overview
$header = array(
t('Feedback page name'),
t('Feedback page location'),
'',
);
$pages = _feedback_get_page_names();
foreach ($pages as $page) {
$delete = $page != 'default' ? ' ' . l(t('delete'), 'admin/settings/feedback/' . $page . '/delete') : '';
$path = $page != 'default' ? 'feedback/' . $page : 'feedback';
$rows[] = array(
$page,
l(url($path), $path),
l(t('edit'), 'admin/settings/feedback/' . $page) . $delete,
);
}
$output = theme('table', $header, $rows);
$output .= drupal_get_form('feedback_settings_overview_add', $pages);
return $output;
}
function feedback_settings_overview_add($pages) {
$form['group']['page_name'] = array(
'#type' => 'textfield',
'#title' => t('Feedback page name'),
'#size' => 50,
'#maxlength' => 60,
'#required' => TRUE,
);
$form['group'][] = array(
'#type' => 'submit',
'#value' => t('Add page'),
);
$form['group'] += array(
'#type' => 'fieldset',
'#title' => t('Add a further feedback page'),
);
$form['pages'] = array(
'#type' => 'value',
'#value' => $pages,
);
return $form;
}
function feedback_settings_overview_add_validate($form_id, &$edit) {
if (in_array($edit['page_name'], $edit['pages'])) {
form_set_error('page_name', t('This page already exists.'));
}
}
function feedback_settings_overview_add_submit($form_id, &$edit) {
_feedback_add_page($edit['page_name']);
drupal_set_message(t('Your feedback page has been added.'));
}
/**
* Shows a form for editing a feedback page
*/
function feedback_settings_form($pagename) {
$page = _feedback_get_page($pagename);
$form['email'] = array(
'#type' => 'textfield',
'#title' => t('Default Email Address'),
'#default_value' => $page->email,
'#size' => 80,
'#maxlength' => 300,
'#description' => t('The email address which should receive all form submissions'),
'#required' => TRUE,
);
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('Title of the feedback page'),
'#default_value' => $page->title,
'#size' => 80,
'#maxlength' => 80,
'#required' => TRUE,
);
$form['instructions'] = array(
'#type' => 'textarea',
'#title' => t('Instructions'),
'#default_value' => $page->instructions,
'#cols' => 60,
'#rows' => 10,
'#description' => t('The instructions that will be displayed for the user on how to fill the form'),
);
$form['subject'] = array(
'#type' => 'fieldset',
'#title' => t('Subject'),
);
$form['subject']['subject_prefix'] = array(
'#type' => 'textfield',
'#title' => t('Subject Prefix'),
'#default_value' => $page->subject_prefix,
'#size' => 80,
'#maxlength' => 80,
'#description' => t('The prefix that should be added before the subject on each email'),
);
$form['subject']['field_subject'] = array(
'#type' => 'checkbox',
'#title' => t('Include a subject textfield'),
'#return_value' => 1,
'#default_value' => $page->field_subject,
);
$form['subject']['field_category'] = array(
'#type' => 'textarea',
'#title' => t('Categories'),
'#default_value' => $page->field_category,
'#cols' => 40,
'#rows' => 6,
'#description' => t('Put each subject category on a separate line or separate them by commas. No HTML allowed.') . '<br />' . t('Leave this field empty to disable this feature.'),
);
$form['fields'] = array(
'#type' => 'fieldset',
'#title' => t('Fields to include on the form'),
);
$form['fields']['field_name'] = array(
'#type' => 'checkbox',
'#title' => t('Sender Name'),
'#return_value' => 1,
'#default_value' => $page->field_name,
);
$form['fields']['field_postal'] = array(
'#type' => 'checkbox',
'#title' => t('Postal Address'),
'#return_value' => 1,
'#default_value' => $page->field_postal,
);
$form['fields']['field_phone'] = array(
'#type' => 'checkbox',
'#title' => t('Phone Number'),
'#return_value' => 1,
'#default_value' => $page->field_phone,
);
$form['fields']['field_body'] = array(
'#type' => 'checkbox',
'#title' => t('Message Body'),
'#return_value' => 1,
'#default_value' => $page->field_body,
);
$form['misc'] = array(
'#type' => 'fieldset',
'#title' => t('Miscellaneous Settings'),
);
$form['misc']['hourly_threshold'] = array(
'#type' => 'select',
'#title' => t('Hourly threshold'),
'#default_value' => $page->hourly_threshold,
'#options' => drupal_map_assoc(array(
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
20,
30,
40,
50,
)),
'#description' => t('The maximum number of form submissions a user can perform per hour.'),
);
$form['misc']['logging'] = array(
'#type' => 'checkbox',
'#title' => t('Log all feedback attempts to watchdog'),
'#return_value' => 1,
'#default_value' => $page->logging,
);
$form['page'] = array(
'#type' => 'value',
'#value' => $page,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save configuration'),
);
return $form;
}
function feedback_settings_form_submit($form_id, $edit) {
$page = $edit['page'];
unset($edit['submit'], $edit['form_id'], $edit['page']);
db_query("UPDATE {feedback_pages} SET data = '%s' WHERE name = '%s'", serialize($edit), $page->name);
drupal_set_message(t('The configuration options have been saved.'));
return array(
'admin/settings/feedback',
);
}
/**
* Deletes a feedback page, if the user confirms
*/
function feedback_settings_delete($pagename) {
if ($_POST['op'] == t('Delete')) {
db_query("DELETE FROM {feedback_pages} WHERE name ='%s'", $pagename);
drupal_set_message(t('The feedback page has been deleted.'));
drupal_goto('admin/settings/feedback');
}
else {
$message = t('Are you sure you want to delete the feedback page "!page"?', array(
'!page' => $pagename,
));
$output = drupal_get_form('confirm_form', array(), $message, 'admin/settings/feedback', $message, t('Delete'), t('Cancel'));
return $output;
}
}
/**
* Site-wide feedback page
*/
function feedback_mail_page() {
if ($pagename = arg(1)) {
//check if this feedback page exists
$pages = _feedback_get_page_names();
if (!in_array($pagename, $pages)) {
drupal_not_found();
exit;
}
}
else {
$pagename = 'default';
}
$page = _feedback_get_page($pagename);
$breadcrumb[] = array(
'path' => 'feedback',
'title' => $page->title,
);
menu_set_location($breadcrumb);
drupal_set_title($page->title);
if (!flood_is_allowed('feedback' . $page->name, $page->hourly_threshold)) {
$message = t('You cannot send more than !number messages per hour. Please try again later.', array(
'!number' => $page->hourly_threshold,
));
drupal_set_message($message, 'error');
return;
}
return drupal_get_form('feedback_mail_form', $page);
}
function feedback_mail_form($page) {
global $user;
$form['instructions'] = array(
'#value' => $page->instructions,
);
if ($page->field_name) {
$form['emailname'] = array(
'#type' => 'textfield',
'#title' => t('Your full name'),
'#default_value' => $user->uid ? $user->name : '',
'#size' => 60,
'#maxlength' => 64,
'#description' => NULL,
'#attributes' => NULL,
'#required' => TRUE,
);
}
$form['mail'] = array(
'#type' => 'textfield',
'#title' => t('Your e-mail address'),
'#default_value' => $user->uid ? $user->mail : '',
'#size' => 60,
'#maxlength' => 64,
'#description' => NULL,
'#attributes' => NULL,
'#required' => TRUE,
);
if ($page->field_postal) {
$form['postal'] = array(
'#type' => 'textarea',
'#title' => t('Your postal address'),
'#cols' => 50,
'#rows' => 4,
);
}
if ($page->field_phone) {
$form['phone'] = array(
'#type' => 'textfield',
'#title' => t('Your phone number'),
'#size' => 60,
'#maxlength' => 64,
);
}
if ($page->field_subject) {
$form['subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#size' => 60,
'#maxlength' => 64,
'#description' => NULL,
'#attributes' => NULL,
'#required' => TRUE,
);
}
if ($page->field_category) {
$form['category'] = array(
'#type' => 'select',
'#title' => t('Category'),
'#options' => _feedback_get_options($page->field_category),
'#description' => NULL,
'#extra' => 0,
'#multiple' => FALSE,
'#required' => TRUE,
);
}
if ($page->field_body) {
$form['body'] = array(
'#type' => 'textarea',
'#title' => t('Message'),
'#cols' => 60,
'#rows' => 15,
'#description' => NULL,
'#attributes' => NULL,
'#required' => TRUE,
);
}
$form['referer'] = array(
'#type' => 'hidden',
'#value' => $_SERVER[HTTP_REFERER],
);
$form['op'] = array(
'#type' => 'submit',
'#value' => t('Send message'),
);
$form['page'] = array(
'#type' => 'value',
'#value' => $page,
);
return $form;
}
/**
* Validate the site-wide form submission.
*/
function feedback_mail_form_validate($form_id, &$edit) {
$page = $edit['page'];
if (!valid_email_address($edit['mail'])) {
form_set_error('mail', t('You must enter a valid e-mail address.'));
}
if (preg_match("/\r|\n/", $edit['subject'])) {
form_set_error('subject', t('The subject cannot contain linebreaks.'));
watchdog('mail', 'Email injection exploit attempted in feedback form subject: ' . check_plain($edit['subject']), WATCHDOG_NOTICE);
}
if (!$edit['emailname'] && $page->field_name) {
form_set_error('emailname', t('Please enter your full name'));
}
else {
if ($page->field_name && drupal_strlen($edit['emailname']) > FEEDBACK_MAX_NAME) {
form_set_error('emailname', t('Too long input.'));
}
}
if ($page->field_category && (!$edit['category'] || !in_array($edit['category'], _feedback_get_options($page->field_category)))) {
form_set_error('category', t('Please choose a category'));
}
if (!$edit['subject'] && $page->field_subject) {
form_set_error('subject', t('Please enter a subject'));
}
else {
if ($page->field_subject && drupal_strlen($edit['subject']) > FEEDBACK_MAX_SUBJECT) {
form_set_error('subject', t('Too long input.'));
}
}
if (!$edit['body'] && $page->field_body) {
form_set_error('body', t('Please enter your message.'));
}
else {
if ($page->field_body && drupal_strlen($edit['body']) > FEEDBACK_MAX_BODY) {
form_set_error('body', t('Please shorten your input. Up to !limit characters are allowed.', array(
'!limit' => FEEDBACK_MAX_BODY,
)));
}
}
if ($page->field_postal && drupal_strlen($edit['postal']) > FEEDBACK_MAX_POSTAL) {
form_set_error('postal', t('Please shorten your input. Up to !limit characters are allowed.', array(
'!limit' => FEEDBACK_MAX_POSTAL,
)));
}
if ($page->field_phone && drupal_strlen($edit['phone']) > 64) {
form_set_error('phone', t('Too long input.'));
}
}
/**
* Process the site-wide form submission.
*/
function feedback_mail_form_submit($form_id, &$edit) {
// Prepare the sender:
$from = feedback_plain_text($edit['mail']);
$page = $edit['page'];
// Compose the body:
if ($page->field_category) {
$message[] = t('Category') . ': ' . check_plain($edit['category']);
}
if ($page->field_body) {
$message[] = feedback_plain_text($edit['body']);
}
$message[] = t('Sent from @form by @name.', array(
'@name' => $edit['emailname'],
'@form' => url($_GET['q'], NULL, NULL, TRUE),
));
$message[] = _feedback_user_info($edit, $page);
// Tidy up the body:
foreach ($message as $key => $value) {
$message[$key] = wordwrap($value);
}
// Prepare the body:
$body = implode("\n\n", $message);
$category = $page->field_category ? ' [' . $edit['category'] . '] ' : ' ';
$subject = $page->subject_prefix . $category . $edit['subject'];
// Send the e-mail to the recipients:
drupal_mail('feedback', $page->email, $subject, $body, $from);
// Log the operation:
flood_register_event('feedback' . $page->name);
if ($page->logging) {
watchdog('mail', t('@name-from sent a feedback e-mail', array(
'@name-from' => $edit['emailname'] . " <{$from}>",
)));
}
// Update user:
drupal_set_message(t('Your message has been sent.'));
// Jump to home page rather than back to feedback page to avoid contradictory messages if flood control has been activated.
drupal_goto();
}
/*
* Returns some additional user information to append to the mail
*/
function _feedback_user_info(&$edit, $page) {
global $user;
$info = "\n" . t('Site Name') . ': ' . variable_get('site_name', '');
if ($user->name) {
$info .= "\n" . t('Registered name') . ': ' . feedback_plain_text($user->name);
}
if ($page->field_name) {
$info .= "\n" . t('Entered Name') . ': ' . feedback_plain_text($edit['emailname']);
}
$info .= "\n" . t('E-mail address') . ': ' . $edit['mail'];
if ($page->field_postal) {
$info .= "\n" . t('Postal address') . ': ' . feedback_plain_text($edit['postal']);
}
if ($page->field_phone) {
$info .= "\n" . t('Phone Number') . ': ' . feedback_plain_text($edit['phone']);
}
if ($edit['referer']) {
$info .= "\n" . t('Referring page') . ': ' . feedback_plain_text($edit['referer']);
}
if (isset($_SERVER['REMOTE_ADDR'])) {
$info .= "\n" . t('IP Address') . ': ' . 'http://whois.domaintools.com/' . feedback_plain_text($_SERVER['REMOTE_ADDR']);
}
if (isset($_SERVER['REMOTE_HOST'])) {
$info .= "\n" . t('Machine name') . ': ' . feedback_plain_text($_SERVER['REMOTE_HOST']);
}
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$info .= "\n" . t('Browser info') . ': ' . feedback_plain_text($_SERVER['HTTP_USER_AGENT']);
}
return $info;
}
/*
* Strips tags and makes entities readable
*/
function feedback_plain_text($string) {
return html_entity_decode(strip_tags($string), ENT_QUOTES);
}
function _feedback_get_options($text) {
$options = array(
'0' => '--',
);
$lines = split("[,\n\r]", $text);
foreach ($lines as $line) {
if ($line = trim($line)) {
$options[$line] = $line;
}
}
return $options;
}
/*
* Returns an array of all available feedback page names
*/
function _feedback_get_page_names() {
$result = db_query('SELECT name from {feedback_pages}');
$pages = array();
while ($row = db_fetch_object($result)) {
$pages[] = $row->name;
}
return $pages;
}
/*
* Returns a data object from a feedback page
*/
function _feedback_get_page($name) {
$result = db_query("SELECT * from {feedback_pages} WHERE name = '%s'", $name);
if ($row = db_fetch_array($result)) {
$row += (array) unserialize($row['data']);
unset($row['data']);
}
return (object) $row;
}
function _feedback_add_page($pagename) {
$defaults = array(
'email' => variable_get('site_mail', ini_get('sendmail_from')),
'title' => t('feedback'),
'hourly_threshold' => 3,
'logging' => 1,
'field_name' => 1,
'field_body' => 1,
);
db_query("INSERT INTO {feedback_pages} (name, data) VALUES('%s','%s')", $pagename, serialize($defaults));
}
Functions
Name | Description |
---|---|
feedback_mail_form | |
feedback_mail_form_submit | Process the site-wide form submission. |
feedback_mail_form_validate | Validate the site-wide form submission. |
feedback_mail_page | Site-wide feedback page |
feedback_menu | Implementation of hook_menu(). |
feedback_perm | Implementation of hook_perm(). |
feedback_plain_text | |
feedback_settings_delete | Deletes a feedback page, if the user confirms |
feedback_settings_form | Shows a form for editing a feedback page |
feedback_settings_form_submit | |
feedback_settings_overview | admin settings overview page |
feedback_settings_overview_add | |
feedback_settings_overview_add_submit | |
feedback_settings_overview_add_validate | |
feedback_settings_page | feedback admin center |
_feedback_add_page | |
_feedback_get_options | |
_feedback_get_page | |
_feedback_get_page_names | |
_feedback_user_info |