Created
March 6, 2024 18:04
-
-
Save RomainMazB/5863bebb6f4e4d1771967f632f9b97e6 to your computer and use it in GitHub Desktop.
Nova repeater with file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php namespace App\Nova\Fields; | |
| use Closure; | |
| use Laravel\Nova\Http\Requests\NovaRequest; | |
| use Laravel\Nova\Fields\File; | |
| class MyFile extends File { | |
| protected function fillAttribute(NovaRequest $request, $requestAttribute, $model, $attribute) | |
| { | |
| $hasExistingFile = ! is_null($this->getStoragePath()); | |
| if (is_null($file = $this->retrieveFileFromRequest($request, $requestAttribute))) { | |
| if ($hasExistingFile) { | |
| return $model->{$attribute} = $this->getStoragePath(); | |
| } | |
| return; | |
| } | |
| $result = call_user_func( | |
| $this->storageCallback, | |
| $request, | |
| $model, | |
| $attribute, | |
| $requestAttribute, | |
| $this->getStorageDisk(), | |
| $this->getStorageDir() | |
| ); | |
| if ($result === true) { | |
| return; | |
| } | |
| if ($result instanceof Closure) { | |
| return $result; | |
| } | |
| if (! is_array($result)) { | |
| return $model->{$attribute} = $result; | |
| } | |
| foreach ($result as $key => $value) { | |
| $model->{$key} = $value; | |
| } | |
| if ($this->isPrunable() && $hasExistingFile) { | |
| return function () use ($model, $request) { | |
| call_user_func( | |
| $this->deleteCallback, | |
| $request, | |
| $model, | |
| $this->getStorageDisk(), | |
| $this->getStoragePath() | |
| ); | |
| }; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php namespace App\Nova\Presets; | |
| use Illuminate\Database\Eloquent\Model; | |
| use Laravel\Nova\Fields\Field; | |
| use Laravel\Nova\Fields\FieldCollection; | |
| use Laravel\Nova\Fields\Repeater\Presets\JSON; | |
| use Laravel\Nova\Fields\Repeater\Presets\Preset; | |
| use Laravel\Nova\Http\Requests\NovaRequest; | |
| use Laravel\Nova\Support\Fluent; | |
| class MyJSONPreset implements Preset | |
| { | |
| /** | |
| * Save the field value to permanent storage. | |
| * | |
| * @param string|null $uniqueField | |
| * @return \Closure | |
| */ | |
| public function set( | |
| NovaRequest $request, | |
| string $requestAttribute, | |
| Model $model, | |
| string $attribute, | |
| RepeatableCollection $repeatables, | |
| $uniqueField | |
| ) { | |
| // Clone the model to keep track of | |
| $model->setAttribute($attribute, null); | |
| $fieldCallbacks = collect($request->input($requestAttribute)) | |
| ->map(function ($item, $blockKey) use ($request, $requestAttribute, $model, $attribute, $repeatables) { | |
| $data = new Fluent(); | |
| $block = $repeatables->findByKey($item['type']); | |
| $fields = FieldCollection::make($block->fields($request)); | |
| // For each field collection, return the callbacks and set the data on the model, and then return a function | |
| // that invokes all of the callbacks; | |
| $callbacks = $fields | |
| ->withoutUnfillable() | |
| ->withoutMissingValues() | |
| ->map(function (Field $field) use ($model, $attribute, $request, $requestAttribute, $data, $blockKey) { | |
| $originalAttribute = $model->getOriginal($attribute); | |
| if (!is_null($originalAttribute) && isset($originalAttribute[$blockKey])) { | |
| $field->resolve($originalAttribute[$blockKey]['fields'], $field->attribute); | |
| } | |
| return $field->fillInto($request, $data, $field->attribute, "{$requestAttribute}.{$blockKey}.fields.{$field->attribute}"); | |
| }) | |
| ->filter(function ($callback) { | |
| return is_callable($callback); | |
| }); | |
| // Set the block type on the data object | |
| $model->setAttribute("{$attribute}->{$blockKey}->type", $block->key()); | |
| // Set the data on the model | |
| foreach ($data->getAttributes() as $k => $v) { | |
| $model->setAttribute("{$attribute}->{$blockKey}->fields->{$k}", $v); | |
| } | |
| // Return a function that calls the callbacks from the fields | |
| return function () use ($callbacks) { | |
| return $callbacks->each->__invoke(); | |
| }; | |
| }); | |
| return function () use ($fieldCallbacks) { | |
| return collect($fieldCallbacks)->each->__invoke(); | |
| }; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment