$cookies * @param list $roles */ public function __construct( public readonly bool $logged_in, public readonly array $roles, public readonly bool $mobile, public readonly string $referrer, public readonly string $user_agent, public readonly string $language, public readonly array $cookies, public readonly string $ip, public readonly string $country, public readonly ?bool $not_found = null ) {} public static function current( ?bool $not_found = null ): self { $user = wp_get_current_user(); // phpcs:disable WordPress.Security.ValidatedSanitizedInput -- read-only comparisons, never output or stored. $server = static fn( string $key ): string => isset( $_SERVER[ $key ] ) ? (string) wp_unslash( $_SERVER[ $key ] ) : ''; $cookies = []; foreach ( $_COOKIE as $name => $value ) { if ( is_string( $value ) ) { $cookies[ (string) $name ] = wp_unslash( $value ); } } // phpcs:enable return new self( logged_in: $user->exists(), roles: array_values( (array) $user->roles ), mobile: wp_is_mobile(), referrer: $server( 'HTTP_REFERER' ), user_agent: $server( 'HTTP_USER_AGENT' ), language: $server( 'HTTP_ACCEPT_LANGUAGE' ), cookies: $cookies, ip: $server( 'REMOTE_ADDR' ), country: self::country( $server ), not_found: $not_found ); } /** * The country, from whatever the hosting in front of the site says. * * No lookup database is shipped: they are large, they go stale, and the CDN in front * of most sites has already done the lookup and is offering the answer in a header. * Without one of those this is blank and a country condition never matches, which the * settings screen says. */ private static function country( callable $server ): string { $country = ''; foreach ( [ 'HTTP_CF_IPCOUNTRY', 'HTTP_CLOUDFRONT_VIEWER_COUNTRY', 'HTTP_X_COUNTRY_CODE', 'GEOIP_COUNTRY_CODE', 'HTTP_X_GEO_COUNTRY' ] as $header ) { $value = strtoupper( trim( (string) $server( $header ) ) ); if ( preg_match( '/^[A-Z]{2}$/', $value ) ) { $country = $value; break; } } /** * Filter the visitor's two-letter country code, for a site with its own lookup. * * @param string $country Empty when unknown. */ return strtoupper( (string) apply_filters( 'codebold_redirect_country', $country ) ); } /** * A copy with some answers changed, for the tester. * * @param array $overrides */ public function with( array $overrides ): self { $values = get_object_vars( $this ); foreach ( $overrides as $key => $value ) { if ( array_key_exists( $key, $values ) ) { $values[ $key ] = $value; } } return new self( ...$values ); } }