PluginProbe ʕ •ᴥ•ʔ
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 27.5
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v27.5
27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 19.1 19.10 19.11 19.12 19.13 19.14 19.2 19.3 19.4 19.5 19.5.1 19.6 19.6.1 19.7 19.7.1 19.7.2 19.8 19.9 20.0 20.1 20.10 20.11 20.12 20.13 20.2 20.2.1 20.3 20.4 20.5 20.6 20.7 20.8 20.9 21.0 21.1 21.2 21.3 21.4 21.5 21.6 21.7 21.8 21.8.1 21.9 21.9.1 22.0 22.1 22.2 22.3 22.4 22.5 22.6 22.7 22.8 22.9 23.0 23.1 23.2 23.3 23.4 23.5 23.6 23.7 23.8 23.9 24.0 24.1 24.2 24.3 24.4 24.5 24.6 24.7 24.8 24.8.1 24.9 25.0 25.1 25.2 25.3 25.3.1 25.4 25.5 25.6 25.7 25.8 25.9 26.0 26.1 26.1.1 26.2 26.3 26.4 26.5 26.6 26.7 26.8 26.9 27.0 27.1 27.1.1 27.2 27.3 27.4
wordpress-seo / admin / tracking / class-tracking.php
wordpress-seo / admin / tracking Last commit date
class-tracking-addon-data.php 2 years ago class-tracking-default-data.php 3 years ago class-tracking-plugin-data.php 2 years ago class-tracking-server-data.php 3 years ago class-tracking-settings-data.php 3 months ago class-tracking-theme-data.php 4 years ago class-tracking.php 1 year ago
class-tracking.php
241 lines
1 <?php
2 /**
3 * WPSEO plugin file.
4 *
5 * @package WPSEO\Admin\Tracking
6 */
7
8 use Yoast\WP\SEO\Analytics\Application\Missing_Indexables_Collector;
9 use Yoast\WP\SEO\Analytics\Application\To_Be_Cleaned_Indexables_Collector;
10
11 /**
12 * This class handles the tracking routine.
13 */
14 class WPSEO_Tracking implements WPSEO_WordPress_Integration {
15
16 /**
17 * The tracking option name.
18 *
19 * @var string
20 */
21 protected $option_name = 'wpseo_tracking_last_request';
22
23 /**
24 * The limit for the option.
25 *
26 * @var int
27 */
28 protected $threshold = 0;
29
30 /**
31 * The endpoint to send the data to.
32 *
33 * @var string
34 */
35 protected $endpoint = '';
36
37 /**
38 * The current time.
39 *
40 * @var int
41 */
42 private $current_time;
43
44 /**
45 * WPSEO_Tracking constructor.
46 *
47 * @param string $endpoint The endpoint to send the data to.
48 * @param int $threshold The limit for the option.
49 */
50 public function __construct( $endpoint, $threshold ) {
51 if ( ! $this->tracking_enabled() ) {
52 return;
53 }
54
55 $this->endpoint = $endpoint;
56 $this->threshold = $threshold;
57 $this->current_time = time();
58 }
59
60 /**
61 * Registers all hooks to WordPress.
62 *
63 * @return void
64 */
65 public function register_hooks() {
66 if ( ! $this->tracking_enabled() ) {
67 return;
68 }
69
70 // Send tracking data on `admin_init`.
71 add_action( 'admin_init', [ $this, 'send' ], 1 );
72
73 // Add an action hook that will be triggered at the specified time by `wp_schedule_single_event()`.
74 add_action( 'wpseo_send_tracking_data_after_core_update', [ $this, 'send' ] );
75 // Call `wp_schedule_single_event()` after a WordPress core update.
76 add_action( 'upgrader_process_complete', [ $this, 'schedule_tracking_data_sending' ], 10, 2 );
77 }
78
79 /**
80 * Schedules a new sending of the tracking data after a WordPress core update.
81 *
82 * @param bool|WP_Upgrader $upgrader Optional. WP_Upgrader instance or false.
83 * Depending on context, it might be a Theme_Upgrader,
84 * Plugin_Upgrader, Core_Upgrade, or Language_Pack_Upgrader.
85 * instance. Default false.
86 * @param array $data Array of update data.
87 *
88 * @return void
89 */
90 public function schedule_tracking_data_sending( $upgrader = false, $data = [] ) {
91 // Return if it's not a WordPress core update.
92 if ( ! $upgrader || ! isset( $data['type'] ) || $data['type'] !== 'core' ) {
93 return;
94 }
95
96 /*
97 * To uniquely identify the scheduled cron event, `wp_next_scheduled()`
98 * needs to receive the same arguments as those used when originally
99 * scheduling the event otherwise it will always return false.
100 */
101 if ( ! wp_next_scheduled( 'wpseo_send_tracking_data_after_core_update', [ true ] ) ) {
102 /*
103 * Schedule sending of data tracking 6 hours after a WordPress core
104 * update. Pass a `true` parameter for the callback `$force` argument.
105 */
106 wp_schedule_single_event( ( time() + ( HOUR_IN_SECONDS * 6 ) ), 'wpseo_send_tracking_data_after_core_update', [ true ] );
107 }
108 }
109
110 /**
111 * Sends the tracking data.
112 *
113 * @param bool $force Whether to send the tracking data ignoring the two
114 * weeks time threshold. Default false.
115 *
116 * @return void
117 */
118 public function send( $force = false ) {
119 if ( ! $this->should_send_tracking( $force ) ) {
120 return;
121 }
122
123 // Set a 'content-type' header of 'application/json'.
124 $tracking_request_args = [
125 'headers' => [
126 'content-type:' => 'application/json',
127 ],
128 ];
129
130 $collector = $this->get_collector();
131
132 $request = new WPSEO_Remote_Request( $this->endpoint, $tracking_request_args );
133 $request->set_body( $collector->get_as_json() );
134 $request->send();
135
136 update_option( $this->option_name, $this->current_time, 'yes' );
137 }
138
139 /**
140 * Determines whether to send the tracking data.
141 *
142 * Returns false if tracking is disabled or the current page is one of the
143 * admin plugins pages. Returns true when there's no tracking data stored or
144 * the data was sent more than two weeks ago. The two weeks interval is set
145 * when instantiating the class.
146 *
147 * @param bool $ignore_time_treshhold Whether to send the tracking data ignoring
148 * the two weeks time treshhold. Default false.
149 *
150 * @return bool True when tracking data should be sent.
151 */
152 protected function should_send_tracking( $ignore_time_treshhold = false ) {
153 global $pagenow;
154
155 // Only send tracking on the main site of a multi-site instance. This returns true on non-multisite installs.
156 if ( is_network_admin() || ! is_main_site() ) {
157 return false;
158 }
159
160 // Because we don't want to possibly block plugin actions with our routines.
161 if ( in_array( $pagenow, [ 'plugins.php', 'plugin-install.php', 'plugin-editor.php' ], true ) ) {
162 return false;
163 }
164
165 $last_time = get_option( $this->option_name );
166
167 // When tracking data haven't been sent yet or when sending data is forced.
168 if ( ! $last_time || $ignore_time_treshhold ) {
169 return true;
170 }
171
172 return $this->exceeds_treshhold( $this->current_time - $last_time );
173 }
174
175 /**
176 * Checks if the given amount of seconds exceeds the set threshold.
177 *
178 * @param int $seconds The amount of seconds to check.
179 *
180 * @return bool True when seconds is bigger than threshold.
181 */
182 protected function exceeds_treshhold( $seconds ) {
183 return ( $seconds > $this->threshold );
184 }
185
186 /**
187 * Returns the collector for collecting the data.
188 *
189 * @return WPSEO_Collector The instance of the collector.
190 */
191 public function get_collector() {
192 $collector = new WPSEO_Collector();
193 $collector->add_collection( new WPSEO_Tracking_Default_Data() );
194 $collector->add_collection( new WPSEO_Tracking_Server_Data() );
195 $collector->add_collection( new WPSEO_Tracking_Theme_Data() );
196 $collector->add_collection( new WPSEO_Tracking_Plugin_Data() );
197 $collector->add_collection( new WPSEO_Tracking_Settings_Data() );
198 $collector->add_collection( new WPSEO_Tracking_Addon_Data() );
199 $collector->add_collection( YoastSEO()->classes->get( Missing_Indexables_Collector::class ) );
200 $collector->add_collection( YoastSEO()->classes->get( To_Be_Cleaned_Indexables_Collector::class ) );
201
202 return $collector;
203 }
204
205 /**
206 * See if we should run tracking at all.
207 *
208 * @return bool True when we can track, false when we can't.
209 */
210 private function tracking_enabled() {
211 // Check if we're allowing tracking.
212 $tracking = WPSEO_Options::get( 'tracking' );
213
214 if ( $tracking === false ) {
215 return false;
216 }
217
218 // Save this state.
219 if ( $tracking === null ) {
220 /**
221 * Filter: 'wpseo_enable_tracking' - Enables the data tracking of Yoast SEO Premium and add-ons.
222 *
223 * @param string|false $is_enabled The enabled state. Default is false.
224 */
225 $tracking = apply_filters( 'wpseo_enable_tracking', false );
226
227 WPSEO_Options::set( 'tracking', $tracking );
228 }
229
230 if ( $tracking === false ) {
231 return false;
232 }
233
234 if ( ! YoastSEO()->helpers->environment->is_production_mode() ) {
235 return false;
236 }
237
238 return true;
239 }
240 }
241