ValidationHandler.php hinzufuegen
This commit is contained in:
@@ -0,0 +1,127 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Plugin\fp_altcha_spamschutz\src\Handler;
|
||||||
|
|
||||||
|
use Plugin\fp_altcha_spamschutz\src\Service\AltchaService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prueft die ALTCHA-Loesung bei Registrierung und Newsletter-Anmeldung.
|
||||||
|
*
|
||||||
|
* Registrierung: nutzt den dokumentierten Hook HOOK_REGISTRIEREN_PAGE_REGISTRIEREN_PLAUSI (41),
|
||||||
|
* der genau fuer diesen Zweck (Plausibilitaetspruefung nach Formularabsendung) vorgesehen ist.
|
||||||
|
* Bei fehlender/ungueltiger Pruefung wird ein Eintrag zu "fehlendeAngaben" hinzugefuegt -- das ist
|
||||||
|
* derselbe Mechanismus, den JTL-Shop fuer "Pflichtfeld nicht ausgefuellt" nutzt, der Kunde bekommt
|
||||||
|
* also die normale, vertraute Fehlermeldung des Shops.
|
||||||
|
*
|
||||||
|
* Newsletter: die Dokumentation zum passenden Hook (HOOK_NEWSLETTER_PAGE_EMPFAENGEREINTRAGEN) ist
|
||||||
|
* nicht eindeutig genug, um sich allein darauf zu verlassen. Deshalb wird zusaetzlich ganz frueh
|
||||||
|
* (direkt in Bootstrap::boot(), vor jeder Shop-Verarbeitung) geprueft: schlaegt die Pruefung fehl,
|
||||||
|
* wird das POST-Feld "abonnieren" entfernt, sodass JTL-Shop die Anmeldung erst gar nicht verarbeitet.
|
||||||
|
* Der Hook-Handler unten ist eine zusaetzliche Absicherung ("defense in depth"), falls dieser fruehe
|
||||||
|
* Filter aus irgendeinem Grund nicht greift.
|
||||||
|
*/
|
||||||
|
class ValidationHandler
|
||||||
|
{
|
||||||
|
private AltchaService $altchaService;
|
||||||
|
|
||||||
|
public function __construct(AltchaService $altchaService)
|
||||||
|
{
|
||||||
|
$this->altchaService = $altchaService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $args
|
||||||
|
*/
|
||||||
|
public function checkRegistrationPlausibility(array $args): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->altchaService->isEnabledForRegistration()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->altchaService->verifyPost()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($args['fehlendeAngaben']) && \is_array($args['fehlendeAngaben'])) {
|
||||||
|
$args['fehlendeAngaben'][] = 'Sicherheitspruefung';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\array_key_exists('nReturnValue', $args)) {
|
||||||
|
$args['nReturnValue'] = 0;
|
||||||
|
}
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
// Bewusste Entscheidung: bei einem unerwarteten Fehler (z. B. Plugin nicht vollstaendig
|
||||||
|
// konfiguriert) lieber die Registrierung durchlassen, als die komplette Registrierungs-
|
||||||
|
// seite fuer echte Kunden zu blockieren. Ein Bot mehr ist besser als ein Shop, bei dem
|
||||||
|
// sich niemand mehr registrieren kann.
|
||||||
|
if ($this->altchaService->isDebug()) {
|
||||||
|
error_log('[fp_altcha_spamschutz] Fehler bei Registrierungspruefung: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fruehe Pruefung fuer die Newsletter-Anmeldung. Wird direkt aus Bootstrap::boot() aufgerufen,
|
||||||
|
* nicht ueber einen Hook, damit sie garantiert vor der Verarbeitung durch newsletter.php laeuft.
|
||||||
|
*/
|
||||||
|
public function guardNewsletterSubmission(): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->altchaService->isEnabledForNewsletter()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$isNewsletterSubscribeSubmit = ($_SERVER['REQUEST_METHOD'] ?? '') === 'POST'
|
||||||
|
&& isset($_POST['abonnieren']);
|
||||||
|
|
||||||
|
if (!$isNewsletterSubscribeSubmit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->altchaService->verifyPost()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Feld entfernen, damit JTL-Shop die Anmeldung nicht als "abonnieren"-Request erkennt
|
||||||
|
// und stattdessen nur das (leere) Formular erneut anzeigt.
|
||||||
|
unset($_POST['abonnieren']);
|
||||||
|
$_SESSION['fp_altcha_newsletter_error'] = true;
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
// Wird direkt in Bootstrap::boot() aufgerufen (nicht ueber einen Hook) -- ein
|
||||||
|
// Fehler hier darf auf keinen Fall den kompletten Seitenaufbau verhindern.
|
||||||
|
if ($this->altchaService->isDebug()) {
|
||||||
|
error_log('[fp_altcha_spamschutz] Fehler bei Newsletter-Fruehpruefung: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zusaetzliche Absicherung ueber HOOK_NEWSLETTER_PAGE_EMPFAENGEREINTRAGEN, falls die fruehe
|
||||||
|
* Pruefung in guardNewsletterSubmission() aus irgendeinem Grund nicht gegriffen hat.
|
||||||
|
*
|
||||||
|
* @param array<string, mixed> $args Enthaelt 'oNewsletterEmpfaenger' (stdClass, per Referenz).
|
||||||
|
*/
|
||||||
|
public function checkNewsletterRecipient(array $args): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$this->altchaService->isEnabledForNewsletter()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($_SESSION['fp_altcha_newsletter_error'])) {
|
||||||
|
// Bereits in guardNewsletterSubmission() als ungueltig erkannt: Empfaenger-E-Mail
|
||||||
|
// leeren, damit JTL-Shops eigene Pflichtfeld-Pruefung den Insert verhindert.
|
||||||
|
if (isset($args['oNewsletterEmpfaenger']) && \is_object($args['oNewsletterEmpfaenger'])) {
|
||||||
|
$args['oNewsletterEmpfaenger']->cEmail = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
if ($this->altchaService->isDebug()) {
|
||||||
|
error_log('[fp_altcha_spamschutz] Fehler bei Newsletter-Absicherung: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user