token_service = $token_service; } /** * Render hidden protection fields. * * @param string $form_id Generic form identifier. * @param int|null $issued_at Issued timestamp. */ public function render_fields( string $form_id, ?int $issued_at = null ): string { $issued_at = null === $issued_at ? time() : max( 1, $issued_at ); $token = $this->token_service->create_token( $form_id, $issued_at ); $this->enqueue_asset(); return "\n" . '' . "\n" . '' . "\n" . '' . "\n"; } /** * Enqueue the tiny local token helper only when fields are rendered. */ private function enqueue_asset(): void { if ( ! function_exists( 'wp_register_script' ) || ! function_exists( 'wp_enqueue_script' ) || ! defined( 'TWOOTWOCODE_ZSF_URL' ) ) { return; } wp_register_script( self::SCRIPT_HANDLE, TWOOTWOCODE_ZSF_URL . 'assets/frontend/protection-token.js', array(), defined( 'TWOOTWOCODE_ZSF_VERSION' ) ? TWOOTWOCODE_ZSF_VERSION : '1.0.0', true ); wp_enqueue_script( self::SCRIPT_HANDLE ); } /** * Escape an attribute value with a safe fallback for unit tests. * * @param string $value Raw value. */ private function esc_attr( string $value ): string { if ( function_exists( 'esc_attr' ) ) { return esc_attr( $value ); } return htmlspecialchars( $value, ENT_QUOTES, 'UTF-8' ); } }