PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
← All changes | jetpack_vendor/automattic/jetpack-stats/src/class-main.php +59 -18 13.3.3 → 16.3-beta View file →
@@ -8,9 +8,11 @@
8 8 namespace Automattic\Jetpack\Stats;
9 9
10 10 use Automattic\Jetpack\Connection\Manager as Connection_Manager;
11 11 use Automattic\Jetpack\Constants;
12 +use Automattic\Jetpack\IP\Utils as IP_Utils;
12 13 use Automattic\Jetpack\Modules;
14 +use Automattic\Jetpack\Stats\Abilities\Stats_Abilities;
13 15 use Automattic\Jetpack\Status;
14 16 use Automattic\Jetpack\Status\Visitor;
15 17 use WP_User;
16 18
@@ -67,19 +69,42 @@
67 69 }
68 70 // Generate the tracking code after wp() has queried for posts.
69 71 add_action( 'template_redirect', array( __CLASS__, 'template_redirect' ), 1 );
70 72
71 - add_action( 'wp_head', array( __CLASS__, 'hide_smile_css' ) );
72 - add_action( 'embed_head', array( __CLASS__, 'hide_smile_css' ) );
73 + add_action( 'wp_enqueue_scripts', array( __CLASS__, 'hide_smile_css' ) );
73 74
74 75 // Map stats caps.
75 76 add_filter( 'map_meta_cap', array( __CLASS__, 'map_meta_caps' ), 10, 3 );
76 77
77 78 XMLRPC_Provider::init();
78 - REST_Provider::init();
79 79
80 + /*
81 + * REST_Provider only registers its routes on REST init, so defer
82 + * constructing it (and autoloading the class) until a REST request is
83 + * served. A closure is used because rest_api_init passes the REST server
84 + * to callbacks, which would otherwise be read as REST_Provider::init()'s
85 + * $new_instance argument.
86 + */
87 + add_action(
88 + 'rest_api_init',
89 + static function () {
90 + REST_Provider::init();
91 + },
92 + 0
93 + );
94 + Transient_Cleanup::init();
95 +
96 + // Clean up transient cron on module deactivation.
97 + add_action( 'jetpack_deactivate_module_stats', array( Transient_Cleanup::class, 'unschedule_cleanup' ) );
98 +
80 99 // Set up package version hook.
81 100 add_filter( 'jetpack_package_versions', __NAMESPACE__ . '\Package_Version::send_package_version_to_tracker' );
101 +
102 + // Register WP Abilities API surface. Gated behind the
103 + // `jetpack_wp_abilities_enabled` filter inside Registrar::init(),
104 + // which defaults to false — so this call is safe to make unconditionally
105 + // and still opt-in per-site until the flag is flipped.
106 + Stats_Abilities::init();
82 107 }
83 108
84 109 /**
85 110 * Checks if filter is set and dnt is enabled.
@@ -120,13 +145,12 @@
120 145 public static function map_meta_caps( $caps, $cap, $user_id ) {
121 146 // Map view_stats to exists.
122 147 if ( 'view_stats' === $cap ) {
123 148 $user = new WP_User( $user_id );
124 - $user_role = array_shift( $user->roles );
125 149 $stats_roles = Options::get_option( 'roles' );
126 150
127 - // Is the users role in the available stats roles?
128 - if ( is_array( $stats_roles ) && in_array( $user_role, $stats_roles, true ) ) {
151 + // Is any of the user's roles in the available stats roles?
152 + if ( is_array( $stats_roles ) && ! empty( array_intersect( $user->roles, $stats_roles ) ) ) {
129 153 $caps = array( 'read' );
130 154 }
131 155 }
132 156
@@ -159,11 +183,12 @@
159 183 public static function hide_smile_css() {
160 184 if ( ! self::should_track() ) {
161 185 return;
162 186 }
163 - ?>
164 - <style>img#wpstats{display:none}</style>
165 - <?php
187 +
188 + wp_register_style( 'jetpack-stats', false, array(), Package_Version::PACKAGE_VERSION );
189 + wp_enqueue_style( 'jetpack-stats' );
190 + wp_add_inline_style( 'jetpack-stats', 'img#wpstats{display:none}' );
166 191 }
167 192
168 193 /**
169 194 * Whether we should add the tracking pixel.
@@ -195,11 +220,11 @@
195 220 ) {
196 221 return false;
197 222 }
198 223
199 - // Staging Sites should not generate tracking stats.
224 + // Sites in Safe Mode should not generate tracking stats.
200 225 $status = new Status();
201 - if ( $status->is_staging_site() ) {
226 + if ( $status->in_safe_mode() ) {
202 227 return false;
203 228 }
204 229
205 230 // Should we be counting this user's views?
@@ -223,15 +248,31 @@
223 248 * @param array $excluded_ips An array of IP address strings to exclude from tracking.
224 249 */
225 250 $excluded_ips = (array) apply_filters( 'jetpack_stats_excluded_ips', array() );
226 251
227 - // Should we be counting views for this IP address?
228 - $current_user_ip = ( new Visitor() )->get_ip( true );
229 - if (
230 - ! empty( $excluded_ips )
231 - && in_array( $current_user_ip, $excluded_ips, true )
232 - ) {
233 - return false;
252 + /*
253 + * Visitor::get_ip() returns a normalized address, so normalize the configured list the
254 + * same way before comparing. Without this an entry written as `::ffff:203.0.113.5` or
255 + * with uppercase IPv6 hex would never match, and the site owner's traffic would be
256 + * counted with no indication why. Non-strings are dropped: they could never match the
257 + * string get_ip() returns under the strict comparison below.
258 + */
259 + $excluded_ips = array_filter(
260 + array_map( array( IP_Utils::class, 'clean_ip' ), array_filter( $excluded_ips, 'is_string' ) )
261 + );
262 +
263 + /*
264 + * Resolving the visitor address reads request headers and, on a site with brute force
265 + * protection configured, a site option, so only do it when the normalized list still
266 + * holds something to compare against. The filter is unset on almost every site, which
267 + * makes this the common path.
268 + */
269 + if ( ! empty( $excluded_ips ) ) {
270 + // Should we be counting views for this IP address?
271 + $current_user_ip = ( new Visitor() )->get_ip( true );
272 + if ( in_array( $current_user_ip, $excluded_ips, true ) ) {
273 + return false;
274 + }
234 275 }
235 276
236 277 return true;
237 278 }