botcha.admin.inc in BOTCHA Spam Prevention 7.2
Same filename and directory in other branches
Implementation of botcha administration forms.
File
botcha.admin.incView source
<?php
// @todo Migrate all necessary functions not to have this including.
module_load_include('inc', 'botcha', 'botcha');
/**
* @file
* Implementation of botcha administration forms.
*/
/**
* Generate a random secret key.
*/
function botcha_generate_secret_key() {
return md5(uniqid(mt_rand(), TRUE));
}
/**
* Module settings form.
*/
function botcha_admin_settings($form, &$form_state) {
// We can't use system_settings_form() here because it will put all extra stuff into variables, that we want to avoid.
$form = array();
$form['botcha_secret'] = array(
'#type' => 'textfield',
'#title' => t('Secret key'),
'#default_value' => variable_get('botcha_secret', botcha_generate_secret_key()),
'#description' => t('It is recommended to enter some random text into the secret key. This setting makes your site\'s BOTCHA challenges unique and harder to break.') . '<br />' . t('If you leave this field empty and save configuration, a new random key will be generated for you.'),
);
// BOTCHA Statistics & Logging
$form['botcha_statistics'] = array(
'#type' => 'fieldset',
'#title' => t('Statistics & logging'),
'#description' => t('BOTCHA collects statistics of form submissions and it can report different events into the system log.'),
);
$dblog_link = l(t('log'), 'admin/reports/dblog');
$form['botcha_statistics']['botcha_loglevel'] = array(
'#type' => 'select',
'#title' => t('Log level'),
'#default_value' => variable_get('botcha_loglevel', 2),
'#options' => array(
0 => t('0: no log'),
1 => t('1: blocked/bad submissions only'),
2 => t('2: ... and why blocked'),
3 => t('3: ... and good submissions'),
4 => t('4: ... and protected forms'),
5 => t('5: ... and extra submission details'),
6 => t('6: ... and misc development items'),
),
'#description' => t('Select what information to report into the !log.' . ' Please note!: Using BOTCHA logging setting could cause at high' . ' levels putting vulnerable data into logs. We have some basic' . ' escaping (e.g., for password field) - but any other data could' . ' be found in raw format. Please be careful with logging level' . ' setting!', array(
'!log' => $dblog_link,
)),
);
// Button for resetting the BOTCHA statistics.
$form['botcha_statistics']['botcha_statistics_group'] = array(
'#type' => 'item',
'#title' => t('BOTCHA statistics'),
'#description' => t('Reset all accumulated statistics of form submissions.'),
);
// Handle the button for resetting the BOTCHA statistics.
// This is done here instead of in a submit handler because the button is
// not a submitting button.
$form['botcha_statistics']['botcha_statistics_group']['botcha_statistics_reset'] = array(
'#type' => 'button',
'#value' => t('Reset BOTCHA statistics'),
'#submit' => array(
'botcha_statistics_reset',
),
// Pull it down.
'#weight' => 100,
);
if (isset($form_state['input']['op']) && $form_state['input']['op'] == $form['botcha_statistics']['botcha_statistics_group']['botcha_statistics_reset']['#value']) {
variable_set('botcha_form_passed_counter', 0);
variable_set('botcha_form_blocked_counter', 0);
drupal_set_message(t('BOTCHA statistics have been reset.'));
}
// Show statistic counters.
$block_cnt = variable_get('botcha_form_blocked_counter', 0);
$build_cnt = variable_get('botcha_form_passed_counter', 0) + $block_cnt;
$form['botcha_statistics']['botcha_statistics_group']['botcha_statistics'] = array(
'#type' => 'item',
'#markup' => format_plural($block_cnt, 'Already 1 blocked form submission.', 'Already @count blocked form submissions.') . ($build_cnt > 0 ? ' ' . t('(!percent% of total !build_cnt processed)', array(
'!percent' => sprintf("%0.3f", 100 * $block_cnt / $build_cnt),
'!build_cnt' => $build_cnt,
)) : ''),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save configuration'),
);
$form['#theme'] = 'system_settings_form';
return $form;
}
/**
* Submission function for botcha_admin_settings form.
*/
function botcha_admin_settings_submit($form, &$form_state) {
// Generate the secret key.
// @todo botcha_admin_settings_submit Move secret key generation to validate phase.
if (empty($form_state['values']['botcha_secret'])) {
// Generate unique secret for this site
$secret = botcha_generate_secret_key();
$form_state['values']['botcha_secret'] = $secret;
drupal_set_message(t('New BOTCHA secret key have been generated.'));
}
// Do what system_settings_form() would do with regular variable fields
variable_set('botcha_secret', $form_state['values']['botcha_secret']);
variable_set('botcha_loglevel', $form_state['values']['botcha_loglevel']);
drupal_set_message(t('The BOTCHA settings were saved.'), 'status');
}
/**
* Edit existent or add a new recipe book.
* @param array $form
* Form API form array.
* @param array $form_state
* Form API form state array.
* @param BotchaRecipebook $recipebook
* Recipe book object.
*/
function botcha_recipebook_form($form, &$form_state, $recipebook = NULL) {
// Determine default values depending on whether we add or edit recipe book.
// Form a list of recipes.
$options_recipes = array();
foreach (Botcha::getRecipes() as $recipe) {
$options_recipes[$recipe->id] = $recipe->title;
}
if (empty($recipebook)) {
$disabled_id = FALSE;
$default_id = '';
$default_title = '';
$default_description = '';
$default_recipes = array();
$button = t('Add');
}
else {
$disabled_id = TRUE;
$default_id = $recipebook->id;
$default_title = $recipebook->title;
$default_description = $recipebook->description;
$default_recipes = array_keys($recipebook
->getRecipes());
$button = t('Save');
}
$form['id'] = array(
'#type' => 'machine_name',
'#default_value' => $default_id,
'#disabled' => $disabled_id,
'#maxlength' => 128,
'#machine_name' => array(
'exists' => 'botcha_recipebook_exists',
),
);
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#description' => t('A title for this recipe book. You can always change this name later.'),
'#default_value' => $default_title,
'#required' => TRUE,
'#maxlength' => 128,
);
$form['description'] = array(
'#type' => 'textarea',
'#rows' => 5,
'#title' => t('Description'),
'#description' => t('A description of the recipe book.'),
'#default_value' => $default_description,
);
$form['recipes'] = array(
'#type' => 'checkboxes',
'#title' => t('Recipes'),
'#description' => t('Choose what recipes are included in recipe book.'),
'#options' => $options_recipes,
'#default_value' => $default_recipes,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => $button,
);
return $form;
}
/**
* Submit handler for botcha_recipebook_form.
* @param $form
* Form API form array.
* @param $form_state
* Form API form state array.
*/
function botcha_recipebook_form_submit($form, &$form_state) {
$values = $form_state['values'];
$recipebook = Botcha::getRecipebook($values['id'])
->setTitle($values['title'])
->setDescription($values['description']);
/*
foreach (array_filter($values['recipes']) as $recipe_id) {
$recipebook->setRecipe($recipe_id);
}
*
*/
foreach ($values['recipes'] as $recipe_id => $value) {
if ($value) {
$recipebook
->setRecipe($recipe_id);
}
else {
$recipebook
->unsetRecipe($recipe_id);
}
}
$recipebook
->save();
$form_state['redirect'] = Botcha::BOTCHA_ADMIN_PATH . '/recipebook';
drupal_set_message(t('Settings for recipe book "%recipebook" are successfully saved.', array(
'%recipebook' => $recipebook->id,
)), 'status');
}
/**
* Delete configuration form.
*/
function botcha_recipebook_delete_form($form, &$form_state, $recipebook) {
$form['#recipebook'] = $recipebook;
return confirm_form($form, t('Would you really like to delete the recipe book @recipebook?', array(
'@recipebook' => $recipebook->title,
)), Botcha::BOTCHA_ADMIN_PATH . '/recipebook', t('This action cannot be undone.'), t('Delete'));
}
/**
* Submit handler for botcha_recipebook_delete_form().
*/
function botcha_recipebook_delete_form_submit($form, &$form_state) {
$form_state['redirect'] = Botcha::BOTCHA_ADMIN_PATH . '/recipebook';
// Remove recipe book.
$form['#recipebook']
->delete();
}
function botcha_recipebook_exists($value) {
return !Botcha::getRecipebook($value, FALSE) instanceof BotchaRecipebookNone;
}
/**
* Edit existent or add BOTCHA protection to another form.
* @param array $form
* Form API form array.
* @param array $form_state
* Form API form state array.
* @param BotchaForm $botcha_form
* Botcha form object.
*/
function botcha_form_form($form, $form_state, $botcha_form = NULL) {
return Botcha::getAdminForm('form_edit', $form_state, $botcha_form);
}
function botcha_form_exists($value) {
return !Botcha::getForm($value, FALSE) instanceof BotchaFormNone;
}
/**
* Submit handler for botcha_form_form.
*/
function botcha_form_form_submit($form, &$form_state) {
Botcha::submitAdminForm('form_edit', $form, $form_state);
}
/**
* Confirm dialog for deleting a BOTCHA form completely.
*/
function botcha_form_delete_form($form, $form_state, $botcha_form = NULL) {
$form = array();
$form['botcha_form_id'] = array(
'#type' => 'value',
'#value' => $botcha_form->id,
);
$message = t('Are you sure you want to delete the BOTCHA protection for form_id %form_id?', array(
'%form_id' => $botcha_form->id,
));
return confirm_form($form, $message, Botcha::BOTCHA_ADMIN_PATH, NULL, t('Delete'));
}
/**
* Submission handler of BOTCHA form deleting.
*/
function botcha_form_delete_form_submit($form, &$form_state) {
$form_id = $form_state['values']['botcha_form_id'];
Botcha::getForm($form_id, FALSE)
->delete();
drupal_set_message(t('Deleted BOTCHA protection for form %form_id.', array(
'%form_id' => $form_id,
)));
$form_state['redirect'] = Botcha::BOTCHA_ADMIN_PATH . '/form';
}
/**
* Callback for "Forms" admin page.
* Configuration of which forms to protect, with what recipe.
*/
function botcha_forms_form() {
return Botcha::getAdminForm('form_list');
}
/**
* Submission handler for botcha_forms_form form.
*/
function botcha_forms_form_submit($form, &$form_state) {
Botcha::submitAdminForm('form_list', $form, $form_state);
}
/**
* Callback for "Recipe books" admin page.
* @todo ?Is it form really? Perhaps table?
*/
function botcha_recipebooks_form() {
$form['#header'] = array(
t('Title'),
t('Description'),
t('Operations'),
);
// Get all recipe books from database.
$recipebooks = Botcha::getRecipebooks();
// Protect default recipebook from being deleted.
foreach ($recipebooks as $recipebook) {
$form['recipebooks'][$recipebook->id]['title']['#markup'] = $recipebook->title;
$form['recipebooks'][$recipebook->id]['description']['#markup'] = $recipebook->description;
$form['recipebooks'][$recipebook->id]['operations']['#markup'] = in_array($recipebook->id, array(
'forbidden_forms',
)) ? '' : l(t('Edit'), Botcha::BOTCHA_ADMIN_PATH . "/recipebook/{$recipebook->id}") . (in_array($recipebook->id, array(
'default',
'forbidden_forms',
)) ? '' : ' | ' . l(t('Delete'), Botcha::BOTCHA_ADMIN_PATH . "/recipebook/{$recipebook->id}/delete"));
}
return $form;
}
function botcha_recipes_form() {
// @todo Implement Recipe UI.
// @see https://drupal.org/node/1815080
$form = array();
$form['stub'] = array(
'#markup' => t('This functionality is currently in development. See <a href="@issue_link">related issue</a>. Please consider participating in <a href="@patchranger_link">patch crowd funding of this issue</a>. Read more about patch crowd funding on <a href="@botcha_project_link">the BOTCHA project page</a>.', array(
'@issue_link' => url('http://drupal.org/node/1815080'),
'@patchranger_link' => url('http://www.patchranger.com/?do_nid=1815080'),
'@botcha_project_link' => url('http://drupal.org/project/botcha#how-much-does-it-cost'),
)),
);
return $form;
}
/**
* Custom theme function for a table of (form_id -> BOTCHA type) settings
*/
function theme_botcha_forms_form_botcha_forms($variables) {
$form = $variables['form'];
// Prepare header before pass to theme.
$header = $form['#header'];
$rows = array();
// Existing BOTCHA points.
foreach (element_children($form['botcha_forms']) as $id) {
$row = array();
foreach (element_children($form['botcha_forms'][$id]) as $col) {
$row[$col] = drupal_render($form['botcha_forms'][$id][$col]);
}
$rows[$id] = $row;
}
$output = theme('table', array(
'header' => $header,
'rows' => $rows,
));
return $output;
}
/**
* Theme botcha_recipebooks_form().
*/
function theme_botcha_recipebooks_form($variables) {
$form = $variables['form'];
// Iterate through all recipebooks and build a table.
$rows = array();
//foreach (array('enabled', 'disabled') as $type) {
// if (isset($form[$type])) {
foreach (element_children($form['recipebooks']) as $id) {
$row = array();
foreach (element_children($form['recipebooks'][$id]) as $col) {
$row[$col] = array(
'data' => drupal_render($form['recipebooks'][$id][$col]),
);
}
$rows[] = array(
'data' => $row,
);
}
// }
//}
$output = theme('table', array(
'header' => $form['#header'],
'rows' => $rows,
'empty' => t('No recipebooks available.'),
));
if (!empty($rows)) {
$output .= drupal_render_children($form);
}
return $output;
}
//END
Functions
Name | Description |
---|---|
botcha_admin_settings | Module settings form. |
botcha_admin_settings_submit | Submission function for botcha_admin_settings form. |
botcha_forms_form | Callback for "Forms" admin page. Configuration of which forms to protect, with what recipe. |
botcha_forms_form_submit | Submission handler for botcha_forms_form form. |
botcha_form_delete_form | Confirm dialog for deleting a BOTCHA form completely. |
botcha_form_delete_form_submit | Submission handler of BOTCHA form deleting. |
botcha_form_exists | |
botcha_form_form | Edit existent or add BOTCHA protection to another form. |
botcha_form_form_submit | Submit handler for botcha_form_form. |
botcha_generate_secret_key | Generate a random secret key. |
botcha_recipebooks_form | Callback for "Recipe books" admin page. @todo ?Is it form really? Perhaps table? |
botcha_recipebook_delete_form | Delete configuration form. |
botcha_recipebook_delete_form_submit | Submit handler for botcha_recipebook_delete_form(). |
botcha_recipebook_exists | |
botcha_recipebook_form | Edit existent or add a new recipe book. |
botcha_recipebook_form_submit | Submit handler for botcha_recipebook_form. |
botcha_recipes_form | |
theme_botcha_forms_form_botcha_forms | Custom theme function for a table of (form_id -> BOTCHA type) settings |
theme_botcha_recipebooks_form | Theme botcha_recipebooks_form(). |