Y

yii2-book-catalog

Веб-приложение каталога книг и авторов на Yii2 и MySQL с Docker, тестами и интеграцией SMSPilot

Каталог книг на Yii2

Source Code PHP Yii MySQL Docker CI Software License

Yii2 Book Catalog — web catalog with authors, subscriptions, Top-10 report and SMSPilot

Выберите язык

Русский English Español 中文 Français Deutsch
Выбран English Español 中文 Français Deutsch

Тестовое веб-приложение на Yii2 и MySQL: каталог книг и авторов с загрузкой обложек, связью «многие ко многим», публичным рейтингом авторов, подписками по телефону и тестовой интеграцией SMSPilot.

При реализации основной упор сделан на разделение ответственности: контроллеры занимаются обработкой HTTP-запросов и проверкой доступа, входные данные валидируются на сервере, составные операции с книгой вынесены в отдельный сервис, а отчёт строится одним агрегатным запросом. Проект запускается в Docker и не требует PHP или Composer на хосте.

Возможности

  • публичный каталог книг и авторов;
  • создание, редактирование и удаление книг и авторов после входа в систему;
  • загрузка основного изображения книги;
  • несколько авторов у одной книги и несколько книг у одного автора;
  • публичный Top-10 авторов по количеству книг за выбранный год;
  • подписка гостя по номеру телефона на конкретного автора;
  • тестовые SMS-уведомления о новых книгах через SMSPilot.

Быстрый старт

make init
make build
make up
make composer-install
make migrate

После запуска приложение доступно по адресу http://localhost:8080.

Пользователя для входа можно создать через консольную команду:

make yii CMD="user/create <username> <password>"

Для заполнения каталога демонстрационными данными доступна команда make demo-data. Остальные команды для работы с окружением, тестовой базой и проверками собраны в руководстве по разработке.

Доступ

Пользователь Возможности
Гость Просмотр книг и авторов, Top-10 за выбранный год, подписка по телефону на автора
Пользователь после входа Всё, что доступно гостю, а также создание, редактирование и удаление книг и авторов

Как устроено приложение

HTTP-запрос
    ↓
контроллер
    ↓
модель формы
    ↓
сервис / ActiveRecord / отдельный запрос отчёта
    ↓
MySQL

Контроллеры остаются небольшими и отвечают в основном за веб-сценарий: получить запрос, проверить доступ, запустить валидацию и передать работу дальше. Данные книги проверяет BookForm, а сохранение книги, её связей с авторами и изображения выполняет BookService.

Для Top-10 выделен TopAuthorsQuery: подсчёт выполняется сразу в базе данных одним запросом, а не собирается из загруженных моделей в PHP.

Подробно эти решения, работа с изображениями и границы ответственности разобраны в описании архитектуры.

SMSPilot

После успешного создания книги приложение находит подписчиков её авторов и отправляет уведомления через SMSPilot в тестовом режиме. Отправка начинается только после сохранения книги и её связей в базе данных, поэтому ошибка внешнего сервиса не отменяет уже выполненное создание книги. Если один номер подписан сразу на нескольких авторов новой книги, для него выполняется только одна попытка отправки.

Во время ручной проверки выяснилось, что сообщение с длинным кириллическим названием книги в эмуляторе рассчитывалось как более дорогое составное SMS: 19.74 против 9.87 после сокращения текста. Поэтому название книги из уведомления убрано, а текст ограничен двумя короткими вариантами для одного или нескольких подходящих авторов.

Ответы SMSPilot, последовательность отправки и обработка ошибок приведены в описании интеграции.

Что намеренно оставлено простым

  • SMS отправляются синхронно после сохранения книги. Для приложения с заметной нагрузкой эту работу стоило бы вынести из HTTP-запроса в очередь фоновых задач, например через yiisoft/yii2-queue. Для тестового задания отдельный обработчик очереди и дополнительная инфраструктура не добавлялись.
  • ActiveRecord используется напрямую там, где возможностей Yii достаточно для обычного чтения и записи данных. Дополнительный слой репозиториев вокруг каждой модели не вводился, потому что в приложении такого размера он только дублировал бы уже существующий слой работы с базой данных.
  • Отдельный REST API и клиентское SPA не добавлялись: приложение реализовано как обычный серверный Yii2 Web.