Создание базовой модели
В 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() //результат в коллекцию