Skip to content

Commit

Permalink
Enhancement: Extract phpweb\Spam\Challenge
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Dec 14, 2023
1 parent b95f3e7 commit a88faf2
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 92 deletions.
16 changes: 10 additions & 6 deletions manual/add-note.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<?php

use phpweb\Spam\Challenge;

$ip_spam_lookup_url = 'http://www.dnsbl.info/dnsbl-database-check.php?IP=';

$_SERVER['BASE_PAGE'] = 'manual/add-note.php';

require_once __DIR__ . '/../autoload.php';
include_once __DIR__ . '/../include/prepend.inc';
include_once __DIR__ . '/../include/posttohost.inc';
include_once __DIR__ . '/../include/shared-manual.inc';
include __DIR__ . '/spam_challenge.php';

use phpweb\UserNotes\UserNote;

Expand Down Expand Up @@ -55,7 +59,7 @@
}

// SPAM challenge failed
elseif (!test_answer($_POST['func'], $_POST['arga'], $_POST['argb'], $_POST['answer'])) {
elseif (!Challenge::isValidAnswer($_POST['func'], $_POST['arga'], $_POST['argb'], $_POST['answer'])) {
$error = 'SPAM challenge failed.';
}

Expand Down Expand Up @@ -366,14 +370,14 @@
</tr>
<tr>
<th class="subr"><label for="form-answer">Answer to this simple question (SPAM challenge)</label>:<br>
<?php $c = gen_challenge(); echo $c[3]; ?>?</th>
<?php $c = Challenge::create(); echo $c->question; ?>?</th>
<td><input id="form-answer" type="text" name="answer" size="60" maxlength="10" required> (Example: nine)</td>
</tr>
<tr>
<th colspan="2">
<input type="hidden" name="func" value="<?php echo $c[0]; ?>">
<input type="hidden" name="arga" value="<?php echo $c[1]; ?>">
<input type="hidden" name="argb" value="<?php echo $c[2]; ?>">
<input type="hidden" name="func" value="<?php echo $c->function; ?>">
<input type="hidden" name="arga" value="<?php echo $c->argumentOne; ?>">
<input type="hidden" name="argb" value="<?php echo $c->argumentTwo; ?>">
<input type="submit" name="action" value="Preview">
<input type="submit" name="action" value="Add Note">
</th>
Expand Down
66 changes: 0 additions & 66 deletions manual/spam_challenge.php

This file was deleted.

24 changes: 14 additions & 10 deletions manual/vote-note.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<?php

use phpweb\Spam\Challenge;

$_SERVER['BASE_PAGE'] = 'manual/vote-note.php';

require_once __DIR__ . '/../autoload.php';
include_once __DIR__ . '/../include/prepend.inc';
include_once __DIR__ . '/../include/posttohost.inc';
include_once __DIR__ . '/../include/shared-manual.inc';
include_once __DIR__ . '/spam_challenge.php';

// Initialize global variables
$error = false;
Expand Down Expand Up @@ -53,7 +57,7 @@
}
if (!empty($_REQUEST['id']) && !empty($_REQUEST['page']) && ($N = manual_notes_load($_REQUEST['page'])) && array_key_exists($_REQUEST['id'], $N) && !empty($_REQUEST['vote']) && ($_REQUEST['vote'] === 'up' || $_REQUEST['vote'] === 'down')) {
if (!empty($_POST['challenge']) && !empty($_POST['func']) || empty($_POST['arga']) || empty($_POST['argb'])) {
if (!test_answer($_POST['func'], $_POST['arga'], $_POST['argb'], $_POST['challenge'])) {
if (!Challenge::isValidAnswer($_POST['func'], $_POST['arga'], $_POST['argb'], $_POST['challenge'])) {
$error = "Incorrect answer! Please try again.";
}
else {
Expand Down Expand Up @@ -109,13 +113,13 @@
<div style="background-color: #f5f5ff; border: 1px solid black; padding: 15px; width: 90%; margin: auto;">
<form action="" method="post">
<div>
<p><label for="form-challenge">Please answer this simple SPAM challenge</label>: <strong><?php $c = gen_challenge(); echo $c[3]; ?></strong>?<br>
<p><label for="form-challenge">Please answer this simple SPAM challenge</label>: <strong><?php $c = Challenge::create(); echo $c->question; ?></strong>?<br>
<input id="form-challenge" type="text" name="challenge" maxlength="10" required> (Example: nine)</p>
<p><input type="submit" value="Vote" name="votenote"></p>
</div>
<input type="hidden" name="func" value="<?php echo $c[0]; ?>">
<input type="hidden" name="arga" value="<?php echo $c[1]; ?>">
<input type="hidden" name="argb" value="<?php echo $c[2]; ?>">
<input type="hidden" name="func" value="<?php echo $c->function; ?>">
<input type="hidden" name="arga" value="<?php echo $c->argumentOne; ?>">
<input type="hidden" name="argb" value="<?php echo $c->argumentTwo; ?>">
</form>
</div>
</div>
Expand Down Expand Up @@ -158,13 +162,13 @@
<div style="background-color: #f5f5ff; border: 1px solid black; padding: 15px; width: 90%; margin: auto;">
<form action="" method="post">
<div>
<p><label for="form-challenge">Please answer this simple SPAM challenge</label>: <strong><?php $c = gen_challenge(); echo $c[3]; ?></strong>?<br>
<p><label for="form-challenge">Please answer this simple SPAM challenge</label>: <strong><?php $c = Challenge::create(); echo $c->question; ?></strong>?<br>
<input id="form-challenge" type="text" name="challenge" maxlength="10" required> (Example: nine)</p>
<p><input type="submit" value="Vote" name="votenote"></p>
</div>
<input type="hidden" name="func" value="<?php echo $c[0]; ?>">
<input type="hidden" name="arga" value="<?php echo $c[1]; ?>">
<input type="hidden" name="argb" value="<?php echo $c[2]; ?>">
<input type="hidden" name="func" value="<?php echo $c->function; ?>">
<input type="hidden" name="arga" value="<?php echo $c->argumentOne; ?>">
<input type="hidden" name="argb" value="<?php echo $c->argumentTwo; ?>">
</form>
<?php echo $error_div; ?>
</div>
Expand Down
160 changes: 160 additions & 0 deletions src/Spam/Challenge.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<?php

declare(strict_types=1);

namespace phpweb\Spam;

final readonly class Challenge
{
private const NUMBERS = [
0 => 'zero',
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four',
5 => 'five',
6 => 'six',
7 => 'seven',
8 => 'eight',
9 => 'nine',
];

private const CHALLENGES = [
// name, print, generator
'max' => [
'max',
[
self::class,
'print_prefix',
],
],
'min' => [
'min',
[
self::class,
'print_prefix',
],
],
'minus' => [
[
self::class,
'minus',
],
[
self::class,
'print_infix',
],
[
self::class,
'gen_minus',
],
],
'plus' => [
[
self::class,
'plus',
],
[
self::class,
'print_infix',
],
[
self::class,
'gen_plus',
],
],
];

private function __construct(
public string $function,
public string $argumentOne,
public string $argumentTwo,
public string $question,
) {
}

public static function create(): self
{
$function = array_rand(self::CHALLENGES);

$challenge = self::CHALLENGES[$function];

$a = mt_rand(0, 9);
$argumentOne = self::NUMBERS[$a];

$b = isset($challenge[2]) ? $challenge[2]($a) : mt_rand(0, 9);
$argumentTwo = self::NUMBERS[$b];

$question = $challenge[1](
$function,
$argumentOne,
$argumentTwo,
);

return new self(
$function,
$argumentOne,
$argumentTwo,
$question,
);
}

public static function isValidAnswer(
string $function,
string $argumentOne,
string $argumentTwo,
string $answer,
): bool {
if (!array_key_exists($function, self::CHALLENGES)) {
return false;
}

$challenge = self::CHALLENGES[$function];

$a = array_search($argumentOne, self::NUMBERS, true);

if (!is_int($a)) {
return false;
}

$b = array_search($argumentTwo, self::NUMBERS, true);

if (!is_int($b)) {
return false;
}

$expected = self::NUMBERS[$challenge[0]($a, $b)];

return $expected === $answer;
}

private static function plus(int $a, int $b): int
{
return $a + $b;
}

private static function gen_plus(int $a): int
{
return mt_rand(0, 9 - $a);
}

private static function minus(int $a, int $b): int
{
return $a - $b;
}

private static function gen_minus(int $a): int
{
return mt_rand(0, $a);
}

private static function print_infix(string $name, string $a, string $b): string
{
return "$a $name $b";
}

private static function print_prefix(string $name, string $a, string $b): string
{
return "$name($a, $b)";
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
--TEST--
test_answer() returns true when answer to spam challenge is valid
Challenge::isValidAnswer() returns true when answer to spam challenge is valid
--FILE--
<?php

require_once __DIR__ . '/../manual/spam_challenge.php';
declare(strict_types=1);

use phpweb\Spam\Challenge;

require_once __DIR__ . '/../../../src/autoload.php';

$answers = [
[
Expand Down Expand Up @@ -73,7 +77,7 @@ $answers = [
];

$results = array_map(static function (array $answer): array {
$answer['isValid'] = test_answer(
$answer['isValid'] = Challenge::isValidAnswer(
$answer['function'],
$answer['argumentOne'],
$answer['argumentTwo'],
Expand Down
18 changes: 11 additions & 7 deletions tests/gen-challenge.phpt → tests/Spam/Challenge/random.phpt
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
--TEST--
gen_challenge() generates a spam challenge
Challenge::random() generates a spam challenge
--FILE--
<?php

require_once __DIR__ . '/../manual/spam_challenge.php';
declare(strict_types=1);

use phpweb\Spam\Challenge;

require_once __DIR__ . '/../../../src/autoload.php';

mt_srand(9001);

$challenges = array_map(static function (): array {
[$function, $argumentOne, $argumentTwo, $question] = gen_challenge();
$challenge = Challenge::create();

return [
'function' => $function,
'argumentOne' => $argumentOne,
'argumentTwo' => $argumentTwo,
'question' => $question,
'function' => $challenge->function,
'argumentOne' => $challenge->argumentOne,
'argumentTwo' => $challenge->argumentTwo,
'question' => $challenge->question,
];
}, range(1, 20));

Expand Down

0 comments on commit a88faf2

Please sign in to comment.