feat: use country code prefix in visitor IDs (PL1, SG3 instead of #K7)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-04 15:44:47 +00:00
parent 046dd67c1a
commit 24130e28e0

View File

@@ -68,20 +68,23 @@ class VisitorNickname
];
/**
* Generate a short deterministic ID suffix from an IP address.
* Generate a short deterministic ID suffix from an IP + country.
*
* Same IP always produces the same suffix. Used to distinguish
* visitors with the same behavior label.
* Format: CC + number (e.g. "PL1", "SG3", "US7").
* Same IP always produces the same suffix.
*
* @param string $ip IP address (v4 or v6)
* @return string e.g. "K7", "M3" — uppercase letter + digit
* @param string $ip IP address (v4 or v6)
* @param string $countryCode 2-letter country code (e.g. "PL")
* @return string e.g. "PL1", "SG3"
*/
public static function shortId(string $ip): string
public static function shortId(string $ip, string $countryCode = ''): string
{
$hash = crc32($ip) & 0xFFFFFFFF;
$letter = chr(65 + ($hash % 26)); // A-Z
$digit = ($hash >> 5) % 10; // 0-9
return $letter . $digit;
$cc = strtoupper(trim($countryCode));
if (strlen($cc) !== 2) {
$cc = 'XX';
}
$num = (crc32($ip) & 0xFFFFFFFF) % 100; // 0-99
return $cc . $num;
}
/**
@@ -202,13 +205,14 @@ class VisitorNickname
*
* Priority: order > cart > demo download > demo boot > returning visitor > visitor
*
* @param array $tags Output of behaviorTags()
* @param int $pages Total pages viewed
* @param int $sessions Number of sessions
* @param string $ip IP address (for unique suffix)
* @return string Human-readable label, e.g. "Cart Abandoner #K7"
* @param array $tags Output of behaviorTags()
* @param int $pages Total pages viewed
* @param int $sessions Number of sessions
* @param string $ip IP address (for unique suffix)
* @param string $countryCode 2-letter country code
* @return string Human-readable label, e.g. "Cart Abandoner PL1"
*/
public static function primaryLabel(array $tags, int $pages = 0, int $sessions = 0, string $ip = ''): string
public static function primaryLabel(array $tags, int $pages = 0, int $sessions = 0, string $ip = '', string $countryCode = ''): string
{
// Priority map — business funnel order, first match wins
$priority = [
@@ -227,7 +231,7 @@ class VisitorNickname
'first-visit' => 'New Visitor',
];
$suffix = $ip ? ' #' . self::shortId($ip) : '';
$suffix = $ip ? ' ' . self::shortId($ip, $countryCode) : '';
foreach ($priority as $tag => $label) {
if (in_array($tag, $tags)) {