PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.2.1
Defender Security – Malware Scanner, Login Security & Firewall v6.2.1
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
defender-security / src / controller / class-data-tracking.php

class-data-tracking.php in Defender Security – Malware Scanner, Login Security & Firewall 6.2.1, at src/controller/class-data-tracking.php

289 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handles data tracking functionalities.
4 *
5 * @package WP_Defender\Controller
6 */
7
8 namespace WP_Defender\Controller;
9
10 use Exception;
11 use WP_Defender\Event;
12 use Calotes\Component\Response;
13 use WP_Defender\Model\Setting\Main_Setting;
14 use WP_Defender\Component\Config\Config_Hub_Helper;
15
16 /**
17 * Handles data tracking functionalities.
18 *
19 * @since 4.2.0
20 */
21 class Data_Tracking extends Event {
22
23 public const TRACKING_SLUG = 'wd_show_usage_data';
24
25 /**
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.
29 */
30 public const DASHBOARD_NOTICE_SLUG = 'wd_show_dashboard_usage_notice';
31
32 /**
33 * Records whether the dashboard notice lifecycle has been initialized.
34 */
35 public const DASHBOARD_NOTICE_INITIALIZED_SLUG = 'wd_dashboard_usage_notice_initialized';
36
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();
42 }
43
44 /**
45 * Get the Tracking modal that is displayed on all plugin pages.
46 *
47 * @return array
48 */
49 public function get_tracking_modal(): array {
50 $title = esc_html__( 'Help Us Enhance Your Site\'s Security', 'defender-security' );
51
52 $current_user = wp_get_current_user();
53
54 $desc = sprintf(
55 /* translators: %s: user display name */
56 esc_html__(
57 '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.',
58 'defender-security'
59 ),
60 '<strong>' . esc_html( $current_user->display_name ) . '</strong>'
61 );
62 $desc .= '<br/><br/>';
63 $desc .= sprintf(
64 /* translators: %s: Link. */
65 esc_html__(
66 '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.',
67 'defender-security'
68 ),
69 '<a href="' . Main_Setting::PRIVACY_LINK . '" target="_blank">' . esc_html__( 'here', 'defender-security' ) . '<a>'
70 );
71 $result = $this->dump_routes_and_nonces();
72
73 return array(
74 'title' => $title,
75 'desc' => $desc,
76 'banner_1x' => defender_asset_url( '/assets/img/modal/tracking-modal.png' ),
77 'banner_2x' => defender_asset_url( '/assets/img/modal/[email protected]' ),
78 'banner_alt' => esc_html__( 'Help us improve Defender', 'defender-security' ),
79 'optin_button_title' => esc_html__( 'OPT IN', 'defender-security' ),
80 'skip_button_title' => esc_html__( 'Skip for now', 'defender-security' ),
81 'state_usage_tracking' => wd_di()->get( Main_Setting::class )->usage_tracking,
82 'routes' => $result['routes'],
83 'nonces' => $result['nonces'],
84 );
85 }
86
87 /**
88 * Handles the closing of the tracking modal.
89 *
90 * @return Response Response object indicating success.
91 * @defender_route
92 */
93 public function close_track_modal(): Response {
94 $model_settings = wd_di()->get( Main_Setting::class );
95
96 if ( true === $model_settings->usage_tracking ) {
97 $model_settings->toggle_tracking( false );
98 Config_Hub_Helper::set_clear_active_flag();
99 $this->track_opt_toggle( false, 'Tracking modal' );
100 }
101
102 // Track.
103 $this->track_feature( 'def_tracking_modal', array( 'Modal Action' => 'closed' ) );
104 self::dismiss_modal_key();
105
106 return new Response( true, array() );
107 }
108
109 /**
110 * Save Enabled tracking state.
111 *
112 * @return Response
113 * @defender_route
114 */
115 public function save_track_modal(): Response {
116 $model_settings = wd_di()->get( Main_Setting::class );
117 // Update the value if it's changed.
118 if ( true !== $model_settings->usage_tracking ) {
119 $model_settings->toggle_tracking( true );
120 // Changes for Hub.
121 Config_Hub_Helper::set_clear_active_flag();
122 // Track#1.
123 $this->track_opt_toggle( true, 'Tracking modal' );
124 // Track#2.
125 $this->track_feature( 'def_tracking_modal', array( 'Modal Action' => 'cta_clicked' ) );
126 }
127 // Hide the modal.
128 self::dismiss_modal_key();
129
130 return new Response( true, array() );
131 }
132
133 /**
134 * Marks the tracking notice as dismissed without resetting initialization state.
135 *
136 * @return void
137 */
138 public static function dismiss_modal_key(): void {
139 update_site_option( self::TRACKING_SLUG, false );
140 }
141
142 /**
143 * Deletes the site option that controls the visibility of the tracking modal.
144 */
145 public static function delete_modal_key(): void {
146 delete_site_option( self::TRACKING_SLUG );
147 }
148
149 /**
150 * Conditions of the Tracking modal:
151 * 1)show on all Defender pages.
152 * 2)show to users upgrading from older versions.
153 * 3)should have higher priority than a Welcome modal on the Defender > Dashboard page.
154 * 4)if user closes or clicks on the Save button on one plugin page, we don't itl on another plugin page.
155 * 5)no display after the updated Onboarding with Opt-in.
156 * 6)no display when Whitelabel > Documentation, Tutorials and What’s New Modal is set to “Hide”
157 *
158 * @return bool
159 */
160 public function show_tracking_modal() {
161 $info = defender_white_label_status();
162
163 $white_label_is_hide = isset( $info['hide_doc_link'] ) && $info['hide_doc_link'];
164
165 return (bool) get_site_option( self::TRACKING_SLUG ) && ! $white_label_is_hide;
166 }
167
168 /**
169 * Delete all the data & the cache.
170 */
171 public function remove_data() {
172 self::delete_modal_key();
173 delete_site_option( self::DASHBOARD_NOTICE_SLUG );
174 delete_site_option( self::DASHBOARD_NOTICE_INITIALIZED_SLUG );
175 }
176
177 /**
178 * Exports strings.
179 *
180 * @return array An array of strings.
181 */
182 public function export_strings(): array {
183 return array();
184 }
185
186 /**
187 * Converts the object data to an array.
188 *
189 * @return array An array representation of the object.
190 */
191 public function to_array(): array {
192 return array();
193 }
194
195 /**
196 * Imports data into the model.
197 *
198 * @param array $data Data to be imported into the model.
199 *
200 * @throws Exception If table is not defined.
201 */
202 public function import_data( array $data ) {
203 }
204
205 /**
206 * Removes settings for all submodules.
207 */
208 public function remove_settings(): void {
209 self::delete_modal_key();
210 delete_site_option( self::DASHBOARD_NOTICE_SLUG );
211 delete_site_option( self::DASHBOARD_NOTICE_INITIALIZED_SLUG );
212 }
213
214 /**
215 * Provides data for the frontend.
216 *
217 * @return array An array of data for the frontend.
218 */
219 public function data_frontend(): array {
220 return array();
221 }
222
223 /**
224 * Initializes the dashboard notice lifecycle once.
225 *
226 * A dedicated marker distinguishes an intentionally consumed false value
227 * from an option that an older or interrupted upgrade failed to seed.
228 *
229 * @return void
230 */
231 public static function initialize_dashboard_notice(): void {
232 if ( (bool) get_site_option( self::DASHBOARD_NOTICE_INITIALIZED_SLUG ) ) {
233 return;
234 }
235
236 $usage_tracking = wd_di()->get( Main_Setting::class )->usage_tracking;
237 delete_site_option( self::DASHBOARD_NOTICE_SLUG );
238 add_site_option( self::DASHBOARD_NOTICE_SLUG, ! $usage_tracking );
239 update_site_option( self::DASHBOARD_NOTICE_INITIALIZED_SLUG, true );
240 }
241
242 /**
243 * Returns whether the dashboard share usage notice should be displayed.
244 *
245 * @return bool
246 */
247 public function should_show_dashboard_notice(): bool {
248 $notice_option = (bool) get_site_option( self::DASHBOARD_NOTICE_SLUG );
249
250 // Falsey means not eligible or already displayed.
251 if ( ! $notice_option ) {
252 return false;
253 }
254
255 // Truthy means eligible; also guard against already opted-in.
256 return ! wd_di()->get( Main_Setting::class )->usage_tracking;
257 }
258
259 /**
260 * Returns dashboard notice data and routes for the share usage bubble.
261 *
262 * @return array
263 */
264 public function get_dashboard_notice_data(): array {
265 self::initialize_dashboard_notice();
266 $result = $this->dump_routes_and_nonces();
267
268 return array(
269 'shareUsageNotice' => array(
270 'isVisible' => $this->should_show_dashboard_notice(),
271 ),
272 'routes' => $result['routes'],
273 'nonces' => $result['nonces'],
274 );
275 }
276
277 /**
278 * Marks the share usage dashboard notice as already shown.
279 *
280 * @return Response
281 * @defender_route
282 */
283 public function mark_track_notice_displayed(): Response {
284 update_site_option( self::DASHBOARD_NOTICE_SLUG, false );
285
286 return new Response( true, array() );
287 }
288 }
289