PluginProbe ʕ •ᴥ•ʔ
Hustle – Email Marketing, Lead Generation, Optins, Popups / 7.8.14.1
Hustle – Email Marketing, Lead Generation, Optins, Popups v7.8.14.1
7.8.14 7.8.14.1 7.8.13 7.8.13.1 trunk 3.0 3.1 3.1.1 3.1.2 3.1.3 3.1.4 4.3.2 4.4.4 4.4.5 4.4.5.1 4.4.5.4 4.6 4.6.1.1 4.6.1.4 4.7.0.2 4.7.0.3 4.7.0.7 4.7.0.9 4.7.1.0 4.7.1.1 4.8.0.0 5.0.0 5.0.1 5.0.1.1 5.0.1.2 5.1 5.1.1 5.1.2 5.1.3 5.1.3.1 5.1.3.2 5.1.4 5.1.5 6.0 6.0.1 6.0.2 6.0.3 6.0.4.2 6.0.5 6.0.6.1 6.0.7 6.0.8.1 6.0.9 7.0.0.1 7.0.2 7.0.3 7.0.4 7.1.0 7.1.1 7.2.0 7.2.1 7.3.0 7.3.1 7.3.3 7.3.5 7.3.6 7.3.7 7.4.0 7.4.1 7.4.11 7.4.13 7.4.13.1 7.4.2 7.4.3 7.4.4 7.4.5 7.4.5.1 7.4.5.2 7.4.6 7.4.7 7.5.0 7.6.0 7.6.1 7.6.3 7.6.4 7.6.6 7.7.0 7.7.1 7.8.0 7.8.1 7.8.10 7.8.10.1 7.8.10.2 7.8.11 7.8.12 7.8.12.1 7.8.2 7.8.3 7.8.4 7.8.5 7.8.6 7.8.7 7.8.8 7.8.9 7.8.9.1 7.8.9.2 7.8.9.3
wordpress-popup / inc / hustle-general-data-protection.php
wordpress-popup / inc Last commit date
display-conditions 5 months ago front 2 days ago helpers 1 month ago metas 3 months ago multisite 5 months ago palettes 3 years ago provider 1 month ago providers 2 days ago templates 3 years ago update 5 months ago class-hustle-admin-page-abstract.php 1 month ago class-hustle-auth-token.php 5 months ago class-hustle-condition-factory.php 6 years ago class-hustle-cross-sell.php 10 months ago class-hustle-dashboard-admin.php 1 month ago class-hustle-data.php 1 month ago class-hustle-db.php 2 years ago class-hustle-installer.php 4 years ago class-hustle-meta.php 3 years ago class-hustle-module-admin.php 1 month ago class-hustle-module-collection.php 5 months ago class-hustle-module-fields.php 3 months ago class-hustle-module-page-abstract.php 1 month ago class-hustle-module-validator.php 3 months ago class-hustle-notifications.php 2 days ago class-hustle-settings-admin.php 1 month ago class-hustle-wp-dashboard-page.php 5 months ago class-opt-in.php 2 days ago hustle-background-conversion-log.php 3 months ago hustle-deletion.php 3 months ago hustle-embedded-admin.php 3 years ago hustle-entries-admin.php 5 months ago hustle-entry-model.php 1 month ago hustle-general-data-protection.php 5 months ago hustle-init.php 1 month ago hustle-mail.php 5 months ago hustle-migration.php 5 months ago hustle-model.php 2 days ago hustle-module-model.php 1 month ago hustle-module-widget-legacy.php 5 months ago hustle-module-widget.php 5 months ago hustle-modules-common-admin-ajax.php 1 month ago hustle-popup-admin.php 3 years ago hustle-providers-admin.php 1 month ago hustle-providers.php 5 months ago hustle-settings-admin-ajax.php 1 month ago hustle-settings-page.php 3 years ago hustle-slidein-admin.php 3 years ago hustle-sshare-admin.php 2 days ago hustle-sshare-model.php 2 days ago hustle-tracking-model.php 3 months ago interface-hustle-auth-provider.php 5 months ago opt-in-geo.php 5 months ago opt-in-utils.php 2 days ago opt-in-wpmudev-api.php 5 months ago
hustle-general-data-protection.php
474 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Hustle_General_Data_Protection
4 *
5 * @package Hustle
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 die();
10 }
11
12 /**
13 * Class Hustle_General_Data_Protection
14 *
15 * @since 4.0.2
16 */
17 class Hustle_General_Data_Protection {
18
19 /**
20 * Clean up interval in string
21 *
22 * @var string
23 */
24 protected $cron_cleanup_interval;
25
26 /**
27 * Privacy settings array
28 *
29 * @var array
30 */
31 private static $privacy_settings = array();
32
33 /**
34 * Constructor.
35 *
36 * @param string $cron_cleanup_interval Cron interval.
37 */
38 public function __construct( $cron_cleanup_interval = 'hourly' ) {
39 $this->cron_cleanup_interval = $cron_cleanup_interval;
40 $this->init();
41 }
42
43 /**
44 * Init
45 */
46 protected function init() {
47
48 // for data removal / anonymize data.
49 if ( ! wp_next_scheduled( 'hustle_general_data_protection_cleanup' ) ) {
50 wp_schedule_event( time(), $this->get_cron_cleanup_interval(), 'hustle_general_data_protection_cleanup' );
51 }
52
53 add_action( 'hustle_general_data_protection_cleanup', array( $this, 'personal_data_cleanup' ) );
54 add_filter( 'wp_privacy_personal_data_erasers', array( $this, 'register_eraser' ), 10 );
55 add_filter( 'wp_privacy_personal_data_exporters', array( $this, 'register_exporter' ), 10 );
56 }
57
58 /**
59 * Append registered eraser to wp eraser
60 *
61 * @param array $erasers Erasers.
62 *
63 * @since 4.0.2
64 *
65 * @return array
66 */
67 public function register_eraser( $erasers = array() ) {
68 $erasers['hustle-module-submissions'] = array(
69 /* translators: Plugin name */
70 'eraser_friendly_name' => esc_html( sprintf( __( '%s Module Submissions', 'hustle' ), Opt_In_Utils::get_plugin_name() ) ),
71 'callback' => array( 'Hustle_General_Data_Protection', 'do_submissions_eraser' ),
72 );
73 return $erasers;
74 }
75
76 /**
77 * Append registered eraser to wp eraser
78 *
79 * @param array $exporter Exporter.
80 *
81 * @since 4.0.2
82 *
83 * @return array
84 */
85 public function register_exporter( $exporter = array() ) {
86 $exporter['hustle-module-submissions'] = array(
87 'exporter_friendly_name' => /* translators: Plugin name */ esc_html( sprintf( __( '%s Module Submissions', 'hustle' ), Opt_In_Utils::get_plugin_name() ) ),
88 'callback' => array( 'Hustle_General_Data_Protection', 'do_submissions_exporter' ),
89 );
90 return $exporter;
91 }
92
93 /**
94 * Get Interval
95 *
96 * @since 4.0.2
97 *
98 * @return string
99 */
100 public function get_cron_cleanup_interval() {
101 $cron_cleanup_interval = $this->cron_cleanup_interval;
102
103 /**
104 * Filter interval to be used for cleanup process
105 *
106 * @since 4.0.2
107 *
108 * @params string $cron_cleanup_interval interval in string (daily,hourly, etc)
109 */
110 $cron_cleanup_interval = apply_filters( 'hustle_general_data_cleanup_interval', $cron_cleanup_interval );
111
112 return $cron_cleanup_interval;
113 }
114
115 /**
116 * Eraser
117 *
118 * @since 4.0.2
119 *
120 * @param string $email Email.
121 * @param int $page Page.
122 *
123 * @return array
124 */
125 public static function do_submissions_eraser( $email, $page ) {
126
127 $settings = self::get_privacy_settings();
128
129 $erasure_disabled = '1' === $settings['retain_sub_on_erasure'];
130
131 $response = array(
132 'items_removed' => false,
133 'items_retained' => true,
134 'messages' => array(),
135 'done' => true,
136 );
137
138 if ( true === $erasure_disabled ) {
139 /* translators: Plugin name */
140 $response['messages'][] = esc_html( sprintf( __( '%s Module Submissions were retained.', 'hustle' ), Opt_In_Utils::get_plugin_name() ) );
141 return $response;
142 }
143
144 $entry_ids = Hustle_Entry_Model::get_entries_by_email( $email );
145
146 // using action instead of filter here to stop data manipulation.
147 do_action( 'hustle_before_submission_eraser', $email, $page, $entry_ids );
148
149 if ( ! empty( $entry_ids ) ) {
150 foreach ( $entry_ids as $entry_id ) {
151 $entry_model = new Hustle_Entry_Model( $entry_id );
152 Hustle_Entry_Model::delete_by_entry( $entry_model->module_id, $entry_id );
153 /* translators: 1. Plugin name 2. entry id */
154 $response['messages'][] = esc_html( sprintf( __( '%1$s submission #%2$d was deleted.', 'hustle' ), Opt_In_Utils::get_plugin_name(), $entry_id ) );
155
156 }
157 $response['items_removed'] = true;
158 $response['items_retained'] = false;
159 } else {
160 /* translators: Plugin name */
161 $response['messages'][] = esc_html( sprintf( __( ' %s submissions not found.', 'hustle' ), Opt_In_Utils::get_plugin_name() ) );
162 }
163
164 // using action instead of filter here to stop data manipulation.
165 do_action( 'hustle_after_submission_eraser', $email, $page, $entry_ids );
166
167 return $response;
168 }
169
170 /**
171 * Export module submissions
172 *
173 * @since 4.0.2
174 *
175 * @param string $email Email.
176 * @param int $page Page.
177 *
178 * @return array
179 */
180 public static function do_submissions_exporter( $email, $page ) {
181 $entry_ids = Hustle_Entry_Model::get_entries_by_email( $email );
182 $data_to_export = array();
183
184 if ( ! empty( $entry_ids ) && is_array( $entry_ids ) ) {
185 foreach ( $entry_ids as $entry_id ) {
186 $entry_model = new Hustle_Entry_Model( $entry_id );
187
188 $data = array();
189
190 if ( is_object( $entry_model ) ) {
191 $data = self::get_custom_form_export_mappers( $entry_model );
192 }
193
194 $data_to_export[] = array(
195 'group_id' => 'hustle_module_submissions',
196 'group_label' => /* translators: Plugin name */ esc_html( sprintf( __( '%s Module Submissions', 'hustle' ), Opt_In_Utils::get_plugin_name() ) ),
197 'item_id' => 'entry-' . $entry_id,
198 'data' => $data,
199 );
200 }
201 }
202
203 /**
204 * Filter Export data for Custom form submission on tools.php?page=export_personal_data
205 *
206 * @since 4.0.2
207 *
208 * @param array $data_to_export
209 * @param string $email
210 * @param array $entry_ids
211 */
212 $data_to_export = apply_filters( 'hustle_module_submissions_export_data', $data_to_export, $email, $entry_ids );
213
214 return array(
215 'data' => $data_to_export,
216 'done' => true,
217 );
218 }
219
220 /**
221 * Get data mappers and their values
222 *
223 * @since 4.0.2
224 *
225 * @param Hustle_Entry_Model $model Model.
226 *
227 * @return array
228 */
229 public static function get_custom_form_export_mappers( $model ) {
230
231 $meta = $model->meta_data;
232
233 $mappers = array(
234 array(
235 'name' => __( 'Entry ID', 'hustle' ),
236 'value' => $model->entry_id,
237 ),
238 array(
239 'name' => __( 'Submission Date', 'hustle' ),
240 'value' => $model->date_created_sql,
241 ),
242 );
243
244 if ( ! empty( $meta ) ) {
245 foreach ( $meta as $key => $value ) {
246 // base mapper for every field.
247 if ( is_array( $value['value'] ) ) {
248 continue;
249 }
250
251 $mapper = array();
252 $mapper['meta_key'] = $key;// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
253 $mapper['name'] = $key;
254 $mapper['value'] = $value['value'];
255
256 if ( ! empty( $mapper ) ) {
257 $mappers[] = $mapper;
258 }
259 }
260 }
261
262 return $mappers;
263 }
264
265 /**
266 * Anonymizing data
267 *
268 * @since 4.0.2
269 *
270 * @return bool
271 */
272 public function personal_data_cleanup() {
273
274 $settings = self::get_privacy_settings();
275
276 $this->cleanup_submissions( $settings );
277 $this->cleanup_ip_address( $settings );
278 $this->cleanup_tracking_data( $settings );
279
280 return true;
281 }
282
283 /**
284 * Clean up form submissions
285 *
286 * @since 4.0.2
287 *
288 * @param array $settings privacy settings.
289 *
290 * @return bool
291 */
292 private function cleanup_submissions( $settings ) {
293
294 $retain_number = $settings['submissions_retention_number'];
295 $retain_unit = $settings['submissions_retention_number_unit'];
296
297 if ( '1' === $settings['retain_submission_forever'] || 0 === $retain_number ) {
298 return false;
299 }
300
301 $possible_units = array(
302 'days',
303 'weeks',
304 'months',
305 'years',
306 );
307
308 if ( ! in_array( $retain_unit, $possible_units, true ) ) {
309 return false;
310 }
311
312 $retain_time = strtotime( '-' . $retain_number . ' ' . $retain_unit );
313 $retain_time = date_i18n( 'Y-m-d H:i:s', $retain_time );
314
315 $entry_ids = Hustle_Entry_Model::get_older_entry_ids( $retain_time );
316
317 foreach ( $entry_ids as $entry_id ) {
318 $entry_model = new Hustle_Entry_Model( $entry_id );
319 Hustle_Entry_Model::delete_by_entry( $entry_model->module_id, $entry_id );
320 }
321
322 return true;
323 }
324
325 /**
326 * Cleanup IP Address based on settings
327 *
328 * @since 4.0.2
329 *
330 * @param array $settings privacy settings.
331 *
332 * @return bool
333 */
334 private function cleanup_ip_address( $settings ) {
335
336 $retain_number = $settings['ip_retention_number'];
337 $retain_unit = $settings['ip_retention_number_unit'];
338
339 if ( '1' === $settings['retain_ip_forever'] || 0 === $retain_number ) {
340 return false;
341 }
342
343 $possible_units = array(
344 'days',
345 'weeks',
346 'months',
347 'years',
348 );
349
350 if ( ! in_array( $retain_unit, $possible_units, true ) ) {
351 return false;
352 }
353
354 $retain_time = strtotime( '-' . $retain_number . ' ' . $retain_unit );
355 $retain_time = date_i18n( 'Y-m-d H:i:s', $retain_time );
356
357 $entry_ids = Hustle_Entry_Model::get_older_entry_ids( $retain_time );
358 $tracking_ids = Hustle_Tracking_Model::get_older_tracking_ids( $retain_time );
359
360 foreach ( $entry_ids as $entry_id ) {
361 $entry_model = new Hustle_Entry_Model( $entry_id );
362 $this->anonymize_entry_model( $entry_model );
363 }
364
365 foreach ( $tracking_ids as $tracking_id ) {
366 $this->anonymize_tracking_model( $tracking_id );
367 }
368
369 return true;
370 }
371
372 /**
373 * Anon Entry model IP
374 *
375 * @since 4.0.2
376 *
377 * @param Hustle_Entry_Model $entry_model Entry model.
378 */
379 private function anonymize_entry_model( Hustle_Entry_Model $entry_model ) {
380 if ( isset( $entry_model->meta_data['hustle_ip'] ) ) {
381 $meta_id = $entry_model->meta_data['hustle_ip']['id'];
382 $meta_value = $entry_model->meta_data['hustle_ip']['value'];
383
384 if ( function_exists( 'wp_privacy_anonymize_ip' ) ) {
385 $anon_value = wp_privacy_anonymize_ip( $meta_value );
386 } else {
387 $anon_value = '';
388 }
389
390 if ( $anon_value !== $meta_value ) {
391 $entry_model->update_meta( $meta_id, 'hustle_ip', $anon_value );
392 }
393 }
394 }
395
396 /**
397 * Cleanup tracking data
398 *
399 * @since 4.0.2
400 * @param array $settings privacy settings.
401 * @return bool
402 */
403 private function cleanup_tracking_data( $settings ) {
404
405 $retain_number = $settings['tracking_retention_number'];
406 $retain_unit = $settings['tracking_retention_number_unit'];
407
408 if ( '1' === $settings['retain_tracking_forever'] || 0 === $retain_number ) {
409 return false;
410 }
411
412 $possible_units = array(
413 'days',
414 'weeks',
415 'months',
416 'years',
417 );
418
419 if ( ! in_array( $retain_unit, $possible_units, true ) ) {
420 return false;
421 }
422
423 $retain_time = strtotime( '-' . $retain_number . ' ' . $retain_unit );
424 $retain_time = date_i18n( 'Y-m-d H:i:s', $retain_time );
425
426 $tracking_ids = Hustle_Tracking_Model::get_older_tracking_ids( $retain_time );
427
428 foreach ( $tracking_ids as $tracking_id ) {
429 Hustle_Tracking_Model::delete_data_by_tracking_id( $tracking_id );
430 }
431
432 return true;
433 }
434
435 /**
436 * Get privacy settings
437 *
438 * @since 4.0.2
439 *
440 * @return settings array()
441 */
442 private static function get_privacy_settings() {
443 if ( empty( self::$privacy_settings ) ) {
444 self::$privacy_settings = Hustle_Settings_Admin::get_privacy_settings();
445 }
446 return self::$privacy_settings;
447 }
448
449 /**
450 * Anon Tracking model IP
451 *
452 * @since 4.0.2
453 *
454 * @param string $tracking tracking id.
455 */
456 private function anonymize_tracking_model( $tracking ) {
457 if ( ! empty( $tracking ) ) {
458
459 $ip = Hustle_Tracking_Model::get_ip_from_tracking_id( $tracking );
460
461 if ( ! empty( $ip ) ) {
462
463 if ( function_exists( 'wp_privacy_anonymize_ip' ) ) {
464 $anon_value = wp_privacy_anonymize_ip( $ip[0] );
465 } else {
466 $anon_value = '';
467 }
468
469 Hustle_Tracking_Model::anonymise_tracked_id( $tracking, $anon_value );
470 }
471 }
472 }
473 }
474