From 6a09436a5dc92b5857b558cbee24d98a4d9637af Mon Sep 17 00:00:00 2001 From: John Gerwin De las Alas Date: Tue, 25 Nov 2025 13:12:38 +0800 Subject: [PATCH] fix: add support for dependsOn inside flexible content fields This commit adds a new middleware (InterceptFlexibleDependsOnAttributes) that transforms flexible content field names in dependsOn requests by stripping the group key prefix. This allows the dependsOn callbacks to receive the original field names they expect. The middleware intercepts Nova's creation-fields and update-fields API requests and: - Transforms the 'field' query parameter by removing the group prefix - Transforms input field names by removing the group prefix This fixes the issue where dependsOn callbacks inside flexible layouts receive prefixed field names (e.g., 'ckOi67sYIRR0L6kh__product') instead of the expected original names (e.g., 'product'). Fixes #524 --- src/FieldServiceProvider.php | 4 +- .../InterceptFlexibleDependsOnAttributes.php | 149 ++++++++++++++++++ 2 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 src/Http/Middleware/InterceptFlexibleDependsOnAttributes.php diff --git a/src/FieldServiceProvider.php b/src/FieldServiceProvider.php index 2b6ae773..74dc93a6 100644 --- a/src/FieldServiceProvider.php +++ b/src/FieldServiceProvider.php @@ -10,6 +10,7 @@ use Whitecube\NovaFlexibleContent\Commands\CreatePreset; use Whitecube\NovaFlexibleContent\Commands\CreateResolver; use Whitecube\NovaFlexibleContent\Http\Middleware\InterceptFlexibleAttributes; +use Whitecube\NovaFlexibleContent\Http\Middleware\InterceptFlexibleDependsOnAttributes; class FieldServiceProvider extends ServiceProvider { @@ -57,6 +58,7 @@ public function addMiddleware() if ($router->hasMiddlewareGroup('nova')) { $router->pushMiddlewareToGroup('nova', InterceptFlexibleAttributes::class); + $router->pushMiddlewareToGroup('nova', InterceptFlexibleDependsOnAttributes::class); return; } @@ -64,7 +66,7 @@ public function addMiddleware() if (! $this->app->configurationIsCached()) { config()->set('nova.middleware', array_merge( config('nova.middleware', []), - [InterceptFlexibleAttributes::class] + [InterceptFlexibleAttributes::class, InterceptFlexibleDependsOnAttributes::class] )); } } diff --git a/src/Http/Middleware/InterceptFlexibleDependsOnAttributes.php b/src/Http/Middleware/InterceptFlexibleDependsOnAttributes.php new file mode 100644 index 00000000..02c7c12a --- /dev/null +++ b/src/Http/Middleware/InterceptFlexibleDependsOnAttributes.php @@ -0,0 +1,149 @@ +shouldTransformRequest($request)) { + return $next($request); + } + + $this->transformFlexibleFieldNames($request); + + return $next($request); + } + + /** + * Determine if the request should be transformed. + * + * @param \Illuminate\Http\Request $request + * @return bool + */ + protected function shouldTransformRequest(Request $request): bool + { + // Only intercept Nova's dependent field requests + if (! $this->isDependentFieldRequest($request)) { + return false; + } + + // Only transform if the request contains flexible content field names + return $this->hasFlexibleFieldNames($request); + } + + /** + * Check if this is a Nova dependent field request. + * + * @param \Illuminate\Http\Request $request + * @return bool + */ + protected function isDependentFieldRequest(Request $request): bool + { + $path = $request->path(); + + // Match Nova API routes for creation-fields and update-fields + return preg_match('/nova-api\/[^\/]+(?:\/\d+)?\/(?:creation-fields|update-fields)/', $path) === 1; + } + + /** + * Check if the request contains flexible content field names. + * + * @param \Illuminate\Http\Request $request + * @return bool + */ + protected function hasFlexibleFieldNames(Request $request): bool + { + // Check if the 'field' parameter or any input contains the flexible group separator + $field = $request->get('field'); + + if ($field && strpos($field, FlexibleAttribute::GROUP_SEPARATOR) !== false) { + return true; + } + + foreach ($request->all() as $key => $value) { + if (strpos($key, FlexibleAttribute::GROUP_SEPARATOR) !== false) { + return true; + } + } + + return false; + } + + /** + * Transform flexible field names by stripping the group key prefix. + * + * @param \Illuminate\Http\Request $request + * @return void + */ + protected function transformFlexibleFieldNames(Request $request): void + { + // Transform the 'field' query parameter if present + $field = $request->get('field'); + + if ($field && strpos($field, FlexibleAttribute::GROUP_SEPARATOR) !== false) { + $transformedField = $this->stripGroupPrefix($field); + $request->query->set('field', $transformedField); + } + + // Transform all input field names + $transformedInput = $this->transformInputFields($request->all()); + + if (! empty($transformedInput)) { + $request->merge($transformedInput); + } + } + + /** + * Transform input fields by stripping flexible group prefixes. + * + * @param array $input + * @return array + */ + protected function transformInputFields(array $input): array + { + $transformed = []; + + foreach ($input as $key => $value) { + if (strpos($key, FlexibleAttribute::GROUP_SEPARATOR) !== false) { + $newKey = $this->stripGroupPrefix($key); + $transformed[$newKey] = $value; + } + } + + return $transformed; + } + + /** + * Strip the flexible group prefix from a field name. + * + * @param string $fieldName + * @return string + */ + protected function stripGroupPrefix(string $fieldName): string + { + $separatorPosition = strpos($fieldName, FlexibleAttribute::GROUP_SEPARATOR); + + if ($separatorPosition === false) { + return $fieldName; + } + + return substr($fieldName, $separatorPosition + strlen(FlexibleAttribute::GROUP_SEPARATOR)); + } +}