| @@ -29,9 +29,9 @@ | ||
| 29 | 29 | * Member Variable |
| 30 | 30 | * |
| 31 | 31 | * @var string Usage tracking document URL |
| 32 | 32 | */ |
| 33 | - public $usage_doc_link = 'https://store.brainstormforce.com/usage-tracking/?utm_source=wp_dashboard&utm_medium=general_settings&utm_campaign=usage_tracking'; | |
| 33 | + public $usage_doc_link = 'https://store.brainstormforce.com/usage-tracking/'; | |
| 34 | 34 | |
| 35 | 35 | /** |
| 36 | 36 | * Setup actions, load files. |
| 37 | 37 | * |
| @@ -92,9 +92,9 @@ | ||
| 92 | 92 | */ |
| 93 | 93 | public function set_actions() { |
| 94 | 94 | |
| 95 | 95 | foreach ( $this->entities as $key => $data ) { |
| 96 | - add_action( 'astra_notice_before_markup_' . $key . '-optin-notice', array( $this, 'enqueue_assets' ) ); | |
| 96 | + add_action( 'bsf_admin_notice_before_markup_' . $key . '-optin-notice', array( $this, 'enqueue_assets' ) ); | |
| 97 | 97 | add_action( 'update_option_' . $key . '_usage_optin', array( $this, 'update_analytics_option_callback' ), 10, 3 ); |
| 98 | 98 | add_action( 'add_option_' . $key . '_usage_optin', array( $this, 'add_analytics_option_callback' ), 10, 2 ); |
| 99 | 99 | } |
| 100 | 100 | } |
| @@ -163,8 +163,14 @@ | ||
| 163 | 163 | * @since 1.0.0 |
| 164 | 164 | */ |
| 165 | 165 | public function is_tracking_enabled() { |
| 166 | 166 | |
| 167 | + // Global kill switch — allows hosting providers, compliance plugins, | |
| 168 | + // or agency developers to disable all BSF tracking with one filter. | |
| 169 | + if ( ! apply_filters( 'bsf_usage_tracking_enabled', true ) ) { | |
| 170 | + return false; | |
| 171 | + } | |
| 172 | + | |
| 167 | 173 | foreach ( $this->entities as $key => $data ) { |
| 168 | 174 | |
| 169 | 175 | $is_enabled = get_site_option( $key . '_usage_optin', false ) === 'yes' ? true : false; |
| 170 | 176 | $is_enabled = $this->is_white_label_enabled( $key ) ? false : $is_enabled; |
| @@ -201,13 +207,38 @@ | ||
| 201 | 207 | return $is_enabled; |
| 202 | 208 | } |
| 203 | 209 | |
| 204 | 210 | /** |
| 211 | + * Get usage doc link with UTM parameters. | |
| 212 | + * | |
| 213 | + * Appends product-specific UTM params to the default usage tracking URL | |
| 214 | + * so we can attribute which plugin's link was clicked. | |
| 215 | + * | |
| 216 | + * @param string $product_key Product key (e.g., 'spectra', 'surerank'). | |
| 217 | + * @param string $context Where the link appears ('notice' or 'settings'). | |
| 218 | + * @return string Full URL with UTM parameters. | |
| 219 | + * @since 1.1.23 | |
| 220 | + */ | |
| 221 | + public function get_usage_doc_link( $product_key, $context = 'notice' ) { | |
| 222 | + return add_query_arg( | |
| 223 | + array( | |
| 224 | + 'utm_source' => $product_key, | |
| 225 | + 'utm_medium' => $context, | |
| 226 | + 'utm_campaign' => 'usage_tracking', | |
| 227 | + ), | |
| 228 | + $this->usage_doc_link | |
| 229 | + ); | |
| 230 | + } | |
| 231 | + | |
| 232 | + /** | |
| 205 | 233 | * Display admin notice for usage tracking. |
| 206 | 234 | * |
| 207 | 235 | * @since 1.0.0 |
| 208 | 236 | */ |
| 209 | 237 | public function option_notice() { |
| 238 | + if ( ! class_exists( 'BSF_Admin_Notices' ) ) { | |
| 239 | + return; | |
| 240 | + } | |
| 210 | 241 | |
| 211 | 242 | if ( ! current_user_can( 'manage_options' ) ) { |
| 212 | 243 | return; |
| 213 | 244 | } |
| @@ -224,9 +255,9 @@ | ||
| 224 | 255 | |
| 225 | 256 | foreach ( $this->entities as $key => $data ) { |
| 226 | 257 | |
| 227 | 258 | $time_to_display = isset( $data['time_to_display'] ) ? $data['time_to_display'] : '+24 hours'; |
| 228 | - $usage_doc_link = isset( $data['usage_doc_link'] ) ? $data['usage_doc_link'] : $this->usage_doc_link; | |
| 259 | + $usage_doc_link = isset( $data['usage_doc_link'] ) ? $data['usage_doc_link'] : $this->get_usage_doc_link( $key, 'notice' ); | |
| 229 | 260 | |
| 230 | 261 | // Don't display the notice if tracking is disabled or White Label is enabled for any of our plugins. |
| 231 | 262 | if ( false !== get_site_option( $key . '_usage_optin', false ) || $this->is_white_label_enabled( $key ) ) { |
| 232 | 263 | continue; |
| @@ -239,11 +270,11 @@ | ||
| 239 | 270 | |
| 240 | 271 | /* translators: %s product name */ |
| 241 | 272 | $notice_string = sprintf( |
| 242 | 273 | __( |
| 243 | - 'Help us improve %1$s and our other products!<br><br>With your permission, we\'d like to collect <strong>non-sensitive information</strong> from your website — like your PHP version and which features you use — so we can fix bugs faster, make smarter decisions, and build features that actually matter to you. <em>No personal info. Ever.</em>' | |
| 274 | + '<strong>Help shape the future of %1$s.</strong><br><br>Share how you use the plugin so we can build features that matter, fix issues faster, and make smarter decisions.' | |
| 244 | 275 | ), |
| 245 | - '<strong>' . esc_html( $data['product_name'] ) . '</strong>' | |
| 276 | + esc_html( $data['product_name'] ) | |
| 246 | 277 | ); |
| 247 | 278 | |
| 248 | 279 | if ( is_multisite() ) { |
| 249 | 280 | $notice_string .= __( 'This will be applicable for all sites from the network.' ); |
| @@ -250,9 +281,9 @@ | ||
| 250 | 281 | } |
| 251 | 282 | |
| 252 | 283 | $language_dir = is_rtl() ? 'rtl' : 'ltr'; |
| 253 | 284 | |
| 254 | - Astra_Notices::add_notice( | |
| 285 | + BSF_Admin_Notices::add_notice( | |
| 255 | 286 | array( |
| 256 | 287 | 'id' => $key . '-optin-notice', |
| 257 | 288 | 'type' => '', |
| 258 | 289 | 'message' => sprintf( |
| @@ -269,9 +300,9 @@ | ||
| 269 | 300 | </a> |
| 270 | 301 | </div> |
| 271 | 302 | </div>', |
| 272 | 303 | /* translators: %s usage doc link */ |
| 273 | - sprintf( $notice_string . '<span dir="%1s"><a href="%2s" target="_blank" rel="noreferrer noopener">%3s</a><span><br><br>', $language_dir, esc_url( $usage_doc_link ), __( ' Know More.' ) ), | |
| 304 | + sprintf( $notice_string . '<span dir="%1s"> <a href="%2s" target="_blank" rel="noreferrer noopener">%3s</a><span><br><br>', $language_dir, esc_url( $usage_doc_link ), __( 'Learn more.' ) ), | |
| 274 | 305 | esc_url( |
| 275 | 306 | add_query_arg( |
| 276 | 307 | array( |
| 277 | 308 | $key . '_analytics_optin' => 'yes', |
| @@ -279,9 +310,9 @@ | ||
| 279 | 310 | 'bsf_analytics_source' => $key, |
| 280 | 311 | ) |
| 281 | 312 | ) |
| 282 | 313 | ), |
| 283 | - __( 'Yes! Allow it' ), | |
| 314 | + __( 'Happy to help!' ), | |
| 284 | 315 | esc_url( |
| 285 | 316 | add_query_arg( |
| 286 | 317 | array( |
| 287 | 318 | $key . '_analytics_optin' => 'no', |
| @@ -290,9 +321,9 @@ | ||
| 290 | 321 | ) |
| 291 | 322 | ) |
| 292 | 323 | ), |
| 293 | 324 | MONTH_IN_SECONDS, |
| 294 | - __( 'No Thanks' ) | |
| 325 | + __( 'Skip' ) | |
| 295 | 326 | ), |
| 296 | 327 | 'show_if' => true, |
| 297 | 328 | 'repeat-notice-after' => false, |
| 298 | 329 | 'priority' => 18, |
| @@ -370,8 +401,11 @@ | ||
| 370 | 401 | */ |
| 371 | 402 | private function optout( $source ) { |
| 372 | 403 | update_site_option( $source . '_usage_optin', 'no' ); |
| 373 | 404 | update_site_option( 'bsf_usage_last_displayed_time', time() ); |
| 405 | + | |
| 406 | + // Clear tracking transient immediately so opt-out takes effect right away. | |
| 407 | + delete_site_transient( 'bsf_usage_track' ); | |
| 374 | 408 | } |
| 375 | 409 | |
| 376 | 410 | /** |
| 377 | 411 | * Load analytics stat class. |
| @@ -454,9 +488,9 @@ | ||
| 454 | 488 | if( ! empty( $data['hide_optin_checkbox'] ) && true === $data['hide_optin_checkbox'] ) { |
| 455 | 489 | continue; |
| 456 | 490 | } |
| 457 | 491 | |
| 458 | - $usage_doc_link = isset( $data['usage_doc_link'] ) ? $data['usage_doc_link'] : $this->usage_doc_link; | |
| 492 | + $usage_doc_link = isset( $data['usage_doc_link'] ) ? $data['usage_doc_link'] : $this->get_usage_doc_link( $key, 'settings' ); | |
| 459 | 493 | $author = isset( $data['author'] ) ? $data['author'] : 'Brainstorm Force'; |
| 460 | 494 | |
| 461 | 495 | register_setting( |
| 462 | 496 | 'general', // Options group. |
| @@ -510,9 +544,9 @@ | ||
| 510 | 544 | <label for="<?php echo esc_attr( $args['label_for'] ); ?>"> |
| 511 | 545 | <input id="<?php echo esc_attr( $args['id'] ); ?>" type="checkbox" value="1" name="<?php echo esc_attr( $args['name'] ); ?>" <?php checked( $is_checked ); ?>> |
| 512 | 546 | <?php |
| 513 | 547 | /* translators: %s Product title */ |
| 514 | - echo esc_html( sprintf( __( 'Allow %s products to track non-sensitive usage tracking data.' ), $args['title'] ) );// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText | |
| 548 | + echo esc_html( sprintf( __( 'Help improve %s by sharing non-sensitive usage data — like PHP version and features used.' ), $args['title'] ) );// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText | |
| 515 | 549 | |
| 516 | 550 | if ( is_multisite() ) { |
| 517 | 551 | esc_html_e( ' This will be applicable for all sites from the network.' ); |
| 518 | 552 | } |