Commit 7d2f2bc7 authored by wundo's avatar wundo

Issue #1949682 by jeqq, m1r1k, podarok, elachlan: Latest patch from the issue

parent c59b4860
File mode changed from 100644 to 100755
......@@ -5,17 +5,20 @@
* Functionality and helper functions for CAPTCHA administration.
*/
/**
* Return an array with the available CAPTCHA types, for use as options array
* for a select form elements.
/**
* Return an array with the available CAPTCHA types.
*
* For use as options array for a select form elements.
*
* @param $add_special_options if true: also add a 'none' and 'default' option
* @param bool $add_special_options
* If true: also add a 'none' and 'default' option.
*
* @return an associative array mapping "$module/$type" to
* "$type (from module $module)" with $module the module name implementing the CAPTCHA
* and $type the name of the CAPTCHA type.
* @return array
* An associative array mapping "$module/$type" to
* "$type (from module $module)" with $module the module name
* implementing the CAPTCHA and $type the name of the CAPTCHA type.
*/
function _captcha_available_challenge_types($add_special_options=TRUE) {
function _captcha_available_challenge_types($add_special_options = TRUE) {
$captcha_types = array();
if ($add_special_options) {
$captcha_types['none'] = t('- No challenge -');
......@@ -35,31 +38,34 @@ function _captcha_available_challenge_types($add_special_options=TRUE) {
}
/**
* Central handler for CAPTCHA point administration (adding, disabling, deleting)
* Central handler for CAPTCHA point administration.
*/
function captcha_point_admin($captcha_point_form_id=NULL, $op=NULL) {
function captcha_point_admin($captcha_point_form_id = NULL, $op = NULL) {
module_load_include('inc', 'captcha');
// if $captcha_point_form_id and action $op given: do the action
// If $captcha_point_form_id and action $op given: do the action.
if ($captcha_point_form_id) {
switch ($op) {
case 'disable':
return drupal_get_form('captcha_point_disable_confirm', $captcha_point_form_id, FALSE);
case 'delete':
return drupal_get_form('captcha_point_disable_confirm', $captcha_point_form_id, TRUE);
}
// return edit form for CAPTCHA point
return drupal_get_form('captcha_point_admin_form', $captcha_point_form_id);
}
// return add form for CAPTCHA point
return drupal_get_form('captcha_point_admin_form');
}
function captcha_point_admin_form($form, $form_state, $captcha_point_form_id=NULL) {
/**
* CAPTCHA settings form.
*/
function captcha_point_admin_form($form, $form_state, $captcha_point_form_id = NULL) {
$form = array();
$default_captcha_type = 'none';
if (isset($captcha_point_form_id)) {
// use given CAPTCHA point form_id
$form['captcha_point_form_id'] = array(
'#type' => 'textfield',
'#title' => t('Form ID'),
......@@ -73,14 +79,13 @@ function captcha_point_admin_form($form, $form_state, $captcha_point_form_id=NUL
}
}
else {
// textfield for CAPTCHA point form_id
$form['captcha_point_form_id'] = array(
'#type' => 'textfield',
'#title' => t('Form ID'),
'#description' => t('The Drupal form_id of the form to add the CAPTCHA to.'),
);
}
// select widget for CAPTCHA type
$form['captcha_type'] = array(
'#type' => 'select',
'#title' => t('Challenge type'),
......@@ -88,9 +93,9 @@ function captcha_point_admin_form($form, $form_state, $captcha_point_form_id=NUL
'#default_value' => $default_captcha_type,
'#options' => _captcha_available_challenge_types(),
);
// redirect to general CAPTCHA settings page after submission
// Redirect to general CAPTCHA settings page after submission.
$form['#redirect'] = 'admin/config/people/captcha';
// submit button
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
'#type' => 'submit',
......@@ -99,9 +104,8 @@ function captcha_point_admin_form($form, $form_state, $captcha_point_form_id=NUL
return $form;
}
/**
* validation function for captcha_point_admin_form
* Validation function for captcha_point_admin_form.
*/
function captcha_point_admin_form_validate($form, $form_state) {
if (!preg_match('/^[a-z0-9_]+$/', $form_state['values']['captcha_point_form_id'])) {
......@@ -109,7 +113,6 @@ function captcha_point_admin_form_validate($form, $form_state) {
}
}
/**
* Submit function for captcha_point_admin_form.
*/
......@@ -121,7 +124,7 @@ function captcha_point_admin_form_submit($form, $form_state) {
}
/**
* Confirm dialog for disabling/deleting a CAPTCHA point
* Confirm dialog for disabling/deleting a CAPTCHA point.
*/
function captcha_point_disable_confirm($form, &$form_state, $captcha_point_form_id, $delete) {
$form = array();
......@@ -173,7 +176,7 @@ function _captcha_generate_example_challenge($module, $type) {
}
/**
* Funtion for generating a page with CAPTCHA examples.
* Function for generating a page with CAPTCHA examples.
*
* If the arguments $module and $challenge are not set, generate a list with
* examples of the available CAPTCHA types.
......@@ -186,12 +189,12 @@ function captcha_examples($form, $form_state, $module, $challenge) {
$form = array();
if ($module && $challenge) {
// Generate 10 example challenges.
for ($i=0; $i<10; $i++) {
for ($i = 0; $i < 10; $i++) {
$form["challenge_{$i}"] = _captcha_generate_example_challenge($module, $challenge);
}
}
else {
// generate a list with examples of the available CAPTCHA types
// Generate a list with examples of the available CAPTCHA types.
$form['info'] = array(
'#markup' => t('This page gives an overview of all available challenge types, generated with their current settings.'),
);
......
This diff is collapsed.
File mode changed from 100644 to 100755
......@@ -5,35 +5,12 @@
* Install, update and uninstall functions for the CAPTCHA module.
*/
use Drupal\captcha\Entity\CaptchaPoint;
/**
* Implementation of hook_schema().
* Implements hook_schema().
*/
function captcha_schema() {
// Table for positions and types of the challenges.
$schema['captcha_points'] = array(
'description' => 'This table describes which challenges should be added to which forms.',
'fields' => array(
'form_id' => array(
'description' => 'The form_id of the form to add a CAPTCHA to.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
'module' => array(
'description' => 'The module that provides the challenge.',
'type' => 'varchar',
'length' => 64,
),
'captcha_type' => array(
'description' => 'The challenge type to use.',
'type' => 'varchar',
'length' => 64,
),
),
'primary key' => array('form_id'),
);
// Table for the CAPTCHA sessions.
$schema['captcha_sessions'] = array(
'description' => 'Stores the data about CAPTCHA sessions (solution, IP address, timestamp, ...).',
'fields' => array(
......@@ -97,7 +74,7 @@ function captcha_schema() {
'type' => 'int',
'not null' => TRUE,
'default' => 0,
)
),
),
'primary key' => array('csid'),
'indexes' => array(
......@@ -109,16 +86,18 @@ function captcha_schema() {
}
/**
* Implementation of hook_requirements().
* Implements hook_requirements().
*/
function captcha_requirements($phase) {
$requirements = array();
if ($phase == 'runtime' && variable_get('captcha_enable_stats', FALSE)) {
$config = \Drupal::config('captcha.settings');
if ($phase == 'runtime' && $config->get('captcha_enable_stats')) {
// Show the wrong response counter in the status report.
$requirements['captcha_wrong_response_counter'] = array(
'title' => t('CAPTCHA'),
'title' => \Drupal::translation()->translate('CAPTCHA'),
'value' => format_plural(
variable_get('captcha_wrong_response_counter', 0),
$config->get('captcha_wrong_response_counter'),
'Already 1 blocked form submission',
'Already @count blocked form submissions'
),
......@@ -129,206 +108,39 @@ function captcha_requirements($phase) {
}
/**
* Implementation of hook_install().
* Implements hook_install().
*/
function captcha_install() {
// Insert some default CAPTCHA points.
$form_ids = array(
'contact_site_form', 'contact_personal_form',
'user_register_form', 'user_pass', 'user_login_form', 'user_login_block',
'forum_node_form'
'contact_site_form',
'contact_personal_form',
'user_register_form',
'user_pass',
'user_login_form',
'user_login_block',
'forum_node_form',
);
// Add form_ids of all currently known node types too.
foreach (node_type_get_names() as $type => $name) {
$form_ids[] = $type .'_node_form';
$form_ids[] = $type . '_node_form';
}
foreach ($form_ids as $form_id) {
db_insert('captcha_points')
->fields(array(
'form_id' => $form_id,
'module' => NULL,
'captcha_type' => NULL,
))
->execute();
$values = array(
'formId' => $form_id,
'captchaType' => 'none',
);
$captcha_point = new CaptchaPoint($values, 'captcha_point');
$captcha_point->save();
}
// Be friendly to your users: what to do after install?
drupal_set_message(t('You can now <a href="!captcha_admin">configure the CAPTCHA module</a> for your site.',
drupal_set_message(\Drupal::translation()->translate('You can now <a href="!captcha_admin">configure the CAPTCHA module</a> for your site.',
array('!captcha_admin' => url('admin/config/people/captcha'))), 'status');
// Explain to users that page caching may be disabled.
if (variable_get('cache', 0) != 0) {
drupal_set_message($t('Note that the CAPTCHA module disables <a href="!performance_admin">page caching</a> of pages that include a CAPTCHA challenge.',
if ($config = \Drupal::config('system.performance')->get('cache.page.use_internal') != 0) {
drupal_set_message(\Drupal::translation()->translate('Note that the CAPTCHA module disables <a href="!performance_admin">page caching</a> of pages that include a CAPTCHA challenge.',
array('!performance_admin' => url('admin/config/development/performance'))), 'warning');
}
}
/**
* Implementation of hook_uninstall().
*/
function captcha_uninstall() {
drupal_uninstall_schema('captcha');
db_query("DELETE FROM {variable} WHERE name LIKE 'captcha_%'");
cache()->deleteTags(array('variables' => TRUE));
}
/**
* Implementation of hook_update_N()
*/
function captcha_update_6200() {
$items = array();
// Table for the CAPTCHA sessions.
$schema['captcha_sessions'] = array(
'description' => 'Stores the data about CAPTCHA sessions (solution, IP address, timestamp, ...).',
'fields' => array(
'csid' => array(
'description' => 'CAPTCHA session ID.',
'type' => 'serial',
'not null' => TRUE,
),
'uid' => array(
'description' => "User's {users}.uid.",
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'sid' => array(
'description' => "Session ID of the user.",
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'default' => '',
),
'ip_address' => array(
'description' => 'IP address of the visitor.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
),
'timestamp' => array(
'description' => 'A Unix timestamp indicating when the challenge was generated.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'form_id' => array(
'description' => 'The form_id of the form where the CAPTCHA is added to.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
),
'solution' => array(
'description' => 'Solution of the challenge.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
'status' => array(
'description' => 'Status of the CAPTCHA session (unsolved, solved, ...)',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'attempts' => array(
'description' => 'The number of attempts.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
)
),
'primary key' => array('csid'),
'indexes' => array(
'csid_ip' => array('csid', 'ip_address'),
),
);
db_create_table($items, 'captcha_sessions', $schema['captcha_sessions']);
return $items;
}
/**
* Implementation of hook_update_N()
* Change the captcha points with the old text CAPTCHA, which was
* removed from the 6.x-2.x branch, to the simple math CAPTCHA.
*/
function captcha_update_6201() {
$items = array();
$items[] = update_sql("UPDATE {captcha_points} SET module = 'captcha', type = 'Math' WHERE module = 'text_captcha' AND type = 'Text';");
return $items;
}
/**
* Implementation of hook_update_N()
* Add a CAPTCHA token column to captcha_sessions table.
*/
function captcha_update_6202() {
$ret = array();
db_add_column($ret, 'captcha_sessions', 'token', 'varchar(64)');
return $ret;
}
/**
* Implementation of hook_update_N()
* Rename the type field to captcha_type in captcha_points.
*/
function captcha_update_6203() {
$ret = array();
db_change_field($ret, 'captcha_points', 'type', 'captcha_type', array('type' => 'varchar', 'length' => 64));
return $ret;
}
/**
* Migrate form configuration for changed form ids in Drupal 7.
*/
function captcha_update_7000() {
// 'user_register' became 'user_register_form'.
db_update('captcha_points')
->fields(array('form_id' => 'user_register_form'))
->condition('form_id', 'user_register')
->execute();
// 'contact_mail_page' became 'contact_site_form'.
db_update('captcha_points')
->fields(array('form_id' => 'contact_site_form'))
->condition('form_id', 'contact_mail_page')
->execute();
// 'contact_mail_user' became 'contact_personal_form'.
db_update('captcha_points')
->fields(array('form_id' => 'contact_personal_form'))
->condition('form_id', 'contact_mail_user')
->execute();
// The D6-style comment_form form_id is split per node type
// in D7: comment_node_{type}_form, e.g. comment_node_page_form.
// Get the current settings for 'comment_form'.
$captcha_point = db_query(
"SELECT * FROM {captcha_points} WHERE form_id = :comment_form_id",
array(':comment_form_id' => 'comment_form')
)->fetchObject();
if ($captcha_point !== FALSE) {
// Create entries for D7-style node form IDs.
$module = $captcha_point->module;
$captcha_type = $captcha_point->captcha_type;
foreach (node_type_get_names() as $type => $name) {
$form_id = 'comment_node_' . $type . '_form';
db_insert('captcha_points')
->fields(array(
'form_id' => $form_id,
'module' => $module,
'captcha_type' => $captcha_type,
))
->execute();
}
// Delete outdated entry.
db_delete('captcha_points')
->condition('form_id', 'comment_form')
->execute();
}
}
(function ($) {
/**
* @file
* Contains helper javascript for captcha settings forms.
*
* @TODO remove this file and use native Drupal states.
*/
(function ($) {
Drupal.behaviors.captchaAdmin = {
attach: function (context) {
// Add onclick handler to checkbox for adding a CAPTCHA description
// so that the textfields for the CAPTCHA description are hidden
// when no description should be added.
// Add onclick handler to checkbox for adding a CAPTCHA description
// so that the textfields for the CAPTCHA description are hidden
// when no description should be added.
// @todo: div.form-item-captcha-description depends on theming, maybe
// it's better to add our own wrapper with id (instead of a class).
$("#edit-captcha-add-captcha-description").click(function() {
if ($("#edit-captcha-add-captcha-description").is(":checked")) {
// Show the CAPTCHA description textfield(s).
$("div.form-item-captcha-description").show('slow');
}
else {
// Hide the CAPTCHA description textfield(s).
$("div.form-item-captcha-description").hide('slow');
}
});
// Hide the CAPTCHA description textfields if option is disabled on page load.
if (!$("#edit-captcha-add-captcha-description").is(":checked")) {
$("div.form-item-captcha-description").hide();
}
$("#edit-captcha-add-captcha-description").click(function() {
if ($("#edit-captcha-add-captcha-description").is(":checked")) {
// Show the CAPTCHA description textfield(s).
$("div.form-item-captcha-description").show('slow');
}
else {
// Hide the CAPTCHA description textfield(s).
$("div.form-item-captcha-description").hide('slow');
}
});
// Hide the CAPTCHA description textfields if option is disabled on page load.
if (!$("#edit-captcha-add-captcha-description").is(":checked")) {
$("div.form-item-captcha-description").hide();
}
}
};
......
base:
version: 1.0
js:
captcha.js: {}
dependencies:
- core/jquery
- core/drupal
- core/drupalSettings
- core/jquery.once
captcha_point.add:
route_name: 'captcha_point.add'
title: 'Add captcha point'
appears_on:
- captcha_point.list
captcha.settings:
title: 'CAPTCHA module settings'
description: 'Administer how and where CAPTCHA is used.'
route_name: captcha_settings
parent: user.admin_index
weight: -1
captcha.examples:
title: 'CAPTCHA examples'
description: An overview of the available challenge types with examples.'
route_name: captcha_examples
parent: captcha.settings
weight: 0
captcha_settings:
route_name: captcha_settings
title: 'CAPTCHA Settings'
base_route: captcha_settings
captcha_examples:
route_name: captcha_examples
title: 'CAPTCHA examples'
base_route: captcha_settings
captcha_points.list:
route_name: captcha_point.list
title: 'CAPTCHA Points'
base_route: captcha_settings
This diff is collapsed.
captcha_settings:
pattern: '/admin/config/people/captcha'
path: '/admin/config/people/captcha'
defaults:
_form: '\Drupal\captcha\Form\CaptchaSettingsForm'
_title: 'CAPTCHA settings'
requirements:
_permission: 'administer CAPTCHA settings'
\ No newline at end of file
_permission: 'administer CAPTCHA settings'
captcha_examples:
path: '/admin/config/people/captcha/examples/{module}/{challenge}'
defaults:
_form: '\Drupal\captcha\Form\CaptchaExamplesForm'
module: ''
challenge: ''
requirements:
_permission: 'administer CAPTCHA settings'
captcha_point.list:
path: '/admin/config/people/captcha/captcha-points'
defaults:
_entity_list: 'captcha_point'
_title: 'CAPTCHA configuration'
requirements:
_permission: 'administer CAPTCHA settings'
captcha_point.add:
path: '/admin/config/people/captcha/captcha-points/add'
defaults:
_entity_form: 'captcha_point.add'
_title: 'Add CAPTCHA point'
requirements:
_permission: 'administer CAPTCHA settings'
captcha_point.edit:
path: '/admin/config/people/captcha/captcha-points/{captcha_point}'
defaults:
_entity_form: 'captcha_point.edit'
_title: 'Edit CAPTCHA point'
options:
_admin_route: TRUE
requirements:
_permission: 'administer CAPTCHA settings'
captcha_point.delete:
path: '/admin/config/people/captcha/captcha-points/{captcha_point}/delete'
defaults:
_entity_form: 'captcha_point.delete'
_title: 'Delete CAPTCHA point'
options:
_admin_route: TRUE
requirements:
_permission: 'administer CAPTCHA settings'
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
captcha_default_challenge: 'captcha/Math'
captcha_description: 'This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.'
captcha_administration_mode: 0
captcha_allow_on_admin_pages: 0
captcha_add_captcha_description: 1
captcha_default_validation: 1
captcha_persistence: 1
captcha_enable_stats: 0
captcha_log_wrong_responses: 0
captcha_wrong_response_counter: 0
image_captcha_fonts_preview_map_cache: []
\ No newline at end of file
captcha.captcha_point.*:
type: config_entity
label: 'CAPTCHA point'
mapping:
formId:
type: string
label: 'Form ID'
captchaType:
type: string
label: 'Captcha Type'
label:
type: label
label: 'Label'
uuid:
type: string
label: 'UUID'
\ No newline at end of file
......@@ -13,22 +13,22 @@ captcha.settings:
label: 'The default captcha description.'
captcha_administration_mode:
type: boolean
label: ''
label: 'Add CAPTCHA administration links to forms'
captcha_allow_on_admin_pages:
type: boolean
label: ''
label: 'Allow CAPTCHAs and CAPTCHA administration links on administrative pages'
captcha_add_captcha_description:
type: boolean
label: ''
label: 'Add a description to the CAPTCHA'
captcha_default_validation:
type: boolean
label: ''
type: integer
label: 'Default CAPTCHA validation'
captcha_persistence:
type: boolean
label: ''
type: integer
label: 'CAPTCHA Persistence'
captcha_enable_stats:
type: boolean
label: ''
label: 'Enable statistics'
captcha_log_wrong_responses:
type: boolean
label: ''
\ No newline at end of file
label: 'Log wrong responses'
\ No newline at end of file
base:
version: 1.0
js:
image_captcha.js: {}
css:
all:
image_captcha.css: {}
dependencies:
- core/jquery
- core/drupal
- core/drupalSettings
- core/jquery.once
image_captcha_fonts_preview_map_cache: []
image_captcha_fonts: ['BUILTIN']
image_captcha_font_size: 30
image_captcha_character_spacing: '1.2'
image_captcha_image_allowed_chars: 'aAbBCdEeFfGHhijKLMmNPQRrSTtWXYZ23456789'
image_captcha_code_length: 5
image_captcha_rtl_support: 0
image_captcha_background_color: '#ffffff'
image_captcha_foreground_color: '#000000'
image_captcha_foreground_color_randomness: 100
image_captcha_file_format: 1
image_captcha_distortion_amplitude: 0
image_captcha_bilinear_interpolation: 0
image_captcha_dot_noise: 0
image_captcha_line_noise: 0
image_captcha_noise_level: 5
......@@ -4,4 +4,4 @@ However, this is not the recommended way, as they can get lost easily during
a module update. The recommended way to provide your own fonts is putting them
in the files directory of your Drupal setup or, just like with contributed
modules and themes, in the "libraries" folders sites/all/libraries/fonts
or sites/<site>/libraries/fonts.
or sites/<site>/libraries/fonts.
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -5,19 +5,19 @@ public domain.
Original licensing statement of the creator
-------------------------------------------
Here are my dabblings in font design. I have placed them in the Public Domain.
This is all 100% my own work. Usage is totally unrestricted.
Here are my dabblings in font design. I have placed them in the Public Domain.
This is all 100% my own work. Usage is totally unrestricted.
If you want to make derivative works for any purpose, please go ahead.
I welcome comments & constructive criticism.
Put another way, a la PD-self (http://en.wikipedia.org/wiki/Template:PD-self):
I, the copyright holder of this work, hereby release it into the public
I, the copyright holder of this work, hereby release it into the public
domain. This applies worldwide.
In case this is not legally possible,
I grant any entity the right to use this work for any purpose,
I grant any entity the right to use this work for any purpose,
without any conditions, unless such conditions are required by law.