$headers Headers the request already sends. * @return array */ public static function headers( array $headers = array() ): array { $headers[ self::HEADER ] = '1'; return $headers; } /** * The fragments, filterable so an add-on can name its own requests. * * @return string[] */ public static function agents(): array { /** * Filter the user-agent fragments that mark a request as xSpeed's own, * so analytics plugins don't count it as a visitor. * * @param string[] $agents Case-insensitive substrings, longer than 3 characters. */ $agents = function_exists( 'apply_filters' ) ? apply_filters( 'xspeed_self_user_agents', self::AGENTS ) : self::AGENTS; if ( ! is_array( $agents ) ) { return array(); } // WP Statistics ignores fragments of 3 characters or fewer, and so // does every other consumer, so the paths agree on what matches. $agents = array_filter( array_map( static fn ( $agent ): string => trim( (string) $agent ), $agents ), static fn ( string $agent ): bool => strlen( $agent ) > 3 ); return array_values( $agents ); } /** Is this user agent one of ours? */ public static function is_self( string $ua ): bool { if ( '' === $ua ) { return false; } foreach ( self::agents() as $fragment ) { if ( false !== stripos( $ua, $fragment ) ) { return true; } } return false; } /** Does the current request carry the marker header? */ public static function request_is_marked(): bool { return isset( $_SERVER[ self::SERVER_KEY ] ) && '' !== $_SERVER[ self::SERVER_KEY ]; } /** Is the current request one of ours, by header or by user agent? */ public static function is_self_request(): bool { return self::request_is_marked() || self::is_self( self::request_ua() ); } /** The current request's user agent, sanitised. */ private static function request_ua(): string { return isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( (string) $_SERVER['HTTP_USER_AGENT'] ) ) : ''; } /** * WP Statistics: add our fragments to its robot list, which it matches * by substring. It has no hook that sees request headers, so a marked * request whose UA is not one of ours (a renamed warmer, a probe) gets * its own UA added, for this request only. A real visitor on the same * browser doesn't carry the header and is still counted. * * @param mixed $robots The list so far. * @return mixed */ public static function add_to_robot_list( $robots ) { if ( ! is_array( $robots ) ) { return $robots; } $robots = array_merge( $robots, self::agents() ); $ua = self::request_ua(); if ( self::request_is_marked() && strlen( $ua ) > 3 && ! self::is_self( $ua ) ) { $robots[] = $ua; } return $robots; } /** * Slimstat: an empty stat aborts the pageview (its error e-302). * * @param mixed $stat The pageview being recorded. * @return mixed */ public static function drop_slimstat_hit( $stat ) { return self::is_self_request() ? array() : $stat; } }