Spaces:
Running
Running
| declare(strict_types=1); | |
| namespace App\Domain\Analytics; | |
| /** | |
| * Coarsens an IP address before any persistence. | |
| * Raw IPs are never stored β only the anonymised form is passed to the job. | |
| * | |
| * IPv4: zeros the last octet 1.2.3.4 β 1.2.3.0 | |
| * IPv6: keeps the first 48 bits 2001:db8::1 β 2001:db8::/48 prefix as string | |
| * Invalid / empty: returns '0.0.0.0' | |
| */ | |
| final class AnalyticsIpAnonymizer | |
| { | |
| public static function coarsen(string $ip): string | |
| { | |
| $ip = trim($ip); | |
| if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) { | |
| $parts = explode('.', $ip); | |
| $parts[3] = '0'; | |
| return implode('.', $parts); | |
| } | |
| if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) { | |
| // Expand to full 128-bit representation, keep first 48 bits (/48 prefix). | |
| $packed = inet_pton($ip); | |
| if ($packed === false) { | |
| return '0.0.0.0'; | |
| } | |
| // Zero bytes 7β15 (keep bytes 0β5, 48 bits) | |
| $zeroed = substr($packed, 0, 6) . str_repeat("\x00", 10); | |
| return inet_ntop($zeroed) . '/48'; | |
| } | |
| return '0.0.0.0'; | |
| } | |
| } | |