1+ <?php
2+
3+ namespace Backstage \Fields \Fields \Logic ;
4+
5+ use Backstage \Fields \Fields \Helpers \FieldOptionsHelper ;
6+ use Backstage \Fields \Models \Field ;
7+ use Filament \Forms ;
8+
9+ class VisibilityLogicApplier
10+ {
11+ public static function applyVisibilityLogic ($ input , ?Field $ field = null ): mixed
12+ {
13+ if (! $ field || empty ($ field ->config ['visibilityRules ' ])) {
14+ return $ input ;
15+ }
16+
17+ $ visibilityRules = $ field ->config ['visibilityRules ' ];
18+
19+ $ input ->visible (function (Forms \Get $ get ) use ($ visibilityRules , $ field ): bool {
20+ return self ::evaluateVisibilityRules ($ get , $ visibilityRules , $ field );
21+ });
22+
23+ return $ input ;
24+ }
25+
26+ protected static function evaluateVisibilityRules (Forms \Get $ get , array $ visibilityRules , Field $ field ): bool
27+ {
28+ foreach ($ visibilityRules as $ rule ) {
29+ $ logic = $ rule ['logic ' ] ?? 'AND ' ;
30+ $ conditions = $ rule ['conditions ' ] ?? [];
31+
32+ if (empty ($ conditions )) {
33+ continue ;
34+ }
35+
36+ $ ruleResult = self ::evaluateRuleConditions ($ get , $ conditions , $ logic , $ field );
37+
38+ // If any rule evaluates to false, the field should be hidden
39+ if (! $ ruleResult ) {
40+ return false ;
41+ }
42+ }
43+
44+ // If all rules evaluate to true, the field should be visible
45+ return true ;
46+ }
47+
48+ protected static function evaluateRuleConditions (Forms \Get $ get , array $ conditions , string $ logic , Field $ field ): bool
49+ {
50+ $ results = [];
51+
52+ foreach ($ conditions as $ condition ) {
53+ $ fieldUlid = $ condition ['field ' ] ?? '' ;
54+ $ operator = $ condition ['operator ' ] ?? 'equals ' ;
55+ $ value = $ condition ['value ' ] ?? null ;
56+
57+ $ fieldName = FieldOptionsHelper::getFieldNameFromUlid ($ fieldUlid , $ field );
58+
59+ if (! $ fieldName ) {
60+ continue ;
61+ }
62+
63+ $ fieldValue = $ get ($ fieldName );
64+ $ results [] = self ::evaluateCondition ($ fieldValue , $ operator , $ value );
65+ }
66+
67+ if (empty ($ results )) {
68+ return true ;
69+ }
70+
71+ return $ logic === 'AND '
72+ ? !in_array (false , $ results , true ) // All must be true
73+ : in_array (true , $ results , true ); // At least one must be true
74+ }
75+
76+ protected static function evaluateCondition ($ fieldValue , string $ operator , $ expectedValue ): bool
77+ {
78+ switch ($ operator ) {
79+ case 'equals ' :
80+ return $ fieldValue == $ expectedValue ;
81+
82+ case 'not_equals ' :
83+ return $ fieldValue != $ expectedValue ;
84+
85+ case 'contains ' :
86+ return is_string ($ fieldValue ) && str_contains ($ fieldValue , $ expectedValue );
87+
88+ case 'not_contains ' :
89+ return is_string ($ fieldValue ) && ! str_contains ($ fieldValue , $ expectedValue );
90+
91+ case 'starts_with ' :
92+ return is_string ($ fieldValue ) && str_starts_with ($ fieldValue , $ expectedValue );
93+
94+ case 'ends_with ' :
95+ return is_string ($ fieldValue ) && str_ends_with ($ fieldValue , $ expectedValue );
96+
97+ case 'is_empty ' :
98+ return empty ($ fieldValue );
99+
100+ case 'is_not_empty ' :
101+ return ! empty ($ fieldValue );
102+
103+ case 'greater_than ' :
104+ return is_numeric ($ fieldValue ) && is_numeric ($ expectedValue ) && $ fieldValue > $ expectedValue ;
105+
106+ case 'less_than ' :
107+ return is_numeric ($ fieldValue ) && is_numeric ($ expectedValue ) && $ fieldValue < $ expectedValue ;
108+
109+ case 'greater_than_or_equal ' :
110+ return is_numeric ($ fieldValue ) && is_numeric ($ expectedValue ) && $ fieldValue >= $ expectedValue ;
111+
112+ case 'less_than_or_equal ' :
113+ return is_numeric ($ fieldValue ) && is_numeric ($ expectedValue ) && $ fieldValue <= $ expectedValue ;
114+
115+ case 'in ' :
116+ if (!is_string ($ expectedValue )) {
117+ return false ;
118+ }
119+ $ allowedValues = array_map ('trim ' , explode (', ' , $ expectedValue ));
120+ return in_array ($ fieldValue , $ allowedValues );
121+
122+ case 'not_in ' :
123+ if (!is_string ($ expectedValue )) {
124+ return true ;
125+ }
126+ $ excludedValues = array_map ('trim ' , explode (', ' , $ expectedValue ));
127+ return !in_array ($ fieldValue , $ excludedValues );
128+
129+ default :
130+ return false ;
131+ }
132+ }
133+ }
0 commit comments