diff --git a/src/Flexible.php b/src/Flexible.php index f0927411..3ce4a010 100644 --- a/src/Flexible.php +++ b/src/Flexible.php @@ -207,7 +207,7 @@ public function resolve($resource, $attribute = null) * @param string $requestAttribute * @param object $model * @param string $attribute - * @return void + * @return null|Closure */ protected function fillAttribute(NovaRequest $request, $requestAttribute, $model, $attribute) { @@ -217,9 +217,17 @@ protected function fillAttribute(NovaRequest $request, $requestAttribute, $model $this->buildGroups($model, $attribute); - $this->syncAndFillGroups($request, $requestAttribute); + $callbacks = collect($this->syncAndFillGroups($request, $requestAttribute)); $this->value = $this->resolver->set($model, $attribute, $this->groups); + + if($callbacks->isEmpty()) { + return; + } + + return function() use ($callbacks) { + $callbacks->each->__invoke(); + }; } /** @@ -227,7 +235,7 @@ protected function fillAttribute(NovaRequest $request, $requestAttribute, $model * * @param \Laravel\Nova\Http\Requests\NovaRequest $request * @param string $requestAttribute - * @return void + * @return array */ protected function syncAndFillGroups(NovaRequest $request, $requestAttribute) { @@ -236,7 +244,9 @@ protected function syncAndFillGroups(NovaRequest $request, $requestAttribute) return; } - $this->groups = collect($raw)->map(function($item, $key) use ($request) { + $callbacks = []; + + $this->groups = collect($raw)->map(function($item, $key) use ($request, &$callbacks) { $layout = $item['layout']; $key = $item['key']; $attributes = $item['attributes']; @@ -245,10 +255,13 @@ protected function syncAndFillGroups(NovaRequest $request, $requestAttribute) if(!$group) return; - $group->fill(ScopedRequest::scopeFrom($request, $attributes, $key)); + $scope = ScopedRequest::scopeFrom($request, $attributes, $key); + $callbacks = array_merge($callbacks, $group->fill($scope)); return $group; }); + + return $callbacks; } /** diff --git a/src/Http/ScopedRequest.php b/src/Http/ScopedRequest.php index 40aa8d03..4149416c 100644 --- a/src/Http/ScopedRequest.php +++ b/src/Http/ScopedRequest.php @@ -62,7 +62,7 @@ protected function getScopeState($group, $attributes) // Sub-objects could contain files that need to be kept if($attribute->isAggregate()) { - $scope['files'] = array_merge($scope['files'], $this->getNestedFiles($value, $attribute->group)); + $scope['files'] = array_merge($scope['files'], $this->pullNestedFiles($value, $attribute->group)); $scope['input'][$attribute->name] = $value; continue; } @@ -81,30 +81,37 @@ protected function getScopeState($group, $attributes) } /** - * Get nested file attributes + * Get & remove nested file attributes from given array * * @param array $iterable * @param null|string $group * @return array */ - protected function getNestedFiles($iterable, $group = null) + protected function pullNestedFiles(&$iterable, $group = null) { $files = []; $key = $this->isFlexibleStructure($iterable) ? $iterable['key'] : $group; - foreach ($iterable as $attribute => $value) { + foreach ($iterable as $original => $value) { if(is_array($value)) { - $files = array_merge($files, $this->getNestedFiles($value, $key)); + $files = array_merge($files, $this->pullNestedFiles($value, $key)); + $iterable[$original] = $value ? $value : null; continue; } - $attribute = FlexibleAttribute::make($attribute, $group); + $attribute = FlexibleAttribute::make($original, $group); - if(!$attribute->isFlexibleFile($value)) continue; + if(!$attribute->isFlexibleFile($value)) { + continue; + } $files[] = $attribute->getFlexibleFileAttribute($value); + + $iterable[$original] = null; } + $iterable = array_filter($iterable); + return $files; } diff --git a/src/Layouts/Layout.php b/src/Layouts/Layout.php index b188670c..06e0dbf2 100644 --- a/src/Layouts/Layout.php +++ b/src/Layouts/Layout.php @@ -230,13 +230,18 @@ public function getResolvedValue() * Fill attributes using underlaying fields and incoming request * * @param \Laravel\Nova\Http\Requests\NovaRequest $request - * @return void + * @return array */ public function fill(ScopedRequest $request) { - $this->fields->each(function($field) use ($request) { - $field->fill($request, $this); - }); + return $this->fields->map(function($field) use ($request) { + return $field->fill($request, $this); + }) + ->filter(function($callback) { + return is_callable($callback); + }) + ->values() + ->all(); } /**