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