class-tracking.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <?php
  2. /**
  3. * WPSEO plugin file.
  4. *
  5. * @package WPSEO\Admin\Tracking
  6. */
  7. /**
  8. * This class handles the tracking routine.
  9. */
  10. class WPSEO_Tracking implements WPSEO_WordPress_Integration {
  11. /**
  12. * The tracking option name.
  13. *
  14. * @var string
  15. */
  16. protected $option_name = 'wpseo_tracking_last_request';
  17. /**
  18. * The limit for the option.
  19. *
  20. * @var int
  21. */
  22. protected $threshold = 0;
  23. /**
  24. * The endpoint to send the data to.
  25. *
  26. * @var string
  27. */
  28. protected $endpoint = '';
  29. /**
  30. * The current time.
  31. *
  32. * @var int
  33. */
  34. private $current_time;
  35. /**
  36. * WPSEO_Tracking constructor.
  37. *
  38. * @param string $endpoint The endpoint to send the data to.
  39. * @param int $threshold The limit for the option.
  40. */
  41. public function __construct( $endpoint, $threshold ) {
  42. $this->endpoint = $endpoint;
  43. $this->threshold = $threshold;
  44. $this->current_time = time();
  45. }
  46. /**
  47. * Registers all hooks to WordPress.
  48. */
  49. public function register_hooks() {
  50. // Send tracking data on `admin_init`.
  51. add_action( 'admin_init', [ $this, 'send' ], 1 );
  52. // Add an action hook that will be triggered at the specified time by `wp_schedule_single_event()`.
  53. add_action( 'wpseo_send_tracking_data_after_core_update', [ $this, 'send' ] );
  54. // Call `wp_schedule_single_event()` after a WordPress core update.
  55. add_action( 'upgrader_process_complete', [ $this, 'schedule_tracking_data_sending' ], 10, 2 );
  56. }
  57. /**
  58. * Schedules a new sending of the tracking data after a WordPress core update.
  59. *
  60. * @param bool|WP_Upgrader $upgrader Optional. WP_Upgrader instance or false.
  61. * Depending on context, it might be a Theme_Upgrader,
  62. * Plugin_Upgrader, Core_Upgrade, or Language_Pack_Upgrader.
  63. * instance. Default false.
  64. * @param array $data Array of update data.
  65. *
  66. * @return void
  67. */
  68. public function schedule_tracking_data_sending( $upgrader = false, $data = [] ) {
  69. // Return if it's not a WordPress core update.
  70. if ( ! $upgrader || ! isset( $data['type'] ) || $data['type'] !== 'core' ) {
  71. return;
  72. }
  73. /*
  74. * To uniquely identify the scheduled cron event, `wp_next_scheduled()`
  75. * needs to receive the same arguments as those used when originally
  76. * scheduling the event otherwise it will always return false.
  77. */
  78. if ( ! wp_next_scheduled( 'wpseo_send_tracking_data_after_core_update', true ) ) {
  79. /*
  80. * Schedule sending of data tracking 6 hours after a WordPress core
  81. * update. Pass a `true` parameter for the callback `$force` argument.
  82. */
  83. wp_schedule_single_event( ( time() + ( HOUR_IN_SECONDS * 6 ) ), 'wpseo_send_tracking_data_after_core_update', true );
  84. }
  85. }
  86. /**
  87. * Sends the tracking data.
  88. *
  89. * @param bool $force Whether to send the tracking data ignoring the two
  90. * weeks time treshhold. Default false.
  91. */
  92. public function send( $force = false ) {
  93. if ( ! $this->should_send_tracking( $force ) ) {
  94. return;
  95. }
  96. $collector = $this->get_collector();
  97. $request = new WPSEO_Remote_Request( $this->endpoint );
  98. $request->set_body( $collector->get_as_json() );
  99. $request->send();
  100. update_option( $this->option_name, $this->current_time, 'yes' );
  101. }
  102. /**
  103. * Determines whether to send the tracking data.
  104. *
  105. * Returns false if tracking is disabled or the current page is one of the
  106. * admin plugins pages. Returns true when there's no tracking data stored or
  107. * the data was sent more than two weeks ago. The two weeks interval is set
  108. * when instantiating the class.
  109. *
  110. * @param bool $ignore_time_treshhold Whether to send the tracking data ignoring
  111. * the two weeks time treshhold. Default false.
  112. *
  113. * @return bool True when tracking data should be sent.
  114. */
  115. protected function should_send_tracking( $ignore_time_treshhold = false ) {
  116. global $pagenow;
  117. /**
  118. * Filter: 'wpseo_enable_tracking' - Enables the data tracking of Yoast SEO Premium.
  119. *
  120. * @api string $is_enabled The enabled state. Default is false.
  121. */
  122. if ( apply_filters( 'wpseo_enable_tracking', false ) === false ) {
  123. return false;
  124. }
  125. // Only send tracking on the main site of a multi-site instance. This returns true on non-multisite installs.
  126. if ( ! is_main_site() ) {
  127. return false;
  128. }
  129. // Because we don't want to possibly block plugin actions with our routines.
  130. if ( in_array( $pagenow, [ 'plugins.php', 'plugin-install.php', 'plugin-editor.php' ], true ) ) {
  131. return false;
  132. }
  133. $last_time = get_option( $this->option_name );
  134. // When tracking data haven't been sent yet or when sending data is forced.
  135. if ( ! $last_time || $ignore_time_treshhold ) {
  136. return true;
  137. }
  138. return $this->exceeds_treshhold( $this->current_time - $last_time );
  139. }
  140. /**
  141. * Checks if the given amount of seconds exceeds the set threshold.
  142. *
  143. * @param int $seconds The amount of seconds to check.
  144. *
  145. * @return bool True when seconds is bigger than threshold.
  146. */
  147. protected function exceeds_treshhold( $seconds ) {
  148. return ( $seconds > $this->threshold );
  149. }
  150. /**
  151. * Returns the collector for collecting the data.
  152. *
  153. * @return WPSEO_Collector The instance of the collector.
  154. */
  155. public function get_collector() {
  156. $collector = new WPSEO_Collector();
  157. $collector->add_collection( new WPSEO_Tracking_Default_Data() );
  158. $collector->add_collection( new WPSEO_Tracking_Server_Data() );
  159. $collector->add_collection( new WPSEO_Tracking_Theme_Data() );
  160. $collector->add_collection( new WPSEO_Tracking_Plugin_Data() );
  161. $collector->add_collection( new WPSEO_Tracking_Settings_Data() );
  162. return $collector;
  163. }
  164. }