<?php
// $Id: hiragana_captcha.module,v 1.1 2008/11/29 0829 Exp $
/**
* Implementation of hook_menu().
*/
function hiragana_captcha_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'admin/user/captcha/hiragana_captcha',
'title' => t('Hiragana CAPTCHA'),
'callback' => 'drupal_get_form',
'callback arguments' => array('hiragana_captcha_settings_form'),
'type' => MENU_LOCAL_TASK,
);
}
return $items;
}
/**
* Implementation of hook_help().
*/
function hiragana_captcha_help($section) {
switch ($section) {
case 'admin/user/captcha/hiragana_captcha':
return '<p>'. t('The hiragana CAPTCHA ask for the n<sup>th</sup> word of a predetermined phrase like text CAPTCHA.') .'</p>';
}
}
/**
* Administration form.
*/
function hiragana_captcha_settings_form() {
$form = array();
$form['hiragana_captcha_kanatype'] = array(
'#type' => 'radios',
'#title' => t('Kana type'),
'#description' => t('Select the kana type which display challenge words.'),
'#default_value' => variable_get('hiragana_captcha_kanatype', 0),
'#options' => array(
0 => t('Hiragana'),
1 => t('Katakana'),
2 => t('Random'),
),
);
$form['hiragana_captcha_words'] = array(
'#type' => 'fieldset',
'#title' => t('Words settings'),
'#description' => t('Input the generated word length and number of words in the phrase for hiragana CAPTCHA.'),
);
$form['hiragana_captcha_words']['hiragana_captcha_length_min'] = array(
'#type' => 'textfield',
'#title' => t('Minimum number of characters'),
'#default_value' => variable_get('hiragana_captcha_length_min', 3),
'#size' => 2,
'#maxlength' => 2,
);
$form['hiragana_captcha_words']['hiragana_captcha_length_max'] = array(
'#type' => 'textfield',
'#title' => t('Maximum number of characters'),
'#default_value' => variable_get('hiragana_captcha_length_max', 3),
'#size' => 2,
'#maxlength' => 2,
);
$form['hiragana_captcha_words']['hiragana_captcha_quantity'] = array(
'#type' => 'textfield',
'#title' => t('Number of words in the phrase'),
'#default_value' => variable_get('hiragana_captcha_quantity', 5),
'#size' => 2,
'#maxlength' => 2,
);
return system_settings_form($form);
}
/**
* Validate function of the administration form.
*/
function hiragana_captcha_settings_form_validate($form_id, $form_values) {
if ($form_id == 'hiragana_captcha_settings_form') {
if ($form_values['hiragana_captcha_length_min'] < 1 || $form_values['hiragana_captcha_length_max'] < 1) {
form_set_error('hiragana_captcha_length', t('Minimum and maximum number of characters should be more than \'1\'.'));
}
else if ($form_values['hiragana_captcha_length_min'] > $form_values['hiragana_captcha_length_max']) {
form_set_error('hiragana_captcha_length', t('Maximum number of characters should be more than minimum number of characters.'));
}
if ($form_values['hiragana_captcha_quantity'] < 4 || $form_values['hiragana_captcha_quantity'] > 10) {
form_set_error('hiragana_captcha_quantity', t('Number of words in the phrase should be between 4 and 10.'));
}
}
}
/**
* Implementation of hook_captcha().
*/
function hiragana_captcha_captcha($op, $captcha_type='') {
switch ($op) {
case 'list':
return array('Hiragana');
case 'generate':
if ($captcha_type == 'Hiragana') {
$words = _hiragana_captcha_generate_words(variable_get('hiragana_captcha_quantity', 5));
$question = _hiragana_captcha_generate_phrase($words, 'question');
$answer = _hiragana_captcha_generate_phrase($words, 'answer');
$key = array_rand($question, 1);
$nth = _hiragana_captcha_ordinal($key + 1);
$result = array();
$result['solution'] = $answer[$key];
$result['form']['captcha_response'] = array(
'#type' => 'textfield',
'#title' => t('What is the @nth word in the phrase "@words"?', array('@nth' => $nth, '@words' => implode(' / ', $question))),
'#description' => t('Input the @nth word in <strong>hiragana</strong>. Whether the answer word is hiragana or katakana, input it by hiragana entirely.', array('@nth' => $nth)),
'#weight' => 0,
'#size' => 15,
'#required' => TRUE,
);
return $result;
}
}
}
/**
* function for generating the phrase of Q or A from an array of words.
*/
function _hiragana_captcha_generate_phrase($words, $which) {
$phrase = array();
foreach ($words as $key => $value) {
foreach ($value as $class => $word) {
if ($class == $which) {
$phrase[] = $word;
}
}
}
return $phrase;
}
/**
* function for generating an array of words.
*/
function _hiragana_captcha_generate_words($quantity) {
$length = variable_get('hiragana_captcha_length_min', 3);
$words = array();
for ($w = 0; $w < $quantity; ++$w) {
$words[] = _hiragana_captcha_generate_word(variable_get('hiragana_captcha_length_min', 3), variable_get('hiragana_captcha_length_max', 3));
}
return $words;
}
/**
* function for generating a random nonsense word of a given number of characters.
*/
function _hiragana_captcha_generate_word($min, $max) {
$katakana = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン';
$hiragana = 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん';
$type = variable_get('hiragana_captcha_kanatype', 0);
$switch = ($type == 2) ? mt_rand(0, 1) : $type;
$kana = ($switch == 1) ? $katakana : $hiragana;
$length = mt_rand($min, $max);
$word = array();
for ($i = 0; $i < $length; ++$i) {
$n = mt_rand(0, 45);
$word['question'] .= mb_substr($kana, $n, 1);
$word['answer'] .= mb_substr($hiragana, $n, 1);
}
return $word;
}
/**
* function that returns a textual represention of an ordinal.
*/
function _hiragana_captcha_ordinal($n) {
$ordinalmap = array(
1 => t('first'),
2 => t('second'),
3 => t('third'),
4 => t('fourth'),
5 => t('fifth'),
6 => t('sixth'),
7 => t('seventh'),
8 => t('eighth'),
9 => t('ninth'),
10 => t('tenth')
);
if (array_key_exists($n, $ordinalmap)) {
return $ordinalmap[$n];
}
else {
return "{$n}th";
}
}
// $Id: hiragana_captcha.module,v 1.1 2008/11/29 0829 Exp $
/**
* Implementation of hook_menu().
*/
function hiragana_captcha_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'admin/user/captcha/hiragana_captcha',
'title' => t('Hiragana CAPTCHA'),
'callback' => 'drupal_get_form',
'callback arguments' => array('hiragana_captcha_settings_form'),
'type' => MENU_LOCAL_TASK,
);
}
return $items;
}
/**
* Implementation of hook_help().
*/
function hiragana_captcha_help($section) {
switch ($section) {
case 'admin/user/captcha/hiragana_captcha':
return '<p>'. t('The hiragana CAPTCHA ask for the n<sup>th</sup> word of a predetermined phrase like text CAPTCHA.') .'</p>';
}
}
/**
* Administration form.
*/
function hiragana_captcha_settings_form() {
$form = array();
$form['hiragana_captcha_kanatype'] = array(
'#type' => 'radios',
'#title' => t('Kana type'),
'#description' => t('Select the kana type which display challenge words.'),
'#default_value' => variable_get('hiragana_captcha_kanatype', 0),
'#options' => array(
0 => t('Hiragana'),
1 => t('Katakana'),
2 => t('Random'),
),
);
$form['hiragana_captcha_words'] = array(
'#type' => 'fieldset',
'#title' => t('Words settings'),
'#description' => t('Input the generated word length and number of words in the phrase for hiragana CAPTCHA.'),
);
$form['hiragana_captcha_words']['hiragana_captcha_length_min'] = array(
'#type' => 'textfield',
'#title' => t('Minimum number of characters'),
'#default_value' => variable_get('hiragana_captcha_length_min', 3),
'#size' => 2,
'#maxlength' => 2,
);
$form['hiragana_captcha_words']['hiragana_captcha_length_max'] = array(
'#type' => 'textfield',
'#title' => t('Maximum number of characters'),
'#default_value' => variable_get('hiragana_captcha_length_max', 3),
'#size' => 2,
'#maxlength' => 2,
);
$form['hiragana_captcha_words']['hiragana_captcha_quantity'] = array(
'#type' => 'textfield',
'#title' => t('Number of words in the phrase'),
'#default_value' => variable_get('hiragana_captcha_quantity', 5),
'#size' => 2,
'#maxlength' => 2,
);
return system_settings_form($form);
}
/**
* Validate function of the administration form.
*/
function hiragana_captcha_settings_form_validate($form_id, $form_values) {
if ($form_id == 'hiragana_captcha_settings_form') {
if ($form_values['hiragana_captcha_length_min'] < 1 || $form_values['hiragana_captcha_length_max'] < 1) {
form_set_error('hiragana_captcha_length', t('Minimum and maximum number of characters should be more than \'1\'.'));
}
else if ($form_values['hiragana_captcha_length_min'] > $form_values['hiragana_captcha_length_max']) {
form_set_error('hiragana_captcha_length', t('Maximum number of characters should be more than minimum number of characters.'));
}
if ($form_values['hiragana_captcha_quantity'] < 4 || $form_values['hiragana_captcha_quantity'] > 10) {
form_set_error('hiragana_captcha_quantity', t('Number of words in the phrase should be between 4 and 10.'));
}
}
}
/**
* Implementation of hook_captcha().
*/
function hiragana_captcha_captcha($op, $captcha_type='') {
switch ($op) {
case 'list':
return array('Hiragana');
case 'generate':
if ($captcha_type == 'Hiragana') {
$words = _hiragana_captcha_generate_words(variable_get('hiragana_captcha_quantity', 5));
$question = _hiragana_captcha_generate_phrase($words, 'question');
$answer = _hiragana_captcha_generate_phrase($words, 'answer');
$key = array_rand($question, 1);
$nth = _hiragana_captcha_ordinal($key + 1);
$result = array();
$result['solution'] = $answer[$key];
$result['form']['captcha_response'] = array(
'#type' => 'textfield',
'#title' => t('What is the @nth word in the phrase "@words"?', array('@nth' => $nth, '@words' => implode(' / ', $question))),
'#description' => t('Input the @nth word in <strong>hiragana</strong>. Whether the answer word is hiragana or katakana, input it by hiragana entirely.', array('@nth' => $nth)),
'#weight' => 0,
'#size' => 15,
'#required' => TRUE,
);
return $result;
}
}
}
/**
* function for generating the phrase of Q or A from an array of words.
*/
function _hiragana_captcha_generate_phrase($words, $which) {
$phrase = array();
foreach ($words as $key => $value) {
foreach ($value as $class => $word) {
if ($class == $which) {
$phrase[] = $word;
}
}
}
return $phrase;
}
/**
* function for generating an array of words.
*/
function _hiragana_captcha_generate_words($quantity) {
$length = variable_get('hiragana_captcha_length_min', 3);
$words = array();
for ($w = 0; $w < $quantity; ++$w) {
$words[] = _hiragana_captcha_generate_word(variable_get('hiragana_captcha_length_min', 3), variable_get('hiragana_captcha_length_max', 3));
}
return $words;
}
/**
* function for generating a random nonsense word of a given number of characters.
*/
function _hiragana_captcha_generate_word($min, $max) {
$katakana = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン';
$hiragana = 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん';
$type = variable_get('hiragana_captcha_kanatype', 0);
$switch = ($type == 2) ? mt_rand(0, 1) : $type;
$kana = ($switch == 1) ? $katakana : $hiragana;
$length = mt_rand($min, $max);
$word = array();
for ($i = 0; $i < $length; ++$i) {
$n = mt_rand(0, 45);
$word['question'] .= mb_substr($kana, $n, 1);
$word['answer'] .= mb_substr($hiragana, $n, 1);
}
return $word;
}
/**
* function that returns a textual represention of an ordinal.
*/
function _hiragana_captcha_ordinal($n) {
$ordinalmap = array(
1 => t('first'),
2 => t('second'),
3 => t('third'),
4 => t('fourth'),
5 => t('fifth'),
6 => t('sixth'),
7 => t('seventh'),
8 => t('eighth'),
9 => t('ninth'),
10 => t('tenth')
);
if (array_key_exists($n, $ordinalmap)) {
return $ordinalmap[$n];
}
else {
return "{$n}th";
}
}

