| 6130 | |
| 6131 | /** |
| 6132 | * Return an anonymized IPV4 or IPV6 address. |
| 6133 | * |
| 6134 | * @since 5.0.0 |
| 6135 | * |
| 6136 | * @param string $ip_addr The IPv4 or IPv6 address to be anonymized. |
| 6137 | * @return string The anonymized IP address. |
| 6138 | */ |
| 6139 | function wp_privacy_anonymize_ip( $ip_addr ) { |
| 6140 | $ip_prefix = ''; |
| 6141 | $is_ipv4 = ( 3 === substr_count( $ip_addr, '.' ) ); |
| 6142 | $is_ipv6 = substr_count( $ip_addr, ':' ) > 1; |
| 6143 | |
| 6144 | if ( $is_ipv6 && $is_ipv4 ) { |
| 6145 | // IPv6 compatibility mode, temporarily strip the IPv6 part, and treat it like IPv4. |
| 6146 | $ip_prefix = '::ffff:'; |
| 6147 | $ip_addr = preg_replace( '/^\[?[0-9a-f:]*:/i', '', $ip_addr ); |
| 6148 | $ip_addr = str_replace( ']', '', $ip_addr ); |
| 6149 | $is_ipv6 = false; |
| 6150 | } |
| 6151 | |
| 6152 | if ( $is_ipv6 ) { |
| 6153 | // IPv6 addresses will always be enclosed in [] if there's a port. |
| 6154 | $ip_start = 1; |
| 6155 | $ip_end = (int) strpos( $ip_addr, ']' ) - 1; |
| 6156 | $netmask = 'ffff:ffff:ffff:ffff:0000:0000:0000:0000'; |
| 6157 | |
| 6158 | // Strip the port (and [] from IPv6 addresses), if they exist. |
| 6159 | if ( $ip_end > 0 ) { |
| 6160 | $ip_addr = substr( $ip_addr, $ip_start, $ip_end ); |
| 6161 | } |
| 6162 | |
| 6163 | // Partially anonymize the IP by reducing it to the corresponding network ID. |
| 6164 | // This basically zeros the last eight octets of an IPV6 address. |
| 6165 | // Note inet_pton and inet_ntop were not available on Windows platforms until PHP 5.3.0. |
| 6166 | if ( function_exists( 'inet_pton' ) && function_exists( 'inet_ntop' ) ) { |
| 6167 | $ip_addr = inet_ntop( inet_pton( $ip_addr ) & inet_pton( $netmask ) ); |
| 6168 | } else { |
| 6169 | return '0.0.0.0'; |
| 6170 | } |
| 6171 | } elseif ( $is_ipv4 ) { |
| 6172 | // Strip any port and partially anonymize the IP. |
| 6173 | $last_octet_position = strrpos( $ip_addr, '.' ); |
| 6174 | $ip_addr = substr( $ip_addr, 0, $last_octet_position ) . '.0'; |
| 6175 | } else { |
| 6176 | return '0.0.0.0'; |
| 6177 | } |
| 6178 | |
| 6179 | // Restore the IPv6 prefix to compatibility mode addresses. |
| 6180 | return $ip_prefix . $ip_addr; |
| 6181 | } |
| 6182 | |
| 6183 | /** |
| 6184 | * Return uniform "anonymous" data by type. |
| 6185 | * |
| 6186 | * @since 5.0.0 |
| 6187 | * |
| 6188 | * @param string $data Optional The data to be anonymized. |
| 6189 | * @param string $type Optional The type of data to be anonymized. |
| 6190 | * @return string The anonymous data for the requested type. |
| 6191 | */ |
| 6192 | function wp_privacy_anonymize_data( $data = '', $type = '' ) { |
| 6193 | |
| 6194 | switch ( $type ) { |
| 6195 | case 'email': |
| 6196 | $anonymous = 'deleted@site.invalid'; |
| 6197 | break; |
| 6198 | case 'url': |
| 6199 | $anonymous = 'https://site.invalid'; |
| 6200 | break; |
| 6201 | case 'ip': |
| 6202 | $anonymous = wp_privacy_anonymize_ip( $data ); |
| 6203 | break; |
| 6204 | case 'date': |
| 6205 | $anonymous = '0000-00-00 00:00:00'; |
| 6206 | break; |
| 6207 | case 'text': |
| 6208 | /* translators: deleted text */ |
| 6209 | $anonymous = __( '[deleted]' ); |
| 6210 | break; |
| 6211 | case 'longtext': |
| 6212 | /* translators: deleted long text */ |
| 6213 | $anonymous = __( 'This content was deleted by the author.' ); |
| 6214 | break; |
| 6215 | default: |
| 6216 | $anonymous = ''; |
| 6217 | } |
| 6218 | |
| 6219 | /** |
| 6220 | * Filters the anonymous data for each type. |
| 6221 | * |
| 6222 | * @since 5.0.0 |
| 6223 | * |
| 6224 | * @param string $anonymous Anonymized data. |
| 6225 | * @param string $data Original data. |
| 6226 | * @param string $type Type of the data. |
| 6227 | */ |
| 6228 | return apply_filters( 'wp_privacy_anonymize_data', $anonymous, $data, $type ); |
| 6229 | } |