| | 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 | } |