Продолжаем улучшать наш онлайн-магазин. В предыдущей статье мы рассмотрели создание системы универсальных скидок. А сегодня добавим категории для удобного поиска товаров.
Что нужно от категорий. Во-первых, должна быть иерархия. То есть каждая категория может иметь неограниченное число подкатегорий, которые могут иметь свои подкатегории и так далее. Во-вторых, товар может быть размещен сразу в нескольких категориях. Это удобно для группировки товаров по разным признакам.
В декларативном фреймворке Evado подобные связи между сущностями легко настраиваются через веб-интерфейс. Устанавливаем и запускаем веб-приложение «Книжный магазин».
Обратите внимание, что в репозитории активна последняя версия приложения с уже сделанными изменения, описанными в данной статье. Исходная версия доступна по метке v3.0.0.
Создание метаданных
Переходим в веб-интерфейс модуля «Студия». Создаем новый класс «Категория». Добавляем обязательный строковый атрибут «Название», а также целочисленный атрибут «Порядковый номер» для произвольной сортировки категорий.
Иерархия категорий будет построена на рекурсивном отношении «родитель - ребёнок» - каждый ребёнок может иметь только одного родителя. Для этого добавляем ссылочный атрибут «Родитель», который ссылается на класса «Категория». Чтобы отобразить всех прямых потомков, добавляем обратную ссылку «Дочерние категории».
Обратные ссылки не хранят значение связи, а получают его из указанного ссылочного атрибута.
Указываем ссылочный класс «Категория» и ссылочный атрибут «Родитель». Теперь категории у которых родителем является текущая, отобразятся как дочерние.
Переходим в класс «Товар» и создаем ссылочный атрибут «Категории». Так как товар можно разместить в нескольких категорий, то ставим флажок «Множественная связь». Переходим в преставление «Публичный вид», которое отвечает за отображение товаров для пользовательского интерфейса, и добавляем атрибут «Категории». Выставляем флажок «Жадная загрузка», чтобы ссылочные объекты загружались вместе с основным.
Древовидное представление
Чтобы наглядно отобразить иерархию категорий в модуле «Офис», создаем «Древовидное представление» с двумя атрибутами - «Название» и «Порядковый номер».
Представления класса служат для переопределения его параметров и атрибутов для использования в некоторых случаях (например, при создании объекта, отображении объектов в списке и тому подобное).
Затем создаем «Представление корневых категорий». В нем также, как и в предыдущем, только два атрибута, но, кроме этого, добавляем фильтр на отсутствие родителя.
Переходим на вкладку «Древовид» и добавляем новый уровень. Указываем «Дочерние категории» как ссылочный атрибут, который формирует данные, а представлением для них - «Древовидное представление», созданное выше. Ставим флажок «Рекурсивно», чтобы эти же настройки распространились на следующие уровни вложенности.
Далее переходим в меню «Секции навигации» и добавляем для главной секции новый пункт «Категории», указав класс «Категория» и представление «Представление корневых категорий».
Экспортируем метаданные в папку приложения metadata/app. При этом метаданные будут автоматически обновлены и станут доступны в приложении.
Права доступа
Чтобы пользователи получили доступ к категориям необходимо дать соответствующее разрешение. Для этого переходим в модуле «Администрирование» в меню «Безопасность» - «Разрешения метаданных». Находим разрешение, дающее право чтение скидок и изображения для авторизованных и анонимных (гостевых) пользователей, и добавляем к нему класс «Категория».
В декларативном фреймворке Evado управление правами доступа осуществляется на основе ролей. Каждому пользователю назначаются роли, а разрешения, дающие права на определенные действия, назначаются уже на эти роли.
Перезапускаем безопасность кнопкой на верхней панели, чтобы сделанные изменения вступили в силу.
Создание категорий
Переходим в модуль «Офис». В боковом меню появился пункт «Категории». Добавляем категории и привязываем к ним товары.
Пользовательский интерфейс
Эксплуатация приложения неограниченна модулем «Офис». Используя AJAX API, дающее доступ, как к данным, так и метаданным приложения, можно реализовывать любые пользовательские интерфейсы.
В данном случае, примером такого интерфейса является модуль «Front». Хотя он и запускается вместе с приложением, но ничто не мешает реализовать его независимо, на отдельном сервере.
Заключение
Готовое веб-приложение магазина доступно в открытом репозитории.