@@ -24,11 +24,14 @@ final class PolicySpec implements IPolicyDefinition {
2424 private ?Closure $ normalizer ;
2525 /** @var Closure(mixed, PolicyContext): void|null */
2626 private ?Closure $ validator ;
27+ /** @var Closure(PolicyContext): bool|null */
28+ private ?Closure $ eligibilityChecker ;
2729
2830 /**
2931 * @param list<mixed>|Closure(PolicyContext): list<mixed> $allowedValues
3032 * @param Closure(mixed): mixed|null $normalizer
3133 * @param Closure(mixed, PolicyContext): void|null $validator
34+ * @param Closure(PolicyContext): bool|null $eligibilityChecker
3235 */
3336 public function __construct (
3437 private string $ key ,
@@ -40,10 +43,12 @@ public function __construct(
4043 private ?string $ userPreferenceKey = null ,
4144 private string $ resolutionMode = self ::RESOLUTION_MODE_RESOLVED ,
4245 private bool $ supportsUserPreference = true ,
46+ ?Closure $ eligibilityChecker = null ,
4347 ) {
4448 $ this ->allowedValuesResolver = $ allowedValues ;
4549 $ this ->normalizer = $ normalizer ;
4650 $ this ->validator = $ validator ;
51+ $ this ->eligibilityChecker = $ eligibilityChecker ;
4752 }
4853
4954 #[\Override]
@@ -105,4 +110,13 @@ public function defaultSystemValue(): mixed {
105110 public function supportsUserPreference (): bool {
106111 return $ this ->supportsUserPreference ;
107112 }
113+
114+ #[\Override]
115+ public function isUserEligible (PolicyContext $ context ): bool {
116+ if ($ this ->eligibilityChecker !== null ) {
117+ return ($ this ->eligibilityChecker )($ context );
118+ }
119+
120+ return true ;
121+ }
108122}
0 commit comments