PluginProbe
Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) / trunk
Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) vtrunk
9.1.2 9.1.1 9.1.0 9.0.2 9.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.1.0 1.1.1 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 All 153 releases
wp-analytify / inc / promotions.php

promotions.php in Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) trunk, at inc/promotions.php

413 lines 13.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName -- File naming is acceptable
2 /**
3 * Promotions Component for WP Analytify
4 *
5 * This file contains all promotional notices and messages
6 * that were previously in the main plugin file.
7 *
8 * @package WP_Analytify
9 * @since 8.0.0
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit;
14 }
15
16 /**
17 * Promotions Component Class
18 */
19 class Analytify_Promotions {
20
21 /**
22 * User meta: when the current user snoozed the review notice ("Maybe Later").
23 */
24 private const REVIEW_LATER_USER_META = WP_ANALYTIFY_USER_META_PREFIX . 'review_later_at';
25
26 /**
27 * User meta: permanent review notice dismissal for the current user.
28 */
29 private const REVIEW_DISMISS_USER_META = WP_ANALYTIFY_USER_META_PREFIX . 'review_dismiss';
30
31 /**
32 * Review notice delay in seconds (15 days).
33 */
34 private const REVIEW_NOTICE_DELAY = 1296000;
35
36 /**
37 * Main plugin instance
38 *
39 * @var WP_Analytify
40 */
41 private $analytify;
42
43 /**
44 * Constructor
45 *
46 * @version 7.0.5
47 * @param WP_Analytify $analytify Main plugin instance.
48 */
49 public function __construct( $analytify ) {
50 $this->analytify = $analytify;
51 }
52
53 /**
54 * Add deactivation modal
55 *
56 * @version 7.0.5
57 * @return void
58 */
59 public function add_deactive_modal() {
60 ?>
61 <div id="analytify-deactivate-modal" style="display: none;">
62 <div class="analytify-deactivate-modal-content">
63 <h3><?php esc_html_e( 'We\'re sorry to see you go!', 'wp-analytify' ); ?></h3>
64 <p><?php esc_html_e( 'Before you deactivate Analytify, would you mind sharing why you\'re leaving?', 'wp-analytify' ); ?></p>
65 <textarea id="analytify-deactivation-reason" placeholder="<?php esc_attr_e( 'Please share your feedback...', 'wp-analytify' ); ?>"></textarea>
66 <div class="analytify-deactivate-modal-actions">
67 <button id="analytify-deactivate-submit" class="button button-primary"><?php esc_html_e( 'Submit & Deactivate', 'wp-analytify' ); ?></button>
68 <button id="analytify-deactivate-cancel" class="button"><?php esc_html_e( 'Cancel', 'wp-analytify' ); ?></button>
69 </div>
70 </div>
71 </div>
72 <?php
73 }
74
75 /**
76 * Addons promo screen
77 *
78 * @return void
79 */
80 public function addons_promo_screen() {
81 include_once defined( 'WP_ANALYTIFY_ROOT_PATH' ) ? WP_ANALYTIFY_ROOT_PATH : WP_ANALYTIFY_PLUGIN_DIR . '/views/addons-list.php';
82 }
83
84 /**
85 * Render optin
86 *
87 * @version 7.0.5
88 * @return void
89 */
90 public function render_optin() {
91 include_once defined( 'WP_ANALYTIFY_ROOT_PATH' ) ? WP_ANALYTIFY_ROOT_PATH : WP_ANALYTIFY_PLUGIN_DIR . '/views/optin-form.php';
92 }
93
94 /**
95 * Settings tabs
96 *
97 * @param string $current Current tab.
98 * @return void
99 */
100 public function pa_settings_tabs( $current = 'authentication' ) {
101 $tabs = array(
102 'authentication' => __( 'Authentication', 'wp-analytify' ),
103 'profile' => __( 'Profile', 'wp-analytify' ),
104 'admin' => __( 'Admin', 'wp-analytify' ),
105 'dashboard' => __( 'Dashboard', 'wp-analytify' ),
106 'front' => __( 'Frontend', 'wp-analytify' ),
107 'advanced' => __( 'Advanced', 'wp-analytify' ),
108 'help' => __( 'Help', 'wp-analytify' ),
109 );
110
111 echo '<h2 class="nav-tab-wrapper">';
112 foreach ( $tabs as $tab => $name ) {
113 $class = ( $tab === $current ) ? ' nav-tab-active' : '';
114 echo '<a class="nav-tab' . esc_attr( $class ) . '" href="?page=analytify-settings&tab=' . esc_attr( $tab ) . '">' . esc_html( $name ) . '</a>';
115 }
116 echo '</h2>';
117 }
118
119 /**
120 * Profile warning
121 *
122 * @return void
123 */
124 public function profile_warning() {
125 if ( ! $this->analytify->pa_check_roles( 'manage_options' ) ) {
126 return;
127 }
128
129 $profile = get_option( 'wp-analytify-profile' );
130 if ( empty( $profile['profile_for_dashboard'] ) ) {
131 // translators: %s is the admin URL.
132 echo '<div class="notice notice-warning is-dismissible"><p>' . wp_kses( sprintf( __( 'Please <a href="%s">select your website profile</a> to view Analytics.', 'wp-analytify' ), esc_url( admin_url( 'admin.php?page=analytify-settings&tab=profile' ) ) ), array( 'a' => array( 'href' => array() ) ) ) . '</p></div>';
133 }
134 }
135
136 /**
137 * GTAG move to notice
138 *
139 * @version 8.1.1
140 * @return void
141 */
142 public function gtag_move_to_notice() {
143 if ( ! $this->analytify->pa_check_roles( 'manage_options' ) ) {
144 return;
145 }
146
147 $gtag_notice = get_option( 'analytify_gtag_move_to_notice' );
148 if ( ! $gtag_notice ) {
149 // translators: %s is the admin URL.
150 echo '<div class="notice notice-info is-dismissible"><p>' . wp_kses( sprintf( /* translators: 1: Opening anchor tag, 2: Closing anchor tag. */ __( 'Analytify now supports GA4! %1$sClick here%2$s to learn more about the new features.', 'wp-analytify' ), '<a href="' . esc_url( admin_url( 'admin.php?page=analytify-settings&tab=advanced' ) ) . '">', '</a>' ), array( 'a' => array( 'href' => array() ) ) ) . '</p></div>';
151 }
152 }
153
154 /**
155 * Dismiss notices
156 *
157 * @return void
158 */
159 public function dismiss_notices() {
160 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated,WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce verification handles security
161 if ( isset( $_GET['analytify_dismiss'] ) && isset( $_GET['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'analytify_dismiss' ) ) {
162 update_option( 'analytify_gtag_move_to_notice', true );
163 wp_safe_redirect( remove_query_arg( array( 'analytify_dismiss', '_wpnonce' ) ) );
164 exit;
165 }
166 }
167
168 /**
169 * Whether the current user may see the review notice (dashboard roles + administrator).
170 *
171 * @return bool
172 */
173 private function wp_analytify_user_can_see_dashboard_review_notice() {
174 if ( ! is_user_logged_in() || ! $this->analytify || ! isset( $this->analytify->settings ) ) {
175 return false;
176 }
177
178 $allowed_roles = $this->analytify->settings->get_option(
179 'show_analytics_roles_dashboard',
180 'wp-analytify-dashboard',
181 array()
182 );
183 $allowed_roles[] = 'administrator';
184
185 return (bool) $this->analytify->pa_check_roles( $allowed_roles );
186 }
187
188 /**
189 * Whether the review notice was permanently dismissed for the current user.
190 *
191 * @since 9.1.0
192 * @return bool
193 */
194 private function wp_analytify_is_review_notice_permanently_dismissed() {
195 // Legacy site-option key used before 9.1; keep reading it for existing dismissals.
196 if ( 'yes_v7' === get_site_option( 'wp_analytify_review_dismiss_4_1_8' ) ) {
197 return true;
198 }
199
200 $user_id = get_current_user_id();
201 if ( $user_id && 'yes_v7' === get_user_meta( $user_id, self::REVIEW_DISMISS_USER_META, true ) ) {
202 return true;
203 }
204
205 return false;
206 }
207
208 /**
209 * Whether the review notice is snoozed for the current user ("Maybe Later").
210 *
211 * @return bool
212 */
213 private function wp_analytify_is_review_notice_snoozed_for_user() {
214 $user_id = get_current_user_id();
215 if ( ! $user_id ) {
216 return false;
217 }
218
219 $snoozed_at = (int) get_user_meta( $user_id, self::REVIEW_LATER_USER_META, true );
220 if ( ! $snoozed_at ) {
221 return false;
222 }
223
224 return ( time() - $snoozed_at ) < self::REVIEW_NOTICE_DELAY;
225 }
226
227 /**
228 * Review notice dismissal
229 *
230 * @return void
231 */
232 public function review_dismissal() {
233 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification handled by safe_verify_nonce
234 if ( ! is_admin() || ! $this->wp_analytify_user_can_see_dashboard_review_notice() || ! WPANALYTIFY_Utils::safe_verify_nonce( '_wpnonce', 'analytify-review-nonce', 'GET' ) || ! isset( $_GET['wp_analytify_review_dismiss'] ) ) {
235 return;
236 }
237
238 $user_id = get_current_user_id();
239 if ( $user_id ) {
240 update_user_meta( $user_id, self::REVIEW_DISMISS_USER_META, 'yes_v7' );
241 }
242
243 wp_safe_redirect( remove_query_arg( array( 'wp_analytify_review_dismiss', '_wpnonce' ) ) );
244 exit;
245 }
246
247 /**
248 * Review notice
249 *
250 * @return void
251 */
252 public function analytify_review_notice() {
253 if ( ! $this->wp_analytify_user_can_see_dashboard_review_notice() ) {
254 return;
255 }
256
257 $this->review_dismissal();
258 $this->review_prending();
259
260 if ( $this->wp_analytify_is_review_notice_permanently_dismissed() || $this->wp_analytify_is_review_notice_snoozed_for_user() ) {
261 return;
262 }
263
264 $activation_time = get_site_option( 'wp_analytify_active_time' );
265
266 if ( ! $activation_time ) {
267 $activation_time = time();
268 add_site_option( 'wp_analytify_active_time', $activation_time );
269 }
270
271 if ( time() - $activation_time > self::REVIEW_NOTICE_DELAY ) {
272 add_action( 'admin_notices', array( $this, 'analytify_review_notice_message' ) );
273 }
274 }
275
276 /**
277 * Review pending
278 *
279 * @return void
280 */
281 public function review_prending() {
282 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification handled by safe_verify_nonce
283 if ( ! is_admin() || ! $this->wp_analytify_user_can_see_dashboard_review_notice() || ! WPANALYTIFY_Utils::safe_verify_nonce( '_wpnonce', 'analytify-review-nonce', 'GET' ) || ! isset( $_GET['wp_analytify_review_later'] ) ) {
284 return;
285 }
286
287 $user_id = get_current_user_id();
288 if ( $user_id ) {
289 update_user_meta( $user_id, self::REVIEW_LATER_USER_META, time() );
290 }
291
292 wp_safe_redirect( remove_query_arg( array( 'wp_analytify_review_later', '_wpnonce' ) ) );
293 exit;
294 }
295
296 /**
297 * Review notice message
298 *
299 * @return void
300 */
301 public function analytify_review_notice_message() {
302 if ( ! $this->wp_analytify_user_can_see_dashboard_review_notice() ) {
303 return;
304 }
305
306 // Sanitize server data for security.
307 $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
308 $scheme = ( wp_parse_url( $request_uri, PHP_URL_QUERY ) ) ? '&' : '?';
309 $url = $request_uri . $scheme . 'wp_analytify_review_dismiss=yes_v7';
310 $dismiss_url = wp_nonce_url( $url, 'analytify-review-nonce' );
311
312 $_later_link = $request_uri . $scheme . 'wp_analytify_review_later=yes';
313 $later_url = wp_nonce_url( $_later_link, 'analytify-review-nonce' );
314 ?>
315
316 <div class="analytify-review-notice">
317 <div class="analytify-review-thumbnail">
318 <img src="<?php echo esc_url( plugins_url( 'assets/img/notice-logo.svg', __DIR__ ) ); ?>" alt="notice">
319 </div>
320 <div class="analytify-review-text">
321 <h3><?php esc_html_e( 'How\'s Analytify going, impressed?', 'wp-analytify' ); ?></h3>
322 <p><?php esc_html_e( 'We hope you\'ve enjoyed using Analytify! Would you consider leaving us a 5-star review on WordPress.org?', 'wp-analytify' ); ?></p>
323 <ul class="analytify-review-ul">
324 <li><a href="https://wordpress.org/support/view/plugin-reviews/wp-analytify?rate=5#postform" target="_blank"><span class="dashicons dashicons-external"></span><?php esc_html_e( 'Sure! I\'d love to!', 'wp-analytify' ); ?></a></li>
325 <li><a href="<?php echo esc_url( $dismiss_url ); ?>"><span class="dashicons dashicons-smiley"></span><?php esc_html_e( 'I\'ve already left a 5-star review', 'wp-analytify' ); ?></a></li>
326 <li><a href="<?php echo esc_url( $later_url ); ?>"><span class="dashicons dashicons-calendar-alt"></span><?php esc_html_e( 'Maybe Later', 'wp-analytify' ); ?></a></li>
327 <li><a href="<?php echo esc_url( $dismiss_url ); ?>"><span class="dashicons dashicons-dismiss"></span><?php esc_html_e( 'Never show again', 'wp-analytify' ); ?></a></li>
328 </ul>
329 </div>
330 </div>
331
332 <?php
333 }
334
335 /**
336 * Buy pro notice
337 *
338 * @return void
339 */
340 public function analytify_buy_pro_notice() {
341 // Don't show upgrade notice if Pro version is active.
342 if ( defined( 'ANALYTIFY_PRO_VERSION' ) || class_exists( 'WP_Analytify_Pro' ) ) {
343 return;
344 }
345
346 $this->buy_pro_notice_dismissal();
347
348 $activation_time = get_site_option( 'wp_analytify_buy_pro_active_time' );
349 $review_dismissal = get_site_option( 'wp_analytify_buy_pro_notice' );
350
351 if ( 'yes' === $review_dismissal ) {
352 return;
353 }
354
355 if ( ! $activation_time ) {
356 $activation_time = time();
357 add_site_option( 'wp_analytify_buy_pro_active_time', $activation_time );
358 }
359
360 // 604800 = 7 Days in seconds.
361 if ( time() - $activation_time > 604800 ) {
362 add_action( 'admin_notices', array( $this, 'analytify_buy_pro_message' ) );
363 }
364 }
365
366 /**
367 * Dismiss Buy Pro Notice.
368 *
369 * @since 2.1.23
370 * @return void
371 */
372 public function buy_pro_notice_dismissal() {
373 if ( ! is_admin() || ! current_user_can( 'manage_options' ) || ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_GET['_wpnonce'] ) ), 'wp_analytify_buy_pro_notice' ) || ! isset( $_GET['wp_analytify_buy_pro_notice_dismiss'] ) ) {
374 return;
375 }
376
377 add_site_option( 'wp_analytify_buy_pro_notice', 'yes' );
378 }
379
380 /**
381 * Show Buy Pro Notice.
382 *
383 * @since 2.1.23
384 * @return void
385 */
386 public function analytify_buy_pro_message() {
387 $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
388 $scheme = ( wp_parse_url( $request_uri, PHP_URL_QUERY ) ) ? '&' : '?';
389 $url = $request_uri . $scheme . 'wp_analytify_buy_pro_notice_dismiss=yes';
390 $dismiss_url = wp_nonce_url( $url, 'wp_analytify_buy_pro_notice' );
391
392 $class = 'wp-analytify-success';
393
394 $message = sprintf( 'Analytify now powering %1$s30,000+%2$s websites. Use the coupon code %1$sBFCM60%2$s to redeem a %1$s60%% %2$s discount on Pro. %3$sApply Coupon%4$s %5$s I\'m good with free.%6$s', '<strong>', '</strong>', '<a href="https://analytify.io/pricing/?discount=BFCM60" target="_blank" class="wp-analytify-notice-link"><span class="dashicons dashicons-smiley"></span> ', '</a>', '<a href="' . $dismiss_url . '" class="wp-analytify-notice-link"><span class="dashicons dashicons-dismiss"></span>', '</a>' );
395
396 analytify_notice( $message, $class );
397 }
398
399 /**
400 * Add rating icon
401 *
402 * @param mixed $meta_fields Plugin meta fields.
403 * @param mixed $file Plugin file.
404 * @return mixed
405 */
406 public function add_rating_icon( $meta_fields, $file ) {
407 if ( plugin_basename( __FILE__ ) === $file ) {
408 $meta_fields[] = '<a href="https://wordpress.org/support/view/plugin-reviews/wp-analytify?rate=5#postform" target="_blank" class="button button-primary" title="' . __( 'Rate Analytify 5 Stars on WordPress.org', 'wp-analytify' ) . '">' . __( 'Rate 5 Stars', 'wp-analytify' ) . '</a>';
409 }
410 return $meta_fields;
411 }
412 }
413