PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
← All changes | src/controller/class-data-tracking.php +100 -62 5.3.1 → 6.3.0 View file →
@@ -22,55 +22,24 @@
22 22
23 23 public const TRACKING_SLUG = 'wd_show_usage_data';
24 24
25 25 /**
26 - * Initializes the model and service, registers routes, and sets up scheduled events if the model is active.
26 + * Site option key that controls the dashboard share-usage bubble lifecycle.
27 + * Kept separate from TRACKING_SLUG so that skipping onboarding does not
28 + * suppress the bubble.
27 29 */
28 - public function __construct() {
29 - $this->register_routes();
30 - }
30 + public const DASHBOARD_NOTICE_SLUG = 'wd_show_dashboard_usage_notice';
31 31
32 32 /**
33 - * Get the Tracking modal that is displayed on all plugin pages.
34 - *
35 - * @return array
33 + * Records whether the dashboard notice lifecycle has been initialized.
36 34 */
37 - public function get_tracking_modal(): array {
38 - $title = esc_html__( 'Help Us Enhance Your Site\'s Security', 'defender-security' );
35 + public const DASHBOARD_NOTICE_INITIALIZED_SLUG = 'wd_dashboard_usage_notice_initialized';
39 36
40 - $current_user = wp_get_current_user();
41 -
42 - $desc = sprintf(
43 - /* translators: %s: user display name */
44 - esc_html__(
45 - 'Hey there! %s, Defender is dedicated to protecting your WordPress website from hackers and malware. However, our mission is more effective with your collaboration. By opting in to share anonymous usage data, you help us refine and enhance our plugin for everyone\'s benefit.',
46 - 'defender-security'
47 - ),
48 - '<strong>' . esc_html( $current_user->display_name ) . '</strong>'
49 - );
50 - $desc .= '<br/><br/>';
51 - $desc .= sprintf(
52 - /* translators: %s: Link. */
53 - esc_html__(
54 - 'Your privacy is important to us. We guarantee that your data stays anonymous and your identity stays secure. Learn more about our usage tracking %s.',
55 - 'defender-security'
56 - ),
57 - '<a href="' . Main_Setting::PRIVACY_LINK . '" target="_blank">' . esc_html__( 'here', 'defender-security' ) . '<a>'
58 - );
59 - $result = $this->dump_routes_and_nonces();
60 -
61 - return array(
62 - 'title' => $title,
63 - 'desc' => $desc,
64 - 'banner_1x' => defender_asset_url( '/assets/img/modal/tracking-modal.png' ),
65 - 'banner_2x' => defender_asset_url( '/assets/img/modal/[email protected]' ),
66 - 'banner_alt' => esc_html__( 'Help us improve Defender', 'defender-security' ),
67 - 'optin_button_title' => esc_html__( 'OPT IN', 'defender-security' ),
68 - 'skip_button_title' => esc_html__( 'Skip for now', 'defender-security' ),
69 - 'state_usage_tracking' => wd_di()->get( Main_Setting::class )->usage_tracking,
70 - 'routes' => $result['routes'],
71 - 'nonces' => $result['nonces'],
72 - );
37 + /**
38 + * Initializes the model and service, registers routes, and sets up scheduled events if the model is active.
39 + */
40 + public function __construct() {
41 + $this->register_routes();
73 42 }
74 43
75 44 /**
76 45 * Handles the closing of the tracking modal.
@@ -78,11 +47,18 @@
78 47 * @return Response Response object indicating success.
79 48 * @defender_route
80 49 */
81 50 public function close_track_modal(): Response {
51 + $model_settings = wd_di()->get( Main_Setting::class );
52 +
53 + if ( true === $model_settings->usage_tracking ) {
54 + $model_settings->toggle_tracking( false );
55 + Config_Hub_Helper::set_clear_active_flag();
56 + $this->track_opt_toggle( false, 'Tracking modal' );
57 + }
82 58 // Track.
83 59 $this->track_feature( 'def_tracking_modal', array( 'Modal Action' => 'closed' ) );
84 - self::delete_modal_key();
60 + self::dismiss_modal_key();
85 61
86 62 return new Response( true, array() );
87 63 }
88 64
@@ -104,37 +80,27 @@
104 80 // Track#2.
105 81 $this->track_feature( 'def_tracking_modal', array( 'Modal Action' => 'cta_clicked' ) );
106 82 }
107 83 // Hide the modal.
108 - self::delete_modal_key();
84 + self::dismiss_modal_key();
109 85
110 86 return new Response( true, array() );
111 87 }
112 88
113 89 /**
114 - * Deletes the site option that controls the visibility of the tracking modal.
90 + * Marks the tracking notice as dismissed without resetting initialization state.
91 + *
92 + * @return void
115 93 */
116 - public static function delete_modal_key(): void {
117 - delete_site_option( self::TRACKING_SLUG );
94 + public static function dismiss_modal_key(): void {
95 + update_site_option( self::TRACKING_SLUG, false );
118 96 }
119 97
120 98 /**
121 - * Conditions of the Tracking modal:
122 - * 1)show on all Defender pages.
123 - * 2)show to users upgrading from older versions.
124 - * 3)should have higher priority than a Welcome modal on the Defender > Dashboard page.
125 - * 4)if user closes or clicks on the Save button on one plugin page, we don't itl on another plugin page.
126 - * 5)no display after the updated Onboarding with Opt-in.
127 - * 6)no display when Whitelabel > Documentation, Tutorials and What’s New Modal is set to “Hide”
128 - *
129 - * @return bool
99 + * Deletes the site option that controls the visibility of the tracking modal.
130 100 */
131 - public function show_tracking_modal() {
132 - $info = defender_white_label_status();
133 -
134 - $white_label_is_hide = isset( $info['hide_doc_link'] ) && $info['hide_doc_link'];
135 -
136 - return (bool) get_site_option( self::TRACKING_SLUG ) && ! $white_label_is_hide;
101 + public static function delete_modal_key(): void {
102 + delete_site_option( self::TRACKING_SLUG );
137 103 }
138 104
139 105 /**
140 106 * Delete all the data & the cache.
@@ -139,8 +105,11 @@
139 105 /**
140 106 * Delete all the data & the cache.
141 107 */
142 108 public function remove_data() {
109 + self::delete_modal_key();
110 + delete_site_option( self::DASHBOARD_NOTICE_SLUG );
111 + delete_site_option( self::DASHBOARD_NOTICE_INITIALIZED_SLUG );
143 112 }
144 113
145 114 /**
146 115 * Exports strings.
@@ -173,8 +142,11 @@
173 142 /**
174 143 * Removes settings for all submodules.
175 144 */
176 145 public function remove_settings(): void {
146 + self::delete_modal_key();
147 + delete_site_option( self::DASHBOARD_NOTICE_SLUG );
148 + delete_site_option( self::DASHBOARD_NOTICE_INITIALIZED_SLUG );
177 149 }
178 150
179 151 /**
180 152 * Provides data for the frontend.
@@ -182,6 +154,72 @@
182 154 * @return array An array of data for the frontend.
183 155 */
184 156 public function data_frontend(): array {
185 157 return array();
158 + }
159 +
160 + /**
161 + * Initializes the dashboard notice lifecycle once.
162 + *
163 + * A dedicated marker distinguishes an intentionally consumed false value
164 + * from an option that an older or interrupted upgrade failed to seed.
165 + *
166 + * @return void
167 + */
168 + public static function initialize_dashboard_notice(): void {
169 + if ( (bool) get_site_option( self::DASHBOARD_NOTICE_INITIALIZED_SLUG ) ) {
170 + return;
171 + }
172 +
173 + $usage_tracking = wd_di()->get( Main_Setting::class )->usage_tracking;
174 + delete_site_option( self::DASHBOARD_NOTICE_SLUG );
175 + add_site_option( self::DASHBOARD_NOTICE_SLUG, ! $usage_tracking );
176 + update_site_option( self::DASHBOARD_NOTICE_INITIALIZED_SLUG, true );
177 + }
178 +
179 + /**
180 + * Returns whether the dashboard share usage notice should be displayed.
181 + *
182 + * @return bool
183 + */
184 + public function should_show_dashboard_notice(): bool {
185 + $notice_option = (bool) get_site_option( self::DASHBOARD_NOTICE_SLUG );
186 +
187 + // Falsey means not eligible or already displayed.
188 + if ( ! $notice_option ) {
189 + return false;
190 + }
191 +
192 + // Truthy means eligible; also guard against already opted-in.
193 + return ! wd_di()->get( Main_Setting::class )->usage_tracking;
194 + }
195 +
196 + /**
197 + * Returns dashboard notice data and routes for the share usage bubble.
198 + *
199 + * @return array
200 + */
201 + public function get_dashboard_notice_data(): array {
202 + self::initialize_dashboard_notice();
203 + $result = $this->dump_routes_and_nonces();
204 +
205 + return array(
206 + 'shareUsageNotice' => array(
207 + 'isVisible' => $this->should_show_dashboard_notice(),
208 + ),
209 + 'routes' => $result['routes'],
210 + 'nonces' => $result['nonces'],
211 + );
212 + }
213 +
214 + /**
215 + * Marks the share usage dashboard notice as already shown.
216 + *
217 + * @return Response
218 + * @defender_route
219 + */
220 + public function mark_track_notice_displayed(): Response {
221 + update_site_option( self::DASHBOARD_NOTICE_SLUG, false );
222 +
223 + return new Response( true, array() );
186 224 }
187 225 }