$value ) { if ( 'http_dnt' === strtolower( $name ) && 1 === (int) $value ) { return true; } } return false; } /** * Maps view_stats cap to read cap as needed. * * @access public * @param mixed $caps Caps. * @param mixed $cap Cap. * @param mixed $user_id User ID. * @return array Possibly mapped capabilities for meta capability. */ public static function map_meta_caps( $caps, $cap, $user_id ) { // Map view_stats to exists. if ( 'view_stats' === $cap ) { $user = new WP_User( $user_id ); $stats_roles = Options::get_option( 'roles' ); // Is any of the user's roles in the available stats roles? if ( is_array( $stats_roles ) && ! empty( array_intersect( $user->roles, $stats_roles ) ) ) { $caps = array( 'read' ); } } return $caps; } /** * Stats Template Redirect. * * @access public * @return void */ public static function template_redirect() { if ( ! self::should_track() ) { return; } add_action( 'wp_enqueue_scripts', array( Tracking_Pixel::class, 'enqueue_stats_script' ), 101 ); add_action( 'wp_footer', array( Tracking_Pixel::class, 'add_amp_pixel' ), 101 ); add_action( 'web_stories_print_analytics', array( Tracking_Pixel::class, 'add_amp_pixel' ), 101 ); } /** * CSS to hide the tracking pixel smiley. * It is now hidden for everyone (used to be visible if you had set the hide_smile option). * * @access public * @return void */ public static function hide_smile_css() { if ( ! self::should_track() ) { return; } wp_register_style( 'jetpack-stats', false, array(), Package_Version::PACKAGE_VERSION ); wp_enqueue_style( 'jetpack-stats' ); wp_add_inline_style( 'jetpack-stats', 'img#wpstats{display:none}' ); } /** * Whether we should add the tracking pixel. * * @return bool */ public static function should_track() { global $current_user; // Not connected sites should not generate tracking stats. if ( ! ( new Connection_Manager() )->is_connected() ) { return false; } // If the stats module is disabled we should not generate tracking stats. if ( ! ( new Modules() )->is_active( 'stats' ) ) { return false; } // Do not generate tracking stats for feeds, robots, embeds, previews // or to honour the DNT headers. if ( is_feed() || is_robots() || is_embed() || is_trackback() || is_preview() || self::jetpack_is_dnt_enabled() ) { return false; } // Sites in Safe Mode should not generate tracking stats. $status = new Status(); if ( $status->in_safe_mode() ) { return false; } // Should we be counting this user's views? if ( ! empty( $current_user->ID ) ) { $count_roles = Options::get_option( 'count_roles' ); if ( ! is_array( $count_roles ) || ! array_intersect( $current_user->roles, $count_roles ) ) { return false; } } /** * Allow excluding specific IP addresses from being tracked in Stats. * Note: for this to work well, visitors' IP addresses must: * - be stored and returned properly in IP address headers; * - not be impacted by any caching setup on your site. * * @module stats * * @since-jetpack 10.6 * * @param array $excluded_ips An array of IP address strings to exclude from tracking. */ $excluded_ips = (array) apply_filters( 'jetpack_stats_excluded_ips', array() ); /* * Visitor::get_ip() returns a normalized address, so normalize the configured list the * same way before comparing. Without this an entry written as `::ffff:203.0.113.5` or * with uppercase IPv6 hex would never match, and the site owner's traffic would be * counted with no indication why. Non-strings are dropped: they could never match the * string get_ip() returns under the strict comparison below. */ $excluded_ips = array_filter( array_map( array( IP_Utils::class, 'clean_ip' ), array_filter( $excluded_ips, 'is_string' ) ) ); /* * Resolving the visitor address reads request headers and, on a site with brute force * protection configured, a site option, so only do it when the normalized list still * holds something to compare against. The filter is unset on almost every site, which * makes this the common path. */ if ( ! empty( $excluded_ips ) ) { // Should we be counting views for this IP address? $current_user_ip = ( new Visitor() )->get_ip( true ); if ( in_array( $current_user_ip, $excluded_ips, true ) ) { return false; } } return true; } }