/home/bdqbpbxa/api-uniferx.goodface.com.ua/vendor/laravel/nova/src/Fields/Repeater/Presets/JSON.php
<?php

namespace Laravel\Nova\Fields\Repeater\Presets;

use Illuminate\Database\Eloquent\Model;
use Laravel\Nova\Fields\Field;
use Laravel\Nova\Fields\FieldCollection;
use Laravel\Nova\Fields\Repeater\RepeatableCollection;
use Laravel\Nova\Http\Requests\NovaRequest;
use Laravel\Nova\Support\Fluent;

class JSON 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
    ) {
        // Reset the field attribute in case it's filled already
        $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 ($request, $requestAttribute, $data, $blockKey) {
                        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();
        };
    }

    /**
     * Retrieve the value from storage and hydrate the field's value.
     *
     * @return \Illuminate\Support\Collection
     */
    public function get(NovaRequest $request, Model $model, string $attribute, RepeatableCollection $repeatables)
    {
        return RepeatableCollection::make($model->{$attribute})
            ->map(function ($block) use ($repeatables) {
                return $repeatables->newRepeatableByKey($block['type'], $block['fields']);
            });
    }
}