Всем привет, начал писать свой велосипед для прокачки скилла и просто для решения повседневных задач. Хочу написать универсальный плагин для создания кастомных полей.
Пока удалось сделать следующее:
Разработать интерфейс по управлению кастомными полями.
Есть страничка для создания полей, есть страничка для создания наборов полей.
В форме создания набора полей есть relation виджет для добавления полей в набор
Итого: получаем возможность создавать поля и пробрасывать их в наборы.
Реализовать универсальный способ расширения моделей и форм.
Тут я ничего нового не открыл, все есть в доках. Сделал небольшую хитрость добавив в таблицу наборов 2 поля model и controller по этим полям провожу проверку и подключаю поля.
Итого: Созданные нами поля подключаться на страницу контроллера
Реализовать возможность сохранения полей с привязкой к сущности
В этом как я думал, должна помочь полиморфная связь. Но у меня ничего не вышло. На этом этапе я завис. Я не могу понять как эта связь должна работать. Я уверен что у меня проблема с архитектурой, недостаточно таблиц, например, так как ранее я так голову не ломал.
Архитектура примерно такая (таблицы):
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. Подскажите товарищи как быть. Заранее премного благодарен!