Создание базовой модели
В CMS реализована простая модель. Мы честно признаем, что эта модель, нечто среднее между ELoquento от Laravel и библиотеки PDOx.
В целом модель обеспечивает необходимый набор дейтсвий с данными, при минимальных зависимостях.
Как создать модель?
Есть два способа создать модель.
1. Классический, когда вы в вашем модуле создает папку models. Затем в папке создаете файл с вашей моделью, описывая ее по правилам.
2. Более быстрый. Для этого вам необходимо создать таблицу данных в БД. Затем зайти в модуль GKG и там выбрать создание модели. В этом случае модель сгенерируется сама с описанием ваших данных.
Как выглядит модель
Модель это класс, котоорый наследуются от основной модели из ядра (Core).
Изначально модель может состоять всего лишь из этих строк:
<?php namespace ВАШ ПУТЬ; user core\Model; class ВАШ КЛАСС extends Model { public $table = "Ваша таблица"; public $sanitize = ['field1','field2']; // для полей получаемых от стороннего пользователя }
По сути это все, что нужно для работы базовой модели.
Что может модель?
На самом деле многое, как пример:
Выборки:
Предположим нам нужно получить все записи из нашей таблицы:
$model->getAll(); //вернет массив объектов
С ограничением по полям:
$model->select(['id','name'])->getAll(); //вернет массив объектов только указанные поля
Получить одну запись по ID:
$model->getOne('ID'); //вернет один объект
Получить выборку по условию:
$model->where('id','>',5)->getAll();
Получить выборку с ограничением:
$model->where('id','>',5)->limit(5)->getAll();
Множественные условия:
$model->select(['name', 'id', 'alias', 'data_create']) ->where('visible', '=', 1) ->where('deleted', '=', 0) ->where('categories_id', '=', $catId) ->whereRaw('(data_end > NOW() or data_end is null) ') ->whereRaw('(data_create <= NOW() or data_create is null) ') ->orderBy('data_create DESC') ->getAll();
Выборка с группировкой:
Primes::instance() ->where( function ($q) use ($userId) { $q->where('to_user_id', intval($userId)) ->where('user_id', User::current()->id); }) ->where( function ($q) use ($userId) { $q->orWhere('to_user_id', User::current()->id) ->where('user_id', intval($userId)); }) ->getAll(); //если хотим увидеть запрос то getQuery()
Вставки:
Добавление записи:
$m = new Model(); $m->name = "Вася"; $m->show = 'Y'; $m->save();
Можно так:
$model->insert('ARRAY OF DATA'); // где массив ключ значение
После любой вставки вам возвращается PK. Массовая вставка пока не предусмотрена, но решается вставкой в цикле.
Обновление:
Классическая схема подразумевает, что вы сначала получаете данные, а затем их обновляете.
Схема с получением данных:
$m = new Model(); $m->getOne(PK); $m->name = 'Petro'; $m->save();
Ниже схема без получения данных:
Три разных способа:
$m = new Model(); $m->name = 'Petro'; $m->PK = 3; //ОБЯЗАТЕЛЬНО ПЕРЕДАЕМ Первичный ключ, иначе будет вставка $m->save();
$m->update($data); // где data это массив или объект данных содержащий PK
$m->save($data); //аналогично записи 2, но если в записи два всегда будет ошибка если нет PK, то в этом случае будет вставка.
Обновление в цикле
Иногда нам нужно делать операции в цикле или с большим объемом данных. Операция не частая, но как вариант можно делать так:
$m = new Model(); foreach ($array as $item) { $m->clear()->update($item); //clear -- опусташает модель до первичного состояния, гарантируя отсутствие коллизий. В целом должно работать и без него. }
Удаление:
Почистим табилицу:
$m->truncate();
Удалим запись:
$m->delete('PK');
Удалим все скрытые записи:
$m->where('visible', 'n')->delete();
Удалим записи в диапазоне:
$m->between('id', '5', '10')->delete();
Зависимости:
Предположим, что у нас есть статьи, и категории. В этом случае писать запрос на получение можно, но удобнее воспользоваться методами модели:
И так в классе Категории мы делаем связь с статьями:
class Category extends Model { ... public function articles() { return $this->hasMany(Article::instance(), 'categories_id'); } ... }
В классе статей делаем связь с категорией:
class Article extends Model { ... /** * Связь к категории */ public function category() { return $this->belongsTo(Categories::instance(), 'id'); } ... }
Соотвественно используя ту или иную модель, мы легко получаем связанные вещи, и только тогда, когда к ним обращаемся.
Кроссмодельные выборки
$model ->in('id', UserPermission::instance()->select(['permission_id']) //в условия можно передавать класс которые является инстансом модели ->where(['user_id' => USER::current()->id])) //условия можно передавать в виде массива, но в этом случае считается что условие будет `ключ` = `значению` ->getAll()
Фишечки:
В модели предусмотрены методы, которые могут ничего не возвращать, но модифицировать информацию самой модели:
beforeSave() // перед сохранением (например преобразовать урл) afterSave() //после сохранения ( например провести тест, или проверить консистентность данных) beforeInsert() //перед вставкой (например проверить права) afterInsert() //после вставки (например сохранить картинку) beforeSelect() //перед выборкой afterSelect() //после выборки beforeUpdate() //перед обновлением afterUpdate() //после обновления beforeDelete() //перед удалением (например проверить зависимости) afterDelete() //после удаления (например удалить картинку) getQuery() //получить запрос (ставим вместо query, getAll, getOne и получаем вывод запроса на экран) toArray() //результат в массив toCollection() //результат в коллекцию