View source
<?php
include_once "botcha.module";
function botcha_schema() {
$schema['botcha_form'] = array(
'description' => 'Contains a list of all forms for BOTCHA spam protection.',
'fields' => array(
'id' => array(
'description' => 'The machine name of the form.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
),
'primary key' => array(
'id',
),
);
$schema['botcha_recipe'] = array(
'description' => 'Contains a list of all recipes for BOTCHA spam protection.',
'fields' => array(
'id' => array(
'description' => 'The machine name of the recipe.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
'title' => array(
'description' => 'The title of the concrete recipe.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
'description' => array(
'description' => 'The description of the concrete recipe.',
'type' => 'text',
'size' => 'big',
'not null' => FALSE,
),
'classname' => array(
'description' => 'The name of the class initialized for the concrete recipe.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
),
'primary key' => array(
'id',
),
);
$schema['botcha_recipebook'] = array(
'description' => 'Contains a list of all recipe books for BOTCHA spam protection.',
'fields' => array(
'id' => array(
'description' => 'The machine name of the recipe book.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
'title' => array(
'description' => 'The title of the concrete recipe book.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
'description' => array(
'description' => 'The description of the concrete recipe book.',
'type' => 'text',
'size' => 'big',
'not null' => FALSE,
),
),
'primary key' => array(
'id',
),
);
$schema['botcha_recipebook_form'] = array(
'description' => 'Contains a list of the relationships between recipe books and forms.',
'fields' => array(
'rbid' => array(
'description' => 'The machine name of the recipe book.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
'form_id' => array(
'description' => 'The string identificator of the form.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
),
'primary key' => array(
'form_id',
),
'indexes' => array(
'brf_rbid' => array(
'rbid',
),
),
'foreign keys' => array(
'brf_recipebook' => array(
'table' => 'botcha_recipebook',
'columns' => array(
'rbid' => 'id',
),
),
),
);
$schema['botcha_recipebook_recipe'] = array(
'description' => 'Contains a list of the relationships between recipe books and recipes.',
'fields' => array(
'rbid' => array(
'description' => 'The machine name of the recipe book.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
'recipe_id' => array(
'description' => 'The machine name of the recipe.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
),
'primary key' => array(
'rbid',
'recipe_id',
),
'indexes' => array(
'brr_rbid' => array(
'rbid',
),
'brr_recipe_id' => array(
'recipe_id',
),
),
'foreign keys' => array(
'brr_recipe' => array(
'table' => 'botcha_recipe',
'columns' => array(
'recipe_id' => 'id',
),
),
'brr_recipebook' => array(
'table' => 'botcha_recipebook',
'columns' => array(
'rbid' => 'id',
),
),
),
);
return $schema;
}
function botcha_requirements($phase) {
$requirements = array();
$t = get_t();
if ($phase == 'runtime') {
if (variable_get('botcha_form_pass_counter', 0) > 0) {
variable_set('botcha_form_passed_counter', variable_get('botcha_form_passed_counter', 0) + variable_get('botcha_form_pass_counter', 0));
variable_del('botcha_form_pass_counter');
}
if (variable_get('botcha_wrong_response_counter', 0) > 0) {
variable_set('botcha_form_blocked_counter', variable_get('botcha_form_blocked_counter', 0) + variable_get('botcha_wrong_response_counter', 0));
variable_del('botcha_wrong_response_counter');
}
$block_cnt = variable_get('botcha_form_blocked_counter', 0);
$build_cnt = variable_get('botcha_form_passed_counter', 0) + $block_cnt;
$requirements['botcha_statistics'] = array(
'title' => $t('BOTCHA'),
'value' => 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,
)) : ''),
'severity' => REQUIREMENT_INFO,
);
}
return $requirements;
}
function _botcha_default_form_ids() {
$form_ids = array(
'contact_personal_form',
'contact_site_form',
'forum_node_form',
'update_script_selection_form',
'user_login',
'user_login_block',
'user_pass',
'user_register_form',
);
foreach (node_type_get_names() as $type => $name) {
$form_ids[] = 'comment_node_' . $type . '_form';
}
return $form_ids;
}
function botcha_install() {
$t = get_t();
$i18n_variables = variable_get('i18n_variables', '');
if (!is_array($i18n_variables)) {
$i18n_variables = array();
}
$i18n_variables = array_merge($i18n_variables, _botcha_variables(TRUE));
variable_set('i18n_variables', $i18n_variables);
drupal_set_message($t('You can now <a href="@botcha_admin">configure BOTCHA module</a> for your site.', array(
'@botcha_admin' => url(Botcha::BOTCHA_ADMIN_PATH),
)), 'status');
variable_set('botcha_secret', md5(uniqid(mt_rand(), TRUE)));
variable_set('botcha_form_passed_counter', variable_get('botcha_form_passed_counter', 0));
variable_set('botcha_form_blocked_counter', variable_get('botcha_form_blocked_counter', 0));
botcha_update_7200();
botcha_update_7201();
cache_clear_all();
}
function botcha_uninstall() {
db_delete('variable')
->condition('name', 'botcha_%', 'LIKE')
->execute();
$i18n_variables = variable_get('i18n_variables', '');
if (is_array($i18n_variables)) {
$i18n_variables = array_diff($i18n_variables, _botcha_variables());
variable_set('i18n_variables', $i18n_variables);
}
Botcha::clean();
cache_clear_all('variables', 'cache');
}
function botcha_update_7200() {
$schema_definition = botcha_schema();
if (!db_table_exists('botcha_form')) {
db_create_table('botcha_form', $schema_definition['botcha_form']);
}
if (!db_table_exists('botcha_recipe')) {
db_create_table('botcha_recipe', $schema_definition['botcha_recipe']);
}
if (!db_table_exists('botcha_recipebook')) {
db_create_table('botcha_recipebook', $schema_definition['botcha_recipebook']);
}
if (!db_table_exists('botcha_recipebook_form')) {
db_create_table('botcha_recipebook_form', $schema_definition['botcha_recipebook_form']);
}
if (!db_table_exists('botcha_recipebook_recipe')) {
db_create_table('botcha_recipebook_recipe', $schema_definition['botcha_recipebook_recipe']);
}
$recipebooks = array(
array(
'id' => 'default',
'title' => 'Default',
'description' => 'Default recipe book provided by BOTCHA installer. You can customize it.',
),
array(
'id' => 'ajax_friendly',
'title' => 'AJAX friendly',
'description' => 'Recipe book which contains recipes that do not break AJAX form submissions.',
),
array(
'id' => 'forbidden_forms',
'title' => 'Forbidden forms',
'description' => 'Recipe book which contains no recipes at all and forms that must not be protected. This recipe book was created for informational purpose only and can not be edited or deleted.',
),
);
foreach ($recipebooks as $recipebook) {
db_merge('botcha_recipebook')
->key(array(
'id' => $recipebook['id'],
))
->fields(array(
'title' => $recipebook['title'],
'description' => $recipebook['description'],
))
->execute();
}
$forms = _botcha_default_form_ids();
foreach ($forms as $form_id) {
db_merge('botcha_form')
->key(array(
'id' => $form_id,
))
->execute();
$query = db_merge('botcha_recipebook_form')
->key(array(
'form_id' => $form_id,
));
if (in_array($form_id, array(
'update_script_selection_form',
'user_login',
'user_login_block',
))) {
$query
->fields(array(
'rbid' => 'forbidden_forms',
))
->execute();
}
else {
$query
->fields(array(
'rbid' => 'default',
))
->execute();
}
}
$recipes = array(
array(
'id' => 'honeypot',
'classname' => 'BotchaRecipeHoneypot',
'title' => 'Default Honeypot recipe',
'description' => 'Recipe which implements Honeypot protection method with default configuration.',
),
array(
'id' => 'honeypot2',
'classname' => 'BotchaRecipeHoneypot2',
'title' => 'Default Honeypot2 recipe',
'description' => 'Recipe which implements Honeypot2 protection method with default configuration.',
),
array(
'id' => 'no_resubmit',
'classname' => 'BotchaRecipeNoResubmit',
'title' => 'Default NoResubmit recipe',
'description' => 'Recipe which implements NoResubmit protection method with default configuration.',
),
array(
'id' => 'obscure_url',
'classname' => 'BotchaRecipeObscureUrl',
'title' => 'Default ObscureUrl recipe',
'description' => 'Recipe which implements ObscureUrl protection method with default configuration.',
),
array(
'id' => 'timegate',
'classname' => 'BotchaRecipeTimegate',
'title' => 'Default Timegate recipe',
'description' => 'Recipe which implements Timegate protection method with default configuration.',
),
);
foreach ($recipes as $recipe) {
db_merge('botcha_recipe')
->key(array(
'id' => $recipe['id'],
))
->fields(array(
'classname' => $recipe['classname'],
'title' => $recipe['title'],
'description' => $recipe['description'],
))
->execute();
$count = count(db_select('botcha_recipebook_recipe', 'brr')
->fields('brr')
->condition('rbid', 'default')
->condition('recipe_id', $recipe['id'])
->execute()
->fetchCol());
if (!$count) {
db_insert('botcha_recipebook_recipe')
->fields(array(
'rbid',
'recipe_id',
))
->values(array(
'rbid' => 'default',
'recipe_id' => $recipe['id'],
))
->execute();
}
if (in_array($recipe['id'], array(
'no_resubmit',
'timegate',
))) {
$count = count(db_select('botcha_recipebook_recipe', 'brr')
->fields('brr')
->condition('rbid', 'ajax_friendly')
->condition('recipe_id', $recipe['id'])
->execute()
->fetchCol());
if (!$count) {
db_insert('botcha_recipebook_recipe')
->fields(array(
'rbid',
'recipe_id',
))
->values(array(
'rbid' => 'ajax_friendly',
'recipe_id' => $recipe['id'],
))
->execute();
}
}
}
if (db_table_exists('botcha_points')) {
db_drop_table('botcha_points');
}
Botcha::clean();
}
function botcha_update_7201() {
foreach (_botcha_default_form_ids() as $form_id) {
$enabled = !in_array($form_id, array(
'update_script_selection_form',
'user_login',
'user_login_block',
));
Botcha::getForm($form_id, TRUE)
->setEnabled($enabled)
->save();
}
Botcha::clean();
}