@@ -95,55 +95,73 @@ public static function make(string $name, ?Field $field = null): Input
9595 public static function calculateDynamicValue (Field $ field , $ sourceValue , ?Get $ get = null )
9696 {
9797 $ mode = $ field ->config ['dynamic_mode ' ] ?? 'none ' ;
98-
98+
9999 if ($ mode === 'relation ' ) {
100- if (empty ($ sourceValue )) return null ;
101-
100+ if (empty ($ sourceValue )) {
101+ return null ;
102+ }
103+
102104 $ sourceUlid = $ field ->config ['dynamic_source_field ' ] ?? null ;
103- if (! $ sourceUlid ) return null ;
105+ if (! $ sourceUlid ) {
106+ return null ;
107+ }
104108
105109 $ sourceField = \Backstage \Fields \Models \Field::find ($ sourceUlid );
106- if (! $ sourceField ) return null ;
110+ if (! $ sourceField ) {
111+ return null ;
112+ }
107113
108114 $ relations = $ sourceField ->config ['relations ' ] ?? [];
109115 $ relationConfig = reset ($ relations );
110- if (! $ relationConfig || empty ($ relationConfig ['resource ' ])) return null ;
116+ if (! $ relationConfig || empty ($ relationConfig ['resource ' ])) {
117+ return null ;
118+ }
111119
112120 $ modelInstance = \Backstage \Fields \Fields \Select::resolveResourceModel ($ relationConfig ['resource ' ]);
113- if (! $ modelInstance ) return null ;
121+ if (! $ modelInstance ) {
122+ return null ;
123+ }
114124
115125 $ relatedRecord = $ modelInstance ::find ($ sourceValue );
116- if (! $ relatedRecord ) return null ;
126+ if (! $ relatedRecord ) {
127+ return null ;
128+ }
117129
118130 $ targetColumn = $ field ->config ['dynamic_relation_column ' ] ?? null ;
119131 if ($ targetColumn && isset ($ relatedRecord ->$ targetColumn )) {
120132 return $ relatedRecord ->$ targetColumn ;
121133 }
122134 }
123-
135+
124136 if ($ mode === 'calculation ' ) {
125- if (! $ get ) return null ;
126-
127- $ formula = $ field ->config ['dynamic_formula ' ] ?? null ;
128- if (! $ formula ) return null ;
129-
130- // Regex to find {ulid} patterns
131- $ parsedFormula = preg_replace_callback ('/\{([a-zA-Z0-9-]+)\}/ ' , function ($ matches ) use ($ get ) {
132- $ ulid = $ matches [1 ];
133- $ val = $ get ("values. {$ ulid }" );
134- // Ensure value is numeric for safety
135- return is_numeric ($ val ) ? $ val : 0 ;
136- }, $ formula );
137-
138- // Safety: Only allow numbers and basic math operators
139- if (preg_match ('/^[0-9\.\+\-\*\/\(\)\s]+$/ ' , $ parsedFormula )) {
140- try {
141- $ result = @eval ("return {$ parsedFormula }; " );
142- return $ result ;
143- } catch (\Throwable $ e ) {
144- return null ;
145- }
146- }
137+ if (! $ get ) {
138+ return null ;
139+ }
140+
141+ $ formula = $ field ->config ['dynamic_formula ' ] ?? null ;
142+ if (! $ formula ) {
143+ return null ;
144+ }
145+
146+ // Regex to find {ulid} patterns
147+ $ parsedFormula = preg_replace_callback ('/\{([a-zA-Z0-9-]+)\}/ ' , function ($ matches ) use ($ get ) {
148+ $ ulid = $ matches [1 ];
149+ $ val = $ get ("values. {$ ulid }" );
150+
151+ // Ensure value is numeric for safety
152+ return is_numeric ($ val ) ? $ val : 0 ;
153+ }, $ formula );
154+
155+ // Safety: Only allow numbers and basic math operators
156+ if (preg_match ('/^[0-9\.\+\-\*\/\(\)\s]+$/ ' , $ parsedFormula )) {
157+ try {
158+ $ result = @eval ("return {$ parsedFormula }; " );
159+
160+ return $ result ;
161+ } catch (\Throwable $ e ) {
162+ return null ;
163+ }
164+ }
147165 }
148166
149167 return null ;
@@ -156,22 +174,22 @@ protected static function applyDynamicSettings(Input $input, ?Field $field = nul
156174 }
157175
158176 return $ input
159- // We keep afterStateHydrated for initial load,
177+ // We keep afterStateHydrated for initial load,
160178 // but we remove the `key` hack as we use "Push" model for updates.
161179 ->afterStateHydrated (function (Input $ component , Get $ get , Set $ set ) use ($ field ) {
162180 $ mode = $ field ->config ['dynamic_mode ' ] ?? 'none ' ;
163-
181+
164182 // Use the shared calculation logic
165183 // But we need to resolve sourceValue from $get
166184 $ sourceUlid = $ field ->config ['dynamic_source_field ' ] ?? null ;
167185 if ($ sourceUlid ) {
168- $ sourceValue = $ get ("values. {$ sourceUlid }" );
169- $ newValue = self ::calculateDynamicValue ($ field , $ sourceValue ); // We need to update this sig for calc?
170-
171- if ($ newValue !== null && $ component ->getState () !== $ newValue ) {
172- $ component ->state ($ newValue );
173- $ set ($ component ->getStatePath (), $ newValue );
174- }
186+ $ sourceValue = $ get ("values. {$ sourceUlid }" );
187+ $ newValue = self ::calculateDynamicValue ($ field , $ sourceValue ); // We need to update this sig for calc?
188+
189+ if ($ newValue !== null && $ component ->getState () !== $ newValue ) {
190+ $ component ->state ($ newValue );
191+ $ set ($ component ->getStatePath (), $ newValue );
192+ }
175193 }
176194 });
177195 }
@@ -327,7 +345,7 @@ public function getForm(): array
327345
328346 $ relations = $ sourceField ->config ['relations ' ] ?? [];
329347 $ relationConfig = reset ($ relations );
330-
348+
331349 if (! $ relationConfig || empty ($ relationConfig ['resource ' ])) {
332350 return [];
333351 }
@@ -338,7 +356,7 @@ public function getForm(): array
338356 }
339357
340358 $ columns = \Illuminate \Support \Facades \Schema::getColumnListing ($ modelInstance ->getTable ());
341-
359+
342360 return collect ($ columns )->mapWithKeys (function ($ column ) {
343361 return [$ column => $ column ];
344362 })->toArray ();
0 commit comments