Общее
Начало работы Окружение Работа с E-mail Адаптер Работа с обновлениями Роутер Api
Разработка
Модели Миграции Подсистемы Сервисные страницы
Настройки
Персонализация Стили
Тестирование
TDD
Пользователи
Пользователи
ECommerce
Заказы Корзина Профиль заказа Пункты выдачи
Специальность
Стажировка
  • 1 Модели приложения
  • 2 Методы ORM
  • 3 Работа с динамической моделью
  • 4 Создание методов

Модели приложения

Модели приложения обеспечивают работу с данными.

Все модели группируются по модулям, например модель Пользователи принадлежит к модулю Users

Для примера создадим модель Курсы.

Курсы будут относится к модулю обучение. 

Создание модуля

  1. Откройте админ панель
  2. Перейдите в пункт меню (сверху) Разработчикам
  3. Откройте Динамические модули
  4. Нажмите Создать модуль
  5. Заполните поля и нажмите создать:

Название модуля: Обучение

Код модуля: Education

cool Важно верно называть модули, название должно отображать реальную суть модуля и быть названным в стиле UpperCamelCase

 

 

Создание блока ( модели )

  1. Перейдите в модуль Обучение
  2. Нажмите Создать блок
  3. Заполните поля и нажмите создать:

Название блока: Курсы

Код блока: Courses

 

 

Настройка персонализации

  1. Перейдите в модуль Курсы
  2. Откройте вкладку Персонализация
  3. В графе Подписи заполните поля и нажмите сохранить:

Это необходимо сделать, что персонализировать блок, управлять таким блоком будет проще и понятнее.

Обновите страницу админ-панели, перейдите в Обучение > Курсы и добавьте курс.

 

Название курса: Курс по работе с базой данных

Нажмите сохранить, и вернитесь в список.

Курс успешно создался! 

Теперь попробуем его расширить.

Перейдите: Разработчику > Динамические модули > Обучение > Курсы > Структура базы данных

Тут отображена текущая структура таблицы с курсами.

Добавим столбец видео для нашего курса:

  1. Нажмите добавить столбец
  2. Заполните поля и нажмите Сохранить:

Тип поля: Интерактивные > Youtube видео

Название поля: Видео

Код поля: youtube_video

Столбец успешно создался, в редакторе появилось новое поле, в базе данных тоже:

Вставьте ссылку: https://www.youtube.com/watch?v=EaYGawGWKiE

И нажмите Сохранить

Готово, курс успешно сохранен!

Таким образом можно расширять карточку курса сколько угодно.

 

 

 

Методы ORM

save()

Метод сохраняет запись в модель

Цепочка Описание Пример Комментарий
set(array) Метод задает параметры для сохранения

Users::set(['name' => 'Ivan'])->save();

Будет создана новая запись
find(array) Метод задает параметры для поиска записи

Users::find(['id' => 1])->set(['name' => 'Ivan'])->save();

Запись с id=1 будет обновлена

 

getOne()

Метод получает единственный экземпляр записи

getCollection()

Метод получает коллекцию записей

Цепочка Описание Пример Комментарий
find(array) Метод задает параметры для поиска записи

Users::find(['id' => 1])->getOne();

Метод вернет единственный экземпляр с id=1
fl(array) Метод указывает какие поля доставать

Users::find()
    ->fl(['id', 'name', 'email'])
    ->getCollection();

Метод вернет коллекцию записей, с полями id, name, email
orderBy(array,string) Метод указывает порядок выборки

Users::find(['id' => 1])
    ->orderBy('id.asc')
    ->getCollection();

Users::find()
    ->orderBy(['name.asc', 'id.asc'])
    ->getCollection();

Метод вернет коллекцию отсортированных записей
limit(string) Метод указывает лимит выборки

Users::find()->limit(5)->getCollection();

Users::find()->limit('5,10')->getCollection();

Метод вернет 5 записей в первом случае, во втором случае метод вернет с пятой по 10ю запись

 

Чтение и обработка на лету


$users = Users::find()->getCollection(function ($item) {
    return [
        'id' => $item['id'],
        'name' => $item['name'],
        'email' => $item['email'],
    ];
})->items;

laugh Данный хендл доступен в методах getOne() и getCollection()

 

remove()

Метод удаляет один экземпляр записи

Цепочка Описание Пример Комментарий
find(array) Метод задает параметры для поиска записи

Users::find(['id' => 1])->remove();

Метод удалит запись с id=1

 

Работа с динамической моделью

В качестве примера будет использовать модель Education/Courses

После того, как мы создали ее в админ панели, автоматически была создана таблица: block_education_courses

и модель App\Models\Education\Courses которая находится в директории: /app/models/Education/Courses.php

Так как модель является наследником класса: Prologue\Framework\Database\ORM\Model

То по умолчанию, модель имеет ряд методов, с которыми можно ознакомиться тут:

Динамические модули > Обучение > Курсы > Документация

 

Модель умеет:

  1. Создать запись
  2. Обновить запись
  3. Получить единственный экземпляр
  4. Получить коллекцию
  5. Удалить запись

cool Функционал на этом не ограничивается, его можно создавать дописывая новые методы в модели

 

Работа с методами

Создаем тестовый скрипт и попробуем поработать с моделью.

Создайте файл: /app/tests/Education/Courses/script.php

Чтобы заработала автозагрузка, нужно подключить ядро и импортировать модель:

 


<?php

include $_SERVER['DOCUMENT_ROOT'] . '/app/configuration/init.php';

use \App\Models\Education\Courses;

Создадим курс:


$data = [
    'name' => 'Тестовый курс'
];

$res = Courses::set($data)->save();

var_dump($res);

Курс успешно создался:

Получим курс:


$res = Courses::find(['id' => 1])->getOne();


echo '<pre>'; var_dump($res);

Получим коллекцию курсов


$res = Courses::find()->getCollection();

echo '<pre>';
var_dump($res);

Добавим тестовому курсу ссылку на youtube


$res = Courses::find(['name' => 'Тестовый курс'])->set(
    [
        'youtube_video' => 'https://www.youtube.com/embed/PEKN8NtBDQ0'
    ]
)->save();

echo '<pre>';
var_dump($res);

Удалим тестовый курс


$res = Courses::find(['name' => 'Тестовый курс'])->remove();

echo '<pre>';
var_dump($res);

 

Готово! Были продемонстрированы базовые возможности CRUD

Для написания сложных запросов, используйте PDO


use Prologue\Framework\Database\Database;

$database = new Database;

$pdo = $database->init();

$stmt = $pdo->prepare('SELECT * FROM  block_education_courses WHERE id=:id LIMIT 1');

$stmt->execute(
    [
        'id' => 1
    ]
);

$data = $stmt->fetch();

 

Создание методов

Создание методов сложный и ответственный процесс. Помимо функциональности, методы должны обеспечивать:

  1. Типизацию входных параметров
  2. Фильтрацию параметров
  3. Присвоение параметров по умолчанию
  4. Валидацию обязательных парамеров
  5. Валидацию типизации, существования сущностей
  6. Ответ в случае ошибки
  7. Обработка данных
  8. Ответ в случае успеха

Практика

Разберем весь процесс на примере создания метода, который получит пользователя по e-mail

1. Создание тела метода

Откроем модель App\Models\Users и создадим тело метода:


    public static function getUserByEmail($params)
    {
        TDD::debug($params);
    }

cool Название метода должно быть обязательно в регистре camelCase и отражать весь смысл метода, в нашем случае это getUserByEmail

enlightenedВ качестве единственного параметра, передается $params - массив в котором будет множество параметров

enlightened TDD::debug($params) - это метод дебагера, он будет выводить все параметры в тестах

2. Создаем тест под метод

Создаем файл: /app/tests/Users/Users/getUserByEmail.php

Содержимое:


<?php

include $_SERVER['DOCUMENT_ROOT'] . '/app/configuration/init.php';

use App\Models\Users\Users as User;

\Prologue\Framework\Tests\TDD::start(function () {

    User::getUserByEmail(
        [
            'email' => 'ivan@gmail.ru'
        ]
    );

});

Был создан классический тест, в качестве параметра мы передаем 'email' => 'ivan@gmail.ru'

Запустим тест в браузере http://вашЛокальныйПроект/app/tests/Users/Users/getUserByEmail.php

Тест запущен:

Интерфейс теста отобразил тело тестируемой функции и наши параметры.

3. Задаем типы данных для параметров

Все входящие параметры нужно типизировать и протримить:


    public static function getUserByEmail($params)
    {
        $params['email'] = (string)trim($params['email']);

        TDD::debug($params);
    }

4. Подключаем ошибки

Нужно подключить ошибки, которые в дальнейшем будут использоваться в валидации. Для этого, используйте метод TDD::setErrors(массивСОшибками)


    public static function getUserByEmail($params)
    {
        $params['email'] = (string)trim($params['email']);

        TDD::debug($params);

        TDD::setErrors('userGetUserByEmail');
    }

TDD::setErrors('userGetUserByEmail') - в качестве параметра указали название подсистемы user и название метода GetUserByEmail

Этот метод позволяет подключить ошибки из файла: /app/language/ru/errors.php

Откройте файл и создайте в нем массив userGetUserByEmail с ошибками:

paramEmailRequired Не указан e-mail!
invalidEmail Не корректный e-mail!
userNoExists Пользователь с указанным e-mail не существует!

 

Теперь метод имеет коды ошибок и языковые строки к ним.

5. Валидация

Создадим метод для валидации, в случае ошибко в этом методе - вернем их


    public static function getUserByEmail($params)
    {
        $params['email'] = (string)trim($params['email']);

        TDD::debug($params);

        TDD::setErrors('userGetUserByEmail');

        if ($validateErrors = self::getUserByEmail__validate($params)) {
            return TDD::debug($validateErrors);
        }
    }

    private static function getUserByEmail__validate($params)
    {

    }

cool getUserByEmail__validate() - метод validate название не спроста так. Правило простое: Название родительского метода: getUserByEmail + __ + название метода validate

Обработка обязательных полей в методе getUserByEmail__validate()


    private static function getUserByEmail__validate($params)
    {
        if (!$params['email']) {
            return TDD::debug(
                [
                    'status' => 'error',
                    'errorCode' => 'paramEmailRequired',
                ]
            );
        }
    }

Проверка корректности e-mail


        if (!filter_var($params['email'], FILTER_VALIDATE_EMAIL)) {
            return [
                'status' => 'error',
                'errorCode' => 'invalidEmail',
            ];
        }

Если передать не e-mail, система вернет ошибку:


data                                : Array
(
    [status] => error
    [errorCode] => invalidEmail
    [errorMessage] => Не корректный e-mail!
)

6. Полезное действие

После того, как валидация описана и пройдена, можно делать полезное действие, в нашем случае нужно достать пользователя с указанным e-mail из модели.

Получаем пользователя и выводим его в тест:


        $user = self::find(['email' => $params['email']])->getOne()->data;

        TDD::debug($user);

Запускаем тест и видим что вернулся NULL - потому что такого пользователя нет в базе.

Напишем обработку данной ошибки:


        if (!$user) {
            return TDD::debug(
                [
                    'status' => 'error',
                    'errorCode' => 'userNoExists',
                ]
            );
        }

Занесем пользователя с e-mail который в параметрах в базу пользователей и запустим повторно тест:

Метод вернул нам пользователя.

7. Обработка данных

Обработаем данные в отдельном методе:


    private static function getUserByEmail__handle($user)
    {
        return [
            'id' => (int)$user['id'],
            'name' => (string)$user['name'],
            'email' => (string)$user['email'],
            'phone' => (string)$user['phone'],
        ];
    }

8. Вернем статус успеха и пользователя


        return TDD::debug(
            [
                'status' => 'ok',
                'user' => $user
            ]
        );

 

Запустим тест:

 

Готово! Теперь нужно протестировать метод на разных данных.