Live Demo: Try this and other plugins live — no installation, no risk: demo.markus-michalski.net
On its own the module protects only contact, newsletter and registration. You can use the same check chain for your own forms. The classes are not a documented public API with stability guarantees; they live in the namespace Mmd\AltchaIntegration and are described here as they appear in the code.
The service SpamProtectionFacade is registered as public in the container and runs the whole check chain. A custom controller extension calls it before the actual processing:
use Mmd\AltchaIntegration\Service\SpamProtectionFacade;
use Mmd\AltchaIntegration\Struct\SpamCheckRequest;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
$facade = ContainerFactory::getInstance()
->getContainer()
->get(SpamProtectionFacade::class);
$request = Registry::getRequest();
$result = $facade->validate(new SpamCheckRequest(
action: 'my_form',
ipAddress: $clientIp,
altchaPayload: (string) $request->getRequestParameter('altcha'),
honeypotValue: (string) $request->getRequestParameter($facade->getHoneypotFieldName()),
formData: [
'email' => $email,
'firstName' => $firstName,
'lastName' => $lastName,
],
));
if (!$result->isValid()) {
// evaluate $result->reason and $result->retryAfterSeconds
}
Field of SpamCheckRequest |
Meaning |
|---|---|
action |
Name of the form, at most 50 characters. The rate limit counts per action and client separately |
ipAddress |
Client address. The module's own extensions take it from X-Forwarded-For (first entry) or REMOTE_ADDR |
altchaPayload |
Content of the POST field altcha |
honeypotValue |
Content of the honeypot field |
formData |
Optional. Only email, firstName, lastName and billingAddress with street and city are evaluated. If the array is empty, content validation is skipped |
If spam protection is switched off as a whole, validate() always returns a valid result.
$result->reason holds one of these values:
| Reason | Cause | Message key in the bundled controllers |
|---|---|---|
honeypot_triggered |
Honeypot field not empty | MMD_ALTCHA_ERROR_SPAM_DETECTED |
content_validation_failed |
At least two fields flagged | MMD_ALTCHA_ERROR_CONTENT_VALIDATION |
altcha_missing |
Field altcha empty |
MMD_ALTCHA_ERROR_VERIFICATION_FAILED |
altcha_invalid |
Solution not readable as Base64 or JSON, a required field is missing, the algorithm is not SHA-256, or signature or hash do not match |
MMD_ALTCHA_ERROR_VERIFICATION_FAILED |
altcha_expired |
Challenge too old | MMD_ALTCHA_ERROR_GENERIC |
altcha_replay |
Challenge already used | MMD_ALTCHA_ERROR_GENERIC |
rate_limit_exceeded |
Too many requests, retryAfterSeconds is set |
MMD_ALTCHA_ERROR_RATE_LIMITED, followed by MMD_ALTCHA_RETRY_AFTER |
The translations of the keys are in translations/de/mmd_altcha_lang.php and translations/en/mmd_altcha_lang.php. The keys MMD_ALTCHA_ERROR_CHALLENGE_EXPIRED and MMD_ALTCHA_ERROR_CHALLENGE_REUSED are defined there, but the bundled controllers do not use them.
The widget can be included in any Twig template. Example and prerequisites are on the Storefront page. The widget adds the POST field altcha to the surrounding form by itself.
An overview of the extended core classes is on the Technical page. If your shop extends the same classes as well, the module order in the admin decides which extension runs first.