Реализация универсального custom fields?

Всем привет, начал писать свой велосипед для прокачки скилла и просто для решения повседневных задач. Хочу написать универсальный плагин для создания кастомных полей.

**Пока удалось сделать следующее:**

1. Разработать интерфейс по управлению кастомными полями.  

Есть страничка для создания полей, есть страничка для создания наборов полей.  

В форме создания набора полей есть relation виджет для добавления полей в набор  

Итого: получаем возможность создавать поля и пробрасывать их в наборы.
2. Реализовать универсальный способ расширения моделей и форм.  

Тут я ничего нового не открыл, все есть в доках. Сделал небольшую хитрость добавив в таблицу наборов 2 поля model и controller по этим полям провожу проверку и подключаю поля.  

Итого: Созданные нами поля подключаться на страницу контроллера
3. Реализовать возможность сохранения полей с привязкой к сущности  

В этом как я думал, должна помочь полиморфная связь. Но у меня ничего не вышло. На этом этапе я завис. Я не могу понять как эта связь должна работать. Я уверен что у меня проблема с архитектурой, недостаточно таблиц, например, так как ранее я так голову не ломал.

**Архитектура примерно такая (таблицы):**  

`catdesign_additional_fields => [id, name, params, created_at, updated_at]`  

Эта таблица содержит сами поля, params это jsonable поле, содержит настройки поля типа type, label, span, tab и тд. Смысл такой структуры был в том, что бы с минимальными усилиями получить готовый массив для вставки в addfields().

`catdesign_additional_lists => [id, name, description, model, controller, active, created_at, updated_at]`  

Данная таблица описывает набор полей, ячейки model и controller служат для проверки event::listen, по этим ячейкам плагин знает к какой модели крепить поля.

**Вот пример как это выглядит:**  

[![](//i.imgur.com/vlls63s.png)](//i.imgur.com/vlls63s.png)

`catdesign_additional_field_list => [id, field_id, list_id]`  

Эта таблица нужна для relation widget. Отношение многие ко многим

`catdesign_additional_values => [id, value, valueable_id, valueable_type, created_at, updated_at]`  

Вот здесь я накосяпорил. Знаю это потому, что не могу объяснить смысл этой таблицы. Она должна была служить для полиморфной связи morphmany, но что то пошло не так. В этой таблице я пытаюсь сохранять поля в ячейку value, она имеет jsonable.

**А теперь покажу код, но именно ту связь, что не работает:**

**Вот так я расширяюсь. Этот код работает:**

```
// Создаю переменную для списков полей
private $fieldlists;

    private function extendsitems() {

        // Получаю списки полей и кладу в переменную
        $this->fieldlists = fieldlist::get();

        // Расширяю модель, полиморфную связь один ко многим. Класс модели беру из ячейки model списка полей
        foreach ($this->fieldlists as $fieldlist) {
            $fieldlist->model::extend(function ($model) {
                $model->morphmany['property'] = ['catdesignadditionalfieldsmodelsvalue', 'table' => 'catdesign_additional_values', 'name' => 'valueable'];
            });
        }

        // Слушаю события открытия бекенд формы
        event::listen('backend.form.extendfields', function($widget) {
            foreach ($this->fieldlists as $fieldlist) {

                // Проверяю тот ли контролер
                if (!$widget->getcontroller() instanceof $fieldlist->controller) {
                    return true;
                }

                // Проверяю та ли модель
                if (!$widget->model instanceof $fieldlist->model) {
                    return true;
                }

                // Создаю коллекцию для упаковки сгенерированных полей
                $fields = new collection();

                // Перебираю все поля из списка и упаковываю в коллекцию, делаю временный костыль для проверки работоспособности property[value]
                foreach ($fieldlist->fields as $item) {
                    $fields->put("property[value][$item->name]", $item->params);
                }
                
                // Инжект полей
                $widget->addfields($fields->toarray());
            }
        });
    }
```
Не судите за красоту и чистоту, делаю пока "наотъебись", ой то бишь тестирую.

**Результат примерно такой:**  

[![](//i.imgur.com/r2jipur.png)](//i.imgur.com/r2jipur.png)

Как видно по картинке у меня появилось тестовое поле. Если его заполнить и нажать кнопку сохранить, то октябрь отрапортует зеленым окошком с текстом запись успешно сохранена.

Но поле не сохранит свое значение. Вот что показывает debugbar

`update 'catdesign_additional_values' set 'valueable_id' = '', 'valueable_type' = '', 'updated_at' = '2020-02-20 06:52:01' where 'catdesign_additional_values'.'valueable_id' = '7' and 'catdesign_additional_values'.'valueable_id' is not null and 'catdesign_additional_values'.'valueable_type' = 'catdesign\blog\models\post' and 1 = 1`

То есть попытка есть, просто данных 0. Подскажите товарищи как быть. Заранее премного благодарен!

Может на github?  

Хоть пощупать можно будет.



[dinwid](https://octoclub.ru/d/162/2) <https://github.com/zloycod/afop>

Ссылка на репу, прошу прощения не успел быстро все собрать. Если есть желание можно его доработать и опубликовать в бесплатный доступ для всех желающих.



Нарисуй таблицы (со связями). И поймешь почему не работает.  

Обрати внимание на value (как они связаны с field)

Сейчас имеет смысл начать заново. И изначально нормально проработать таблицы.



Да, спасибо, помог немного распутать мысли, скоро начну перерабатывать файлы миграций