query($sql); if ($result && $result->num_rows > 0) { $row = $result->fetch_object(); return (int)$row->customer_group_id; } return 0; } /** * Erzeugt ein kryptographisch zufälliges Token (Hex). */ public static function generate_token() { return bin2hex(random_bytes(REVOCATION_TOKEN_BYTES)); } /** * SHA-256 des Klartext-Tokens. Nur dieser Hash wird persistiert. */ public static function hash_token($token_plain) { return hash('sha256', $token_plain); } /** * Baut die vollständige Widerrufs-URL für eine Bestell-Mail. */ public static function build_link($token_plain, $host = null) { if ($host === null) { $host = (isset($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'www.intelectra.de'; } return 'https://' . $host . REVOCATION_LANDING_PATH . '?t=' . urlencode($token_plain); } /** * DSGVO-konforme IP-Anonymisierung. * IPv4: letztes Oktett auf 0 (/24) * IPv6: letzte 80 Bits auf 0 (/48) * Ungültige Eingabe → NULL. */ public static function anonymize_ip($ip) { if (empty($ip)) { return null; } if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { $parts = explode('.', $ip); $parts[3] = '0'; return implode('.', $parts); } if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { $bin = inet_pton($ip); if ($bin === false) return null; // /48: erste 6 Bytes behalten, Rest auf 0 $masked = substr($bin, 0, 6) . str_repeat("\0", 10); return inet_ntop($masked); } return null; } /** * Berechnet den expires_at-Timestamp ab einem Basis-Datum. * $base_date: 'YYYY-MM-DD' aus orders.order_date, oder null → jetzt. */ public static function calc_expires_at($base_date = null) { $days = (int) REVOCATION_TOKEN_VALIDITY_DAYS; if (!empty($base_date)) { $ts = strtotime($base_date); if ($ts === false) $ts = time(); } else { $ts = time(); } return date('Y-m-d H:i:s', $ts + $days * 86400); } }