' . '' . esc_html__( 'Leave this field empty', 'double-opt-in' ) . ' ' . '' . ''; } /** * `.` — the signature keeps a bot from sending a * made-up, old enough time. */ public static function stamp( int $time ): string { return $time . '.' . self::sign( $time ); } /** * Why a submission is a bot, or '' when it passes. * * @param array $post Raw request fields. * @param int $now Current time. * @param int $minSeconds Minimum time between render and submit. * * @return string '' | 'honeypot' | 'stamp_invalid' | 'too_fast' */ public static function check( array $post, int $now, int $minSeconds ): string { if ( isset( $post[ self::HONEYPOT ] ) && ( ! is_string( $post[ self::HONEYPOT ] ) || trim( $post[ self::HONEYPOT ] ) !== '' ) ) { return 'honeypot'; } if ( ! isset( $post[ self::STAMP ] ) ) { return ''; } $stamp = is_string( $post[ self::STAMP ] ) ? $post[ self::STAMP ] : ''; if ( ! preg_match( '/^(\d{9,11})\.([a-f0-9]{16})$/', $stamp, $m ) ) { return 'stamp_invalid'; } $time = (int) $m[1]; if ( ! hash_equals( self::sign( $time ), $m[2] ) || $time > $now + 60 ) { return 'stamp_invalid'; } return $now - $time < $minSeconds ? 'too_fast' : ''; } private static function sign( int $time ): string { return substr( wp_hash( 'f12_doi_submission_trap|' . $time ), 0, 16 ); } }