/
MathSpamProtectorField.php
149 lines (126 loc) · 3.63 KB
/
MathSpamProtectorField.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<?php
/**
* {@link FormField} for adding an optional maths protection question to a form.
*
* @package mathspamprotection
*/
class MathSpamProtectorField extends TextField {
/**
* @config
*
* @var bool $enabled
*/
private static $enabled = true;
public function Field($properties = array()) {
if(Config::inst()->get('MathSpamProtectorField', 'enabled')) {
return parent::Field($properties);
}
return null;
}
public function FieldHolder($properties = array()) {
if(Config::inst()->get('MathSpamProtectorField', 'enabled')) {
return parent::FieldHolder($properties);
}
return null;
}
/**
* Returns the spam question
*
* @return string
*/
public function Title() {
return sprintf(
_t('MathSpamProtectionField.SPAMQUESTION', "Spam protection question: %s"),
self::get_math_question()
);
}
/**
* Validates the value submitted by the user with the one saved into the
* {@link Session} and then notify callback object with the spam checking
* result.
*
* @return bool
*/
public function validate($validator) {
if(!Config::inst()->get('MathSpamProtectorField', 'enabled')) {
return true;
}
if(!self::correct_answer($this->Value())) {
$validator->validationError(
$this->name,
_t(
'MathSpamProtectionField.INCORRECTSOLUTION',
"Incorrect solution to the spam protection question, please try again."
),
"error"
);
return false;
}
return true;
}
/**
* Creates the question from random variables, which are also saved to the session.
*
* @return string
*/
public static function get_math_question() {
if(!Session::get("mathQuestionV1") && !Session::get("mathQuestionV2")) {
$v1 = rand(1,9);
$v2 = rand(1,9);
Session::set("mathQuestionV1",$v1);
Session::set("mathQuestionV2",$v2);
} else {
$v1 = Session::get("mathQuestionV1");
$v2 = Session::get("mathQuestionV2");
}
return sprintf(
_t('MathSpamProtection.WHATIS',"What is %s plus %s?"),
MathSpamProtectorField::digit_to_word($v1),
MathSpamProtectorField::digit_to_word($v2)
);
}
/**
* Checks the given answer if it matches the addition of the saved session
* variables.
*
* Users can answer using words or digits.
*
* @return bool
*/
public static function correct_answer($answer){
$v1 = Session::get("mathQuestionV1");
$v2 = Session::get("mathQuestionV2");
Session::clear('mathQuestionV1');
Session::clear('mathQuestionV2');
$word = MathSpamProtectorField::digit_to_word($v1 + $v2);
return ($word == strtolower($answer) || ($v1 + $v2) == $answer);
}
/**
* Helper method for converting digits to their equivalent english words
*
* @return string
*/
public static function digit_to_word($num){
$numbers = array(_t('MathSpamProtection.ZERO', 'zero'),
_t('MathSpamProtection.ONE', 'one'),
_t('MathSpamProtection.TWO', 'two'),
_t('MathSpamProtection.THREE', 'three'),
_t('MathSpamProtection.FOUR', 'four'),
_t('MathSpamProtection.FIVE', 'five'),
_t('MathSpamProtection.SIX', 'six'),
_t('MathSpamProtection.SEVEN', 'seven'),
_t('MathSpamProtection.EIGHT', 'eight'),
_t('MathSpamProtection.NINE', 'nine'),
_t('MathSpamProtection.TEN', 'ten'),
_t('MathSpamProtection.ELEVEN', 'eleven'),
_t('MathSpamProtection.TWELVE', 'twelve'),
_t('MathSpamProtection.THIRTEEN', 'thirteen'),
_t('MathSpamProtection.FOURTEEN', 'fourteen'),
_t('MathSpamProtection.FIFTEEN', 'fifteen'),
_t('MathSpamProtection.SIXTEEN', 'sixteen'),
_t('MathSpamProtection.SEVENTEEN', 'seventeen'),
_t('MathSpamProtection.EIGHTEEN', 'eighteen'));
if($num < 0) return "minus ".($numbers[-1*$num]);
return $numbers[$num];
}
}