TemplateHandler.php hinzufuegen
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Plugin\fp_altcha_spamschutz\src\Handler;
|
||||
|
||||
use JTL\phpQuery\phpQueryObject;
|
||||
use JTL\Plugin\PluginInterface;
|
||||
use JTL\Smarty\JTLSmarty;
|
||||
use Plugin\fp_altcha_spamschutz\src\Service\AltchaService;
|
||||
|
||||
/**
|
||||
* Fuegt das ALTCHA-Widget (Container + Skript) in Registrierungs- und Newsletter-Formular ein.
|
||||
* Wird ueber HOOK_SMARTY_OUTPUTFILTER aufgerufen, also nach dem Rendern der Seite, auf dem
|
||||
* fertigen HTML-Dokument (phpQuery, jQuery-aehnliche PHP-DOM-API).
|
||||
*/
|
||||
class TemplateHandler
|
||||
{
|
||||
private PluginInterface $plugin;
|
||||
private AltchaService $altchaService;
|
||||
|
||||
public function __construct(PluginInterface $plugin, AltchaService $altchaService)
|
||||
{
|
||||
$this->plugin = $plugin;
|
||||
$this->altchaService = $altchaService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $args Enthaelt 'smarty' (JTLSmarty) und 'document' (phpQueryObject).
|
||||
*/
|
||||
public function generalTemplateIntegration(array $args): void
|
||||
{
|
||||
// WICHTIG: Dieser Hook laeuft bei JEDEM Seitenaufruf im gesamten Shop. Ein Fehler hier
|
||||
// darf niemals die Anzeige irgendeiner Shop-Seite verhindern -- deshalb komplett
|
||||
// defensiv mit try/catch umschlossen. Im Zweifel wird einfach kein Widget angezeigt,
|
||||
// statt die Seite kaputt zu machen.
|
||||
try {
|
||||
$this->doTemplateIntegration($args);
|
||||
} catch (\Throwable $e) {
|
||||
if ($this->altchaService->isDebug()) {
|
||||
error_log('[fp_altcha_spamschutz] Fehler bei Template-Integration: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $args
|
||||
*/
|
||||
private function doTemplateIntegration(array $args): void
|
||||
{
|
||||
/** @var phpQueryObject $document */
|
||||
$document = $args['document'];
|
||||
|
||||
$injected = false;
|
||||
|
||||
if ($this->altchaService->isEnabledForRegistration()) {
|
||||
$registerForm = $document->find('form.register-form');
|
||||
if (\count($registerForm) > 0) {
|
||||
$this->injectWidget($document, $registerForm);
|
||||
$injected = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->altchaService->isEnabledForNewsletter()) {
|
||||
$newsletterForm = $document->find('input[name="abonnieren"]')->closest('form');
|
||||
if (\count($newsletterForm) > 0) {
|
||||
$this->injectWidget($document, $newsletterForm);
|
||||
$injected = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($injected) {
|
||||
$this->includeScript($document);
|
||||
}
|
||||
}
|
||||
|
||||
private function injectWidget(phpQueryObject $document, phpQueryObject $form): void
|
||||
{
|
||||
// Nicht doppelt einfuegen (z. B. wenn die Seite mehrfach gefiltert wird).
|
||||
if (\count($form->find('.fp-altcha')) > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$challenge = $this->altchaService->createChallengeArray();
|
||||
$challengeJson = htmlspecialchars(
|
||||
(string) json_encode($challenge, \JSON_UNESCAPED_SLASHES),
|
||||
\ENT_QUOTES,
|
||||
'UTF-8'
|
||||
);
|
||||
|
||||
$isGerman = empty($_SESSION['cISOSprache']) || $_SESSION['cISOSprache'] === 'ger';
|
||||
$labelPreparing = $isGerman ? 'Sicherheitsprüfung wird vorbereitet …' : 'Preparing security check …';
|
||||
$labelPreparing = htmlspecialchars($labelPreparing, \ENT_QUOTES, 'UTF-8');
|
||||
|
||||
$html = '<div class="fp-altcha form-group" data-fp-altcha="' . $challengeJson . '">'
|
||||
. '<span class="fp-altcha-status text-muted small"><i class="fa fa-shield" aria-hidden="true"></i> '
|
||||
. $labelPreparing . '</span>'
|
||||
. '<input type="hidden" name="altcha" class="fp-altcha-input" value="">'
|
||||
. '</div>';
|
||||
|
||||
// Direkt vor dem Absende-Button einfuegen.
|
||||
$submitButton = $form->find('button[type="submit"], input[type="submit"]');
|
||||
if (\count($submitButton) > 0) {
|
||||
$submitButton->first()->before($html);
|
||||
} else {
|
||||
$form->append($html);
|
||||
}
|
||||
}
|
||||
|
||||
private function includeScript(phpQueryObject $document): void
|
||||
{
|
||||
if (\count($document->find('script[data-fp-altcha-script]')) > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bewusst analog zum bewaehrten Muster anderer JTL5-Plugins (z. B. Endereco) direkt ueber
|
||||
// die globale URL_SHOP-Konstante aufgebaut, statt eine Plugin-Pfad-API zu erraten.
|
||||
$assetUrl = \URL_SHOP . '/plugins/fp_altcha_spamschutz/assets/fp-altcha.js';
|
||||
$assetUrl = htmlspecialchars($assetUrl, \ENT_QUOTES, 'UTF-8');
|
||||
|
||||
$document->find('body')->append(
|
||||
'<script data-fp-altcha-script defer src="' . $assetUrl . '"></script>'
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user