time() + self::TTL, 'path' => COOKIEPATH ? COOKIEPATH : '/', 'domain' => COOKIE_DOMAIN, 'secure' => is_ssl(), 'httponly' => true, 'samesite' => 'Lax', ]); } return self::$id; } public static function is_returning() { $existing = isset($_COOKIE[self::COOKIE]) ? sanitize_key(wp_unslash($_COOKIE[self::COOKIE])) : ''; return (bool) preg_match('/^[a-f0-9]{32}$/', $existing); } public static function store(array $verdict) { set_transient(self::key(self::id()), $verdict, self::TTL); } public static function verdict() { if (!self::is_returning()) { return null; } $stored = get_transient(self::key(self::id())); return is_array($stored) ? $stored : null; } public static function hash_ip($ip = null) { $ip = $ip ?? (isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : ''); return hash_hmac('sha256', $ip, self::daily_salt()); } private static function daily_salt() { $today = gmdate('Y-m-d'); $stored = get_option('adghost_ivt_salt', []); if (is_array($stored) && ($stored['date'] ?? '') === $today && !empty($stored['salt'])) { return $stored['salt']; } $salt = wp_generate_password(64, true, true); update_option('adghost_ivt_salt', ['date' => $today, 'salt' => $salt], false); return $salt; } private static function key($id) { return 'adghost_ivt_' . $id; } public static function forget() { if (self::is_returning()) { delete_transient(self::key(self::id())); } } }