Создание базовой модели

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