1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Personal data erasers. |
4
|
|
|
* |
5
|
|
|
* @since 1.6.26 |
6
|
|
|
* @package GeoDirectory |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
defined( 'ABSPATH' ) || exit; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* GeoDir_Privacy_Erasers Class. |
13
|
|
|
*/ |
14
|
|
|
class GeoDir_Privacy_Erasers { |
15
|
|
|
/** |
16
|
|
|
* Finds and erases data which could be used to identify a person from GeoDirectory data assocated with an email address. |
17
|
|
|
* |
18
|
|
|
* Posts are erased in blocks of 10 to avoid timeouts. |
19
|
|
|
* |
20
|
|
|
* @since 1.6.26 |
21
|
|
|
* @param string $email_address The user email address. |
22
|
|
|
* @param int $page Page. |
23
|
|
|
* @return array An array of personal data in name value pairs |
24
|
|
|
*/ |
25
|
|
|
public static function post_data_eraser( $email_address, $page ) { |
26
|
|
|
$page = (int) $page; |
27
|
|
|
$user = get_user_by( 'email', $email_address ); // Check if user has an ID in the DB to load stored personal data. |
28
|
|
|
|
29
|
|
|
$erasure_enabled = get_option( 'geodir_erasure_request_removes_post_data', false ); |
30
|
|
|
|
31
|
|
|
$response = array( |
32
|
|
|
'items_removed' => false, |
33
|
|
|
'items_retained' => false, |
34
|
|
|
'messages' => array(), |
35
|
|
|
'done' => true, |
36
|
|
|
); |
37
|
|
|
|
38
|
|
|
$post_query = array( |
39
|
|
|
'limit' => 10, |
40
|
|
|
'page' => $page, |
41
|
|
|
'user' => array( $email_address ), |
42
|
|
|
); |
43
|
|
|
|
44
|
|
|
if ( $user instanceof WP_User ) { |
|
|
|
|
45
|
|
|
$post_query['user'][] = (int) $user->ID; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
$posts = array(); |
49
|
|
|
|
50
|
|
|
if ( 0 < count( $posts ) ) { |
51
|
|
|
foreach ( $posts as $post ) { |
52
|
|
|
if ( apply_filters( 'geodir_privacy_erase_post_personal_data', $erasure_enabled, $post ) ) { |
53
|
|
|
self::remove_post_personal_data( $post ); |
54
|
|
|
|
55
|
|
|
/* Translators: %s Post number. */ |
56
|
|
|
$response['messages'][] = sprintf( __( 'Removed personal data from post %s.', 'geodirectory' ), $post->ID ); |
57
|
|
|
$response['items_removed'] = true; |
58
|
|
|
} else { |
59
|
|
|
/* Translators: %s Post number. */ |
60
|
|
|
$response['messages'][] = sprintf( __( 'Personal data within post %s has been retained.', 'geodirectory' ), $post->ID ); |
61
|
|
|
$response['items_retained'] = true; |
62
|
|
|
} |
63
|
|
|
} |
64
|
|
|
$response['done'] = 10 > count( $posts ); |
65
|
|
|
} else { |
66
|
|
|
$response['done'] = true; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
return $response; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Remove personal data specific to GeoDirectory from an post object. |
74
|
|
|
* |
75
|
|
|
* Note; this will hinder post processing for obvious reasons! |
76
|
|
|
* |
77
|
|
|
* @param WP_Post $post Post object. |
78
|
|
|
*/ |
79
|
|
|
public static function remove_post_personal_data( $post ) { |
80
|
|
|
$anonymized_data = array(); |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Allow extensions to remove their own personal data for this post first, so post data is still available. |
84
|
|
|
* |
85
|
|
|
* @since 1.6.26 |
86
|
|
|
* @param WP_Post $post A post object. |
87
|
|
|
*/ |
88
|
|
|
do_action( 'geodir_privacy_before_remove_post_personal_data', $post ); |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Expose props and data types we'll be anonymizing. |
92
|
|
|
* |
93
|
|
|
* @since 1.6.26 |
94
|
|
|
* @param array $props Keys are the prop names, values are the data type we'll be passing to wp_privacy_anonymize_data(). |
95
|
|
|
* @param WP_Post $post A post object. |
96
|
|
|
*/ |
97
|
|
|
$props_to_remove = apply_filters( 'geodir_privacy_remove_post_personal_data_props', array( |
98
|
|
|
'phone' => 'phone', |
99
|
|
|
'email' => 'email' |
100
|
|
|
// TODO more fields |
101
|
|
|
), $post ); |
102
|
|
|
|
103
|
|
|
if ( ! empty( $props_to_remove ) && is_array( $props_to_remove ) ) { |
104
|
|
|
foreach ( $props_to_remove as $prop => $data_type ) { |
105
|
|
|
// Get the current value in edit context. |
106
|
|
|
$value = isset( $post->{$prop} ) ? $post->{$prop} : ''; |
107
|
|
|
|
108
|
|
|
// If the value is empty, it does not need to be anonymized. |
109
|
|
|
if ( empty( $value ) || empty( $data_type ) ) { |
110
|
|
|
continue; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
$anon_value = wp_privacy_anonymize_data( $data_type, $value ); |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Expose a way to control the anonymized value of a prop via 3rd party code. |
117
|
|
|
* |
118
|
|
|
* @since 1.6.26 |
119
|
|
|
* @param bool $anonymized_data Value of this prop after anonymization. |
120
|
|
|
* @param string $prop Name of the prop being removed. |
121
|
|
|
* @param string $value Current value of the data. |
122
|
|
|
* @param string $data_type Type of data. |
123
|
|
|
* @param WP_Post $post The post object. |
124
|
|
|
*/ |
125
|
|
|
$anonymized_data[ $prop ] = apply_filters( 'geodir_privacy_remove_post_personal_data_prop_value', $anon_value, $prop, $value, $data_type, $post ); |
126
|
|
|
} |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
// Set all new props and persist the new data to the database. |
130
|
|
|
//$post->set_props( $anonymized_data ); // TODO |
|
|
|
|
131
|
|
|
//$post->update_meta_data( '_anonymized', 'yes' ); // TODO |
|
|
|
|
132
|
|
|
//$post->save(); // TODO |
|
|
|
|
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* Allow extensions to remove their own personal data for this post. |
136
|
|
|
* |
137
|
|
|
* @since 1.6.26 |
138
|
|
|
* @param WP_Post $post The post object. |
139
|
|
|
*/ |
140
|
|
|
do_action( 'geodir_privacy_remove_post_personal_data', $post ); |
141
|
|
|
} |
142
|
|
|
} |
143
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.