PluginProbe
Elementor Website Builder – more than just a page builder / 3.4.6
Elementor Website Builder – more than just a page builder v3.4.6
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
← All changes | includes/tracker.php +34 -147 4.2.03.4.6 View file →
@@ -1,9 +1,7 @@
1 1 <?php
2 2 namespace Elementor;
3 3
4 -use Elementor\Core\Common\Modules\EventTracker\DB as Events_DB_Manager;
5 -use Elementor\Core\Experiments\Experiments_Reporter;
6 4 use Elementor\Modules\System_Info\Module as System_Info_Module;
7 5
8 6 if ( ! defined( 'ABSPATH' ) ) {
9 7 exit; // Exit if accessed directly.
@@ -28,14 +26,12 @@
28 26 * @access private
29 27 *
30 28 * @var string API URL.
31 29 */
32 - private static $api_url = 'https://my.elementor.com/api/v1/tracker/';
30 + private static $_api_url = 'https://my.elementor.com/api/v1/tracker/';
33 31
34 32 private static $notice_shown = false;
35 33
36 - const LAST_TERMS_UPDATED = '2025-07-07';
37 -
38 34 /**
39 35 * Init.
40 36 *
41 37 * Initialize Elementor tracker.
@@ -46,10 +42,8 @@
46 42 */
47 43 public static function init() {
48 44 add_action( 'elementor/tracker/send_event', [ __CLASS__, 'send_tracking_data' ] );
49 45 add_action( 'admin_init', [ __CLASS__, 'handle_tracker_actions' ] );
50 -
51 - add_action( 'update_option_elementor_allow_tracking', [ __CLASS__, 'set_last_update_time' ] );
52 46 }
53 47
54 48 /**
55 49 * Check for settings opt-in.
@@ -66,20 +60,14 @@
66 60 */
67 61 public static function check_for_settings_optin( $new_value ) {
68 62 $old_value = get_option( 'elementor_allow_tracking', 'no' );
69 63 if ( $old_value !== $new_value && 'yes' === $new_value ) {
70 - Plugin::$instance->custom_tasks->add_tasks_requested_to_run( [
71 - 'opt_in_recalculate_usage',
72 - 'opt_in_send_tracking_data',
73 - ] );
64 + self::send_tracking_data( true );
74 65 }
75 66
76 - self::set_last_update_time();
77 -
78 67 if ( empty( $new_value ) ) {
79 68 $new_value = 'no';
80 69 }
81 -
82 70 return $new_value;
83 71 }
84 72
85 73 /**
@@ -133,10 +121,13 @@
133 121 // Send a maximum of once per week by default.
134 122 if ( $last_send && $last_send > $last_send_interval ) {
135 123 return;
136 124 }
137 - } elseif ( $last_send && $last_send > strtotime( '-1 hours' ) ) {
138 - return;
125 + } else {
126 + // Make sure there is at least a 1 hour delay between override sends, we dont want duplicate calls due to double clicking links.
127 + if ( $last_send && $last_send > strtotime( '-1 hours' ) ) {
128 + return;
129 + }
139 130 }
140 131
141 132 // Update time first before sending to ensure it is set.
142 133 update_option( 'elementor_tracker_last_send', time() );
@@ -142,27 +133,21 @@
142 133 update_option( 'elementor_tracker_last_send', time() );
143 134
144 135 $params = self::get_tracking_data( empty( $last_send ) );
145 136
146 - // Tracking data is used for System Info reports, and events should not be included in System Info reports,
147 - // so it is added here.
148 - $params['analytics_events'] = self::get_events();
149 -
150 137 add_filter( 'https_ssl_verify', '__return_false' );
151 138
152 139 wp_safe_remote_post(
153 - self::$api_url,
140 + self::$_api_url,
154 141 [
155 142 'timeout' => 25,
156 143 'blocking' => false,
144 + // 'sslverify' => false,
157 145 'body' => [
158 146 'data' => wp_json_encode( $params ),
159 147 ],
160 148 ]
161 149 );
162 -
163 - // After sending the event tracking data, we reset the events table.
164 - Events_DB_Manager::reset_table();
165 150 }
166 151
167 152 /**
168 153 * Is allow track.
@@ -176,31 +161,8 @@
176 161 public static function is_allow_track() {
177 162 return 'yes' === get_option( 'elementor_allow_tracking', 'no' );
178 163 }
179 164
180 - public static function get_last_update_time() {
181 - return get_option( 'elementor_allow_tracking_last_update', false );
182 - }
183 -
184 - public static function set_last_update_time(): void {
185 - update_option( 'elementor_allow_tracking_last_update', gmdate( 'U' ) );
186 - }
187 -
188 - public static function has_terms_changed( $terms_updated = self::LAST_TERMS_UPDATED ): bool {
189 - if ( ! self::is_allow_track() ) {
190 - return false;
191 - }
192 -
193 - $last_update_time = self::get_last_update_time();
194 - if ( $last_update_time ) {
195 - $terms_updated_timestamp = strtotime( $terms_updated . ' UTC' );
196 -
197 - return $last_update_time < $terms_updated_timestamp;
198 - }
199 -
200 - return true;
201 - }
202 -
203 165 /**
204 166 * Handle tracker actions.
205 167 *
206 168 * Check if the user opted-in or opted-out and update the database.
@@ -227,9 +189,9 @@
227 189
228 190 self::set_opt_in( false );
229 191 }
230 192
231 - wp_safe_redirect( remove_query_arg( 'elementor_tracker' ) );
193 + wp_redirect( remove_query_arg( 'elementor_tracker' ) );
232 194 exit;
233 195 }
234 196
235 197 /**
@@ -243,10 +205,8 @@
243 205
244 206 public static function set_opt_in( $value ) {
245 207 if ( $value ) {
246 208 update_option( 'elementor_allow_tracking', 'yes' );
247 - self::set_last_update_time();
248 -
249 209 self::send_tracking_data( true );
250 210 } else {
251 211 update_option( 'elementor_allow_tracking', 'no' );
252 212 update_option( 'elementor_tracker_notice', '1' );
@@ -266,17 +226,12 @@
266 226 */
267 227 private static function get_system_reports_data() {
268 228 $reports = Plugin::$instance->system_info->load_reports( System_Info_Module::get_allowed_reports() );
269 229
270 - // The log report should not be sent with the usage data - it is not used and causes bloat.
271 - if ( isset( $reports['log'] ) ) {
272 - unset( $reports['log'] );
273 - }
274 -
275 230 $system_reports = [];
276 231 foreach ( $reports as $report_key => $report_details ) {
277 232 $system_reports[ $report_key ] = [];
278 - foreach ( $report_details['report']->get_report() as $sub_report_key => $sub_report_details ) {
233 + foreach ( $report_details['report'] as $sub_report_key => $sub_report_details ) {
279 234 $system_reports[ $report_key ][ $sub_report_key ] = $sub_report_details['value'];
280 235 }
281 236 }
282 237 return $system_reports;
@@ -324,9 +279,8 @@
324 279 global $wpdb;
325 280
326 281 $usage = [];
327 282
328 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
329 283 $results = $wpdb->get_results(
330 284 "SELECT `post_type`, `post_status`, COUNT(`ID`) `hits`
331 285 FROM {$wpdb->posts} `p`
332 286 LEFT JOIN {$wpdb->postmeta} `pm` ON(`p`.`ID` = `pm`.`post_id` AND `meta_key` = '_elementor_edit_mode' )
@@ -359,9 +313,8 @@
359 313 global $wpdb;
360 314
361 315 $usage = [];
362 316
363 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
364 317 $results = $wpdb->get_results(
365 318 "SELECT `post_type`, `post_status`, COUNT(`ID`) `hits`
366 319 FROM {$wpdb->posts} `p`
367 320 LEFT JOIN {$wpdb->postmeta} `pm` ON(`p`.`ID` = `pm`.`post_id`)
@@ -371,9 +324,9 @@
371 324 );
372 325
373 326 if ( $results ) {
374 327 foreach ( $results as $result ) {
375 - $usage[ $result->post_type ][ $result->post_status ] = (int) $result->hits;
328 + $usage[ $result->post_type ][ $result->post_status ] = $result->hits;
376 329 }
377 330 }
378 331
379 332 return $usage;
@@ -395,9 +348,8 @@
395 348 global $wpdb;
396 349
397 350 $usage = [];
398 351
399 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
400 352 $results = $wpdb->get_results(
401 353 "SELECT `meta_value`, COUNT(`ID`) `hits`
402 354 FROM {$wpdb->posts} `p`
403 355 LEFT JOIN {$wpdb->postmeta} `pm` ON(`p`.`ID` = `pm`.`post_id`)
@@ -412,8 +364,9 @@
412 364 }
413 365 }
414 366
415 367 return $usage;
368 +
416 369 }
417 370
418 371 /**
419 372 * Get usage of general settings.
@@ -435,18 +388,8 @@
435 388 return self::get_tracking_data_from_settings( 'advanced' );
436 389 }
437 390
438 391 /**
439 - * Get usage of performance settings.
440 - * 'Elementor->Settings->Performance'.
441 - *
442 - * @return array
443 - */
444 - public static function get_settings_performance_usage() {
445 - return self::get_tracking_data_from_settings( 'performance' );
446 - }
447 -
448 - /**
449 392 * Get usage of experiments settings.
450 393 *
451 394 * 'Elementor->Settings->Experiments'.
452 395 *
@@ -452,18 +395,30 @@
452 395 *
453 396 * @return array
454 397 */
455 398 public static function get_settings_experiments_usage() {
456 - $system_info = Plugin::$instance->system_info;
399 + $result = [];
457 400
458 - /**
459 - * @var $experiments_report Experiments_Reporter
460 - */
461 - $experiments_report = $system_info->create_reporter( [
462 - 'class_name' => Experiments_Reporter::class,
463 - ] );
401 + $experiments_manager = Plugin::$instance->experiments;
464 402
465 - return $experiments_report->get_experiments()['value'];
403 + // TODO: Those keys should be at `$experiments_manager`.
404 + $tracking_keys = [
405 + 'default',
406 + 'state',
407 + ];
408 +
409 + foreach ( $experiments_manager->get_features() as $feature_name => $feature_data ) {
410 + $data_to_collect = [];
411 +
412 + // Extract only tracking keys.
413 + foreach ( $tracking_keys as $tracking_key ) {
414 + $data_to_collect[ $tracking_key ] = $feature_data[ $tracking_key ];
415 + }
416 +
417 + $result[ $feature_name ] = $data_to_collect;
418 + }
419 +
420 + return $result;
466 421 }
467 422
468 423 /**
469 424 * Get usage of general tools.
@@ -495,66 +450,8 @@
495 450 return self::get_tracking_data_from_tools( 'maintenance_mode' );
496 451 }
497 452
498 453 /**
499 - * Get library usage extend.
500 - *
501 - * Retrieve the number of Elementor library items saved.
502 - *
503 - * @return array The number of Elementor library items grouped by post types, post status
504 - * and meta value.
505 - */
506 - public static function get_library_usage_extend() {
507 - global $wpdb;
508 -
509 - $usage = [];
510 -
511 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
512 - $results = $wpdb->get_results(
513 - "SELECT `meta_value`, COUNT(`ID`) `hits`, `post_status`
514 - FROM {$wpdb->posts} `p`
515 - LEFT JOIN {$wpdb->postmeta} `pm` ON(`p`.`ID` = `pm`.`post_id`)
516 - WHERE `post_type` = 'elementor_library'
517 - AND `meta_key` = '_elementor_template_type'
518 - GROUP BY `post_type`, `meta_value`, `post_status`;"
519 - );
520 -
521 - if ( $results ) {
522 - foreach ( $results as $result ) {
523 - if ( empty( $usage[ $result->meta_value ] ) ) {
524 - $usage[ $result->meta_value ] = [];
525 - }
526 -
527 - if ( empty( $usage[ $result->meta_value ][ $result->post_status ] ) ) {
528 - $usage[ $result->meta_value ][ $result->post_status ] = 0;
529 - }
530 -
531 - $usage[ $result->meta_value ][ $result->post_status ] += $result->hits;
532 - }
533 - }
534 -
535 - return $usage;
536 - }
537 -
538 - public static function get_events() {
539 - global $wpdb;
540 - $table_name = $wpdb->prefix . Events_DB_Manager::TABLE_NAME;
541 -
542 - // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery
543 - $results = $wpdb->get_results( "SELECT event_data FROM {$table_name}" );
544 -
545 - $events_data = [];
546 -
547 - foreach ( $results as $event ) {
548 - // Results are stored in the database as a JSON string. Since all tracking data is encoded right before
549 - // being sent, it is now decoded.
550 - $events_data[] = json_decode( $event->event_data, true );
551 - }
552 -
553 - return $events_data;
554 - }
555 -
556 - /**
557 454 * Get the tracking data
558 455 *
559 456 * Retrieve tracking data and apply filter
560 457 *
@@ -583,24 +480,13 @@
583 480 'general' => self::get_tools_general_usage(),
584 481 'version' => self::get_tools_version_control_usage(),
585 482 'maintenance' => self::get_tools_maintenance_usage(),
586 483 ],
587 - 'library-details' => self::get_library_usage_extend(),
588 484 ],
589 485 'is_first_time' => $is_first_time,
590 486 'install_time' => Plugin::instance()->get_install_time(),
591 487 ];
592 488
593 - $site_key = Api::get_site_key();
594 - if ( ! empty( $site_key ) ) {
595 - $params['site_key'] = $site_key;
596 - }
597 -
598 - $allowed_usage_time = self::get_last_update_time();
599 - if ( ! empty( $allowed_usage_time ) ) {
600 - $params['allowed_usage_time'] = $allowed_usage_time;
601 - }
602 -
603 489 /**
604 490 * Tracker send tracking data params.
605 491 *
606 492 * Filters the data parameters when sending tracking request.
@@ -607,8 +493,9 @@
607 493 *
608 494 * @param array $params Variable to encode as JSON.
609 495 *
610 496 * @since 1.0.0
497 + *
611 498 */
612 499 $params = apply_filters( 'elementor/tracker/send_tracking_data_params', $params );
613 500
614 501 return $params;