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

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

  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, по этим ячейкам плагин знает к какой модели крепить поля.

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

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'] = ['Catdesign\Additionalfields\Models\Value', '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());
            }
        });
    }

Не судите за красоту и чистоту, делаю пока "наотъебись", ой то бишь тестирую.

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

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

Но поле не сохранит свое значение. Вот что показывает 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?
Хоть пощупать можно будет.

  • BlackCat ответили на это сообщение.

    Dinwid https://github.com/ZloyCod/AFOP

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

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

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

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