PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 4.0.9
Visualizer – Tables & Charts Manager with Built-in AI Generator v4.0.9
4.0.9 4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 All 150 releases
← All changes | vendor/codeinwp/themeisle-sdk/src/Modules/Logger.php +149 -31 3.1.3 → 4.0.9 View file →
@@ -26,11 +26,16 @@
26 26 class Logger extends Abstract_Module {
27 27 /**
28 28 * Endpoint where to collect logs.
29 29 */
30 - const TRACKING_ENDPOINT = 'http://log.themeisle.com/wp-json/v1/logs/';
30 + const TRACKING_ENDPOINT = 'https://api.themeisle.com/tracking/log';
31 31
32 + /**
33 + * Endpoint where to collect telemetry.
34 + */
35 + const TELEMETRY_ENDPOINT = 'https://api.themeisle.com/tracking/events';
32 36
37 +
33 38 /**
34 39 * Check if we should load the module for this product.
35 40 *
36 41 * @param Product $product Product to load the module for.
@@ -37,9 +42,8 @@
37 42 *
38 43 * @return bool Should we load ?
39 44 */
40 45 public function can_load( $product ) {
41 -
42 46 return apply_filters( $product->get_slug() . '_sdk_enable_logger', true );
43 47 }
44 48
45 49 /**
@@ -50,11 +54,10 @@
50 54 * @return Logger Module object.
51 55 */
52 56 public function load( $product ) {
53 57 $this->product = $product;
54 - $this->setup_notification();
55 - $this->setup_actions();
56 -
58 + add_action( 'wp_loaded', array( $this, 'setup_actions' ) );
59 + add_action( 'admin_init', array( $this, 'setup_notification' ) );
57 60 return $this;
58 61 }
59 62
60 63 /**
@@ -60,14 +63,12 @@
60 63 /**
61 64 * Setup notification on admin.
62 65 */
63 66 public function setup_notification() {
64 - if ( ! $this->product->is_wordpress_available() ) {
67 + if ( $this->is_logger_active() ) {
65 68 return;
66 69 }
67 -
68 70 add_filter( 'themeisle_sdk_registered_notifications', [ $this, 'add_notification' ] );
69 -
70 71 }
71 72
72 73 /**
73 74 * Setup tracking actions.
@@ -75,14 +76,25 @@
75 76 public function setup_actions() {
76 77 if ( ! $this->is_logger_active() ) {
77 78 return;
78 79 }
80 + add_action(
81 + 'admin_enqueue_scripts',
82 + function() {
83 + if ( ! apply_filters( 'themeisle_sdk_enable_telemetry', false ) ) {
84 + return;
85 + }
86 +
87 + $this->load_telemetry();
88 + },
89 + PHP_INT_MAX
90 + );
91 +
79 92 $action_key = $this->product->get_key() . '_log_activity';
80 93 if ( ! wp_next_scheduled( $action_key ) ) {
81 - wp_schedule_single_event( time() + ( rand( 1, 24 ) * 3600 ), $action_key );
94 + wp_schedule_single_event( time() + ( wp_rand( 1, 24 ) * 3600 ), $action_key );
82 95 }
83 96 add_action( $action_key, array( $this, 'send_log' ) );
84 -
85 97 }
86 98
87 99 /**
88 100 * Check if the logger is active.
@@ -89,23 +101,42 @@
89 101 *
90 102 * @return bool Is logger active?
91 103 */
92 104 private function is_logger_active() {
93 - if ( ! $this->product->is_wordpress_available() ) {
94 - return true;
105 + return self::is_logging_active( $this->product );
106 + }
107 +
108 + /**
109 + * Check if the logging consent is granted for a product.
110 + *
111 + * Shared with the other telemetry modules (e.g. the crash reporter) so the
112 + * consent semantics live in a single place.
113 + *
114 + * @param \ThemeisleSDK\Product $product Product to check.
115 + *
116 + * @return bool Is logging active for the product?
117 + */
118 + public static function is_logging_active( $product ) {
119 + if ( apply_filters( 'themeisle_sdk_disable_telemetry', false ) ) {
120 + return false;
95 121 }
96 - $pro_slug = $this->product->get_pro_slug();
122 + $default = 'no';
97 123
98 - if ( ! empty( $pro_slug ) ) {
124 + if ( ! $product->is_wordpress_available() ) {
125 + $default = 'yes';
126 + } else {
99 127 $all_products = Loader::get_products();
100 - if ( isset( $all_products[ $pro_slug ] ) ) {
101 - return true;
128 + foreach ( $all_products as $registered_product ) {
129 + if ( $registered_product->requires_license() ) {
130 + $default = 'yes';
131 + break;
132 + }
102 133 }
103 134 }
104 135
105 - return ( get_option( $this->product->get_key() . '_logger_flag', 'no' ) === 'yes' );
136 +
137 + return ( get_option( $product->get_key() . '_logger_flag', $default ) === 'yes' );
106 138 }
107 -
108 139 /**
109 140 * Add notification to queue.
110 141 *
111 142 * @param array $all_notifications Previous notification.
@@ -113,9 +144,9 @@
113 144 * @return array All notifications.
114 145 */
115 146 public function add_notification( $all_notifications ) {
116 147
117 - $message = apply_filters( $this->product->get_key() . '_logger_heading', 'Do you enjoy <b>{product}</b>? Become a contributor by opting in to our anonymous data tracking. We guarantee no sensitive data is collected.' );
148 + $message = apply_filters( $this->product->get_key() . '_logger_heading', Loader::$labels['logger']['notice'] );
118 149
119 150 $message = str_replace(
120 151 array( '{product}' ),
121 152 $this->product->get_friendly_name(),
@@ -120,10 +151,10 @@
120 151 array( '{product}' ),
121 152 $this->product->get_friendly_name(),
122 153 $message
123 154 );
124 - $button_submit = apply_filters( $this->product->get_key() . '_logger_button_submit', 'Sure, I would love to help.' );
125 - $button_cancel = apply_filters( $this->product->get_key() . '_logger_button_cancel', 'No, thanks.' );
155 + $button_submit = apply_filters( $this->product->get_key() . '_logger_button_submit', Loader::$labels['logger']['cta_y'] );
156 + $button_cancel = apply_filters( $this->product->get_key() . '_logger_button_cancel', Loader::$labels['logger']['cta_n'] );
126 157
127 158 $all_notifications[] = [
128 159 'id' => $this->product->get_key() . '_logger_flag',
129 160 'message' => $message,
@@ -150,10 +181,11 @@
150 181 $theme = wp_get_theme();
151 182 $environment['theme'] = array();
152 183 $environment['theme']['name'] = $theme->get( 'Name' );
153 184 $environment['theme']['author'] = $theme->get( 'Author' );
185 + $environment['theme']['parent'] = $theme->parent() !== false ? $theme->parent()->get( 'Name' ) : $theme->get( 'Name' );
154 186 $environment['plugins'] = get_option( 'active_plugins' );
155 -
187 + global $wp_version;
156 188 wp_remote_post(
157 189 self::TRACKING_ENDPOINT,
158 190 array(
159 191 'method' => 'POST',
@@ -158,19 +190,105 @@
158 190 array(
159 191 'method' => 'POST',
160 192 'timeout' => 3,
161 193 'redirection' => 5,
162 - 'headers' => array(
163 - 'X-ThemeIsle-Event' => 'log_site',
164 - ),
165 194 'body' => array(
166 - 'site' => get_site_url(),
167 - 'slug' => $this->product->get_slug(),
168 - 'version' => $this->product->get_version(),
169 - 'data' => apply_filters( $this->product->get_key() . '_logger_data', array() ),
170 - 'environment' => $environment,
171 - 'license' => apply_filters( $this->product->get_key() . '_license_status', '' ),
195 + 'site' => get_site_url(),
196 + 'slug' => $this->product->get_slug(),
197 + 'version' => $this->product->get_version(),
198 + 'wp_version' => $wp_version,
199 + 'install_time' => $this->product->get_install_time(),
200 + 'locale' => get_locale(),
201 + 'data' => apply_filters( $this->product->get_key() . '_logger_data', array() ),
202 + 'environment' => $environment,
203 + 'license' => apply_filters( $this->product->get_key() . '_license_status', '' ),
172 204 ),
173 205 )
174 206 );
207 + }
208 +
209 + /**
210 + * Load telemetry.
211 + *
212 + * @return void
213 + */
214 + public function load_telemetry() {
215 + // See which products have telemetry enabled.
216 + try {
217 + $products_with_telemetry = array();
218 + $all_products = Loader::get_products();
219 + $all_products[ $this->product->get_slug() ] = $this->product; // Add current product to the list of products to check for telemetry.
220 +
221 + // Register telemetry params for eligible products.
222 + foreach ( $all_products as $product_slug => $product ) {
223 +
224 + // Ignore PRO products.
225 + if ( false !== strstr( $product_slug, 'pro' ) ) {
226 + continue;
227 + }
228 +
229 + $pro_slug = $product->get_pro_slug();
230 + $logger_key = $product->get_key() . '_logger_flag';
231 +
232 + // If the product is not available in the WordPress store, or it's PRO version is installed, activate the logger if it was not initialized -- Pro users are opted in by default.
233 + if ( ! $product->is_wordpress_available() || ( ! empty( $pro_slug ) && isset( $all_products[ $pro_slug ] ) ) ) {
234 + $logger_flag = get_option( $logger_key );
235 +
236 + if ( false === $logger_flag ) {
237 + update_option( $logger_key, 'yes' );
238 + }
239 + }
240 +
241 + if ( 'yes' === get_option( $product->get_key() . '_logger_flag', 'no' ) ) {
242 +
243 + $main_slug = explode( '-', $product_slug );
244 + $main_slug = $main_slug[0];
245 + $track_hash = Licenser::create_license_hash( str_replace( '-', '_', ! empty( $pro_slug ) ? $pro_slug : $product_slug ) );
246 +
247 + // Check if product was already tracked.
248 + $active_telemetry = false;
249 + foreach ( $products_with_telemetry as $product_with_telemetry ) {
250 + if ( $product_with_telemetry['slug'] === $main_slug ) {
251 + $active_telemetry = true;
252 + break;
253 + }
254 + }
255 +
256 + if ( $active_telemetry ) {
257 + continue;
258 + }
259 +
260 + $products_with_telemetry[] = array(
261 + 'slug' => $main_slug,
262 + 'trackHash' => $track_hash ? $track_hash : 'free',
263 + 'consent' => true,
264 + );
265 + }
266 + }
267 +
268 + $products_with_telemetry = apply_filters( 'themeisle_sdk_telemetry_products', $products_with_telemetry );
269 +
270 + if ( 0 === count( $products_with_telemetry ) ) {
271 + return;
272 + }
273 +
274 + $tracking_handler = apply_filters( 'themeisle_sdk_dependency_script_handler', 'tracking' );
275 + if ( ! empty( $tracking_handler ) ) {
276 + do_action( 'themeisle_sdk_dependency_enqueue_script', 'tracking' );
277 + wp_localize_script(
278 + $tracking_handler,
279 + 'tiTelemetry',
280 + array(
281 + 'products' => $products_with_telemetry,
282 + 'endpoint' => self::TELEMETRY_ENDPOINT,
283 + )
284 + );
285 + }
286 + } catch ( \Exception $e ) {
287 + if ( defined( 'WP_DEBUG' ) && WP_DEBUG && defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
288 + error_log( $e->getMessage() ); // phpcs:ignore
289 + }
290 + } finally {
291 + return;
292 + }
175 293 }
176 294 }