diff --git a/fp_altcha_spamschutz/src/Handler/TemplateHandler.php b/fp_altcha_spamschutz/src/Handler/TemplateHandler.php new file mode 100644 index 0000000..4c492fa --- /dev/null +++ b/fp_altcha_spamschutz/src/Handler/TemplateHandler.php @@ -0,0 +1,125 @@ +plugin = $plugin; + $this->altchaService = $altchaService; + } + + /** + * @param array $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 $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 = '
' + . ' ' + . $labelPreparing . '' + . '' + . '
'; + + // 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( + '' + ); + } +}