-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathUser.php
More file actions
134 lines (115 loc) · 5.04 KB
/
User.php
File metadata and controls
134 lines (115 loc) · 5.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?php
declare(strict_types=1);
namespace ConfigCat;
use Stringable;
/**
* An object containing attributes to properly identify a given user for rollout evaluation.
*/
final class User implements Stringable
{
public const IDENTIFIER_ATTRIBUTE = 'Identifier';
public const EMAIL_ATTRIBUTE = 'Email';
public const COUNTRY_ATTRIBUTE = 'Country';
/**
* @internal
*/
public const WELL_KNOWN_ATTRIBUTES = [self::IDENTIFIER_ATTRIBUTE, self::EMAIL_ATTRIBUTE, self::COUNTRY_ATTRIBUTE];
/**
* User constructor.
*
* @param string $identifier the unique identifier of the user or session (e.g. email address, primary key, session ID, etc.)
* @param ?string $email email address of the user
* @param ?string $country country of the user
* @param ?array<string, mixed> $custom custom attributes of the user for advanced targeting rule definitions (e.g. user role, subscription type, etc.)
*
* All comparators support `string` values as User Object attribute (in some cases they need to be provided in a specific format though, see below),
* but some of them also support other types of values. It depends on the comparator how the values will be handled. The following rules apply:
*
* **Text-based comparators** (EQUALS, IS ONE OF, etc.)
* * accept `string` values,
* * all other values are automatically converted to `string` (a warning will be logged but evaluation will continue as normal).
*
* **SemVer-based comparators** (IS ONE OF, <, >=, etc.)
* * accept `string` values containing a properly formatted, valid semver value,
* * all other values are considered invalid (a warning will be logged and the currently evaluated targeting rule will be skipped).
*
* **Number-based comparators** (=, <, >=, etc.)
* * accept `int` or `float` values,
* * accept `string` values containing a properly formatted, valid `int` or `float` value,
* * all other values are considered invalid (a warning will be logged and the currently evaluated targeting rule will be skipped).
*
* **Date time-based comparators** (BEFORE / AFTER)
* * accept `DateTimeInterface` values, which are automatically converted to a second-based Unix timestamp,
* * accept `int` or `float` values representing a second-based Unix timestamp,
* * accept `string` values containing a properly formatted, valid `int` or `float` value,
* * all other values are considered invalid (a warning will be logged and the currently evaluated targeting rule will be skipped).
*
* **String array-based comparators** (ARRAY CONTAINS ANY OF / ARRAY NOT CONTAINS ANY OF)
* * accept arrays of `string`,
* * accept `string` values containing a valid JSON string which can be deserialized to an array of `string`,
* * all other values are considered invalid (a warning will be logged and the currently evaluated targeting rule will be skipped).
*/
public function __construct(
private string $identifier,
private ?string $email = null,
private ?string $country = null,
private ?array $custom = null
) {}
/**
* @return string the string representation of the user
*/
public function __toString(): string
{
$result = json_encode($this->getAllAttributes(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
return false !== $result ? $result : '<serialization error>';
}
/**
* Gets the identifier of the user.
*
* @return string the identifier of the user
*/
public function getIdentifier(): string
{
return $this->identifier ?? '';
}
/**
* Gets a user attribute identified by the given key.
*
* @param string $key the key of the user attribute
*
* @return mixed the user attribute, or null if it doesn't exist
*/
public function getAttribute(string $key): mixed
{
switch ($key) {
case self::IDENTIFIER_ATTRIBUTE: return $this->getIdentifier();
case self::EMAIL_ATTRIBUTE: return $this->email;
case self::COUNTRY_ATTRIBUTE: return $this->country;
default: return $this->custom[$key] ?? null;
}
}
/**
* Gets all user attributes.
*
* @return array<string, mixed>
*/
public function getAllAttributes(): array
{
$result = [];
$result[self::IDENTIFIER_ATTRIBUTE] = $this->getIdentifier();
if (isset($this->email)) {
$result[self::EMAIL_ATTRIBUTE] = $this->email;
}
if (isset($this->country)) {
$result[self::COUNTRY_ATTRIBUTE] = $this->country;
}
if (isset($this->custom)) {
foreach ($this->custom as $attributeName => $attributeValue) {
if (isset($attributeValue) && !in_array($attributeName, self::WELL_KNOWN_ATTRIBUTES, true)) {
$result[$attributeName] = $attributeValue;
}
}
}
return $result;
}
}