Multicat Market — множественные категории одного товара для модуля Market v.5.x.x (Cotonti Siena)
Описание и принцип работы
Плагин Multicat Market добавляет возможность размещать одно объявление/товар (страницу модуля Market) одновременно в нескольких категориях структуры market.
До установки этого плагина каждая страница Market могла принадлежать только одной категории (поле page_cat → fieldmrkt_cat). После установки плагина:
- Основная категория по-прежнему хранится в стандартном поле
fieldmrkt_cat (это нужно для совместимости с ядром и другими плагинами). - Все выбранные категории (включая основную) дополнительно сохраняются в отдельной таблице
cot_market_multicats. - При просмотре списка товаров в любой категории (
market.list) плагин автоматически подмешивает в запрос условие, которое находит товары и по старому полю, и по новой таблице связей — поэтому товар отображается во всех выбранных категориях. - При редактировании объявления вместо одного селекта категории появляется набор чекбоксов — можно выбрать сколько угодно категорий.
- Первая выбранная категория автоматически становится «основной» (
fieldmrkt_cat) — это гарантирует полную совместимость со всеми существующими шаблонами и функциями ядра.
Таким образом, плагин полностью прозрачен для пользователя и других расширений: всё продолжает работать как раньше, но появляется новая возможность — мультикатегоризация.
Важно: плагин не будет работать с вашим модулем Market, если он не 5-й версии и не моей разработки. Вы можете заказать адаптацию плагина под модули сборки фриланс-биржи. Для этого напишите мне на странице
Установка
- Распаковать архив и папку
multicatmarket загрузить на сервер в папку plugins/. - Зайти в админку → Расширения → Multicat Market → Установить.
- После установки плагина, в шаблон
market.edit.tpl добавить два тега сразу после стандартного селектора категорий:
<!-- IF {PHP|cot_plugin_active('multicatmarket')} -->
<div class="col-12">
<label for="marketCat" class="form-label fw-semibold">{PHP.L.multicatmarket_cats_edit}</label>
<div class="input-group has-validation">{MARKET_FORM_MULTICAT}</div>
<small class="form-text text-muted mt-1">{MARKET_FORM_MULTICAT_HINT}</small>
</div>
<!-- ENDIF -->
в шаблон market.admin.tpl в нужном месте, например сразу после статуса, добавить
<!-- IF {PHP|cot_plugin_active('multicatmarket')} -->
<div class="text-muted small">{ADMIN_PAGE_MULTICATS}</div>
<!-- ENDIF -->
- Готово! Теперь при редактировании карточки товара будет список чекбоксов с категориями.
Важно: если не добавить эти теги в шаблон — множественные категории работать не будут (просто не будет формы выбора).
Структура файлов и назначение каждого файла
/multicatmarket/
├── inc/
│ └── multicatmarket.functions.php ← основные функции работы с мультикатугориями
├── lang/
│ ├── multicatmarket.ru.lang.php ← русский языковой файл
│ └── multicatmarket.en.lang.php ← английский языковой файл
├── setup/
│ ├── multicatmarket.install.sql ← создание таблицы `cot_market_multicats` + миграция существующих данных
│ └── multicatmarket.uninstall.sql ← удаление таблицы при деинсталляции
├── multicatmarket.admin.loop.php ← хук market.admin.loop — выводит категории в админ-списке
├── multicatmarket.market.delete.first.php ← хук market.delete.first — удаляет связи при удалении товара
├── multicatmarket.market.edit.import.php ← хук market.edit.update.import — берёт категории из POST и ставит первую как основную
├── multicatmarket.market.edit.tags.php ← хук market.edit.tags — генерирует чекбоксы в форме редактирования
├── multicatmarket.market.edit.update.done.php ← хук market.edit.update.done — сохраняет связи в БД после обновления
├── multicatmarket.market.list.query.php ← хук market.list.query — главный фильтр списка по категории с учётом мультикатегорий
├── multicatmarket.global.php ← хук global - глобальная инициализация, регистрация таблицы, без него получим ошибку 500
└── multicatmarket.setup.php ← регистрация плагина в ядре Cotonti и настройки конфигурации
Подробное описание каждого файла и хука
1. multicatmarket.global.php
Глобальный файл плагина. Подключается автоматически при любой загрузке Cotonti.
Да, это не очень желательно, но пока это так. Регистрирует таблицу cot_market_multicats в системе:
Cot::$db->registerTable('market_multicats');
Без этого файла при обращении к таблице будет ошибка 500.
2. multicatmarket.setup.php
Регистрирует метаданные плагина в таблице cot_core Добавляет настройки конфигурации в таблице cot_config
3. inc/multicatmarket.functions.php
Содержит три основные функции:
multicatmarket_get_cats($page_id) — возвращает массив structure_id категорий, в которых находится товар.multicatmarket_get_cat_titles($page_id) — возвращает массив названий категорий (используется в админке).multicatmarket_save_cats($page_id, $cats) — при сохранении, на странице редактирования, полностью заменяет связи товара с категориями (удаляет старые, вставляет новые в cot_market_multicats) не путать с fieldmrkt_cat !!!.
4. lang/multicatmarket.ru.lang.php
Все строки интерфейса и подсказки на русском языке:
- название плагина,
- текст подсказки под чекбоксами,
- сообщение об ошибке, если не выбрана ни одна категория,
- инструкция по вставке тегов в шаблон.
5. setup/multicatmarket.install.sql
Создаёт таблицу. И сразу выполняет миграцию: берёт все существующие товары, смотрит их fieldmrkt_cat (код категории), находит соответствующий structure_id и записывает связь в новую таблицу.
Благодаря этому после установки плагина все старые товары автоматически появляются в своих категориях — ничего не теряется.
CREATETABLEIF NOT EXISTS `cot_market_multicats` (
`pcat_page_id`int UNSIGNED NOT NULL,
`pcat_cat_id` mediumint UNSIGNED NOT NULL,
UNIQUE KEY `pcat_unique` (`pcat_page_id`, `pcat_cat_id`),
KEY `pcat_page_id` (`pcat_page_id`),
KEY `pcat_cat_id` (`pcat_cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Миграция существующих категорий, только валидные fieldmrkt_id и structure_id
INSERT IGNORE INTO`cot_market_multicats` (`pcat_page_id`, `pcat_cat_id`)
SELECTp.fieldmrkt_id, s.structure_id
FROM`cot_market` p
JOIN`cot_structure` s
ONp.fieldmrkt_cat=s.structure_code
WHEREp.fieldmrkt_id>0
ANDs.structure_id>0
ANDp.fieldmrkt_cat!=''
ANDs.structure_area='market';
6. multicatmarket.admin.loop.php → хук market.admin.loop
В Панели Управления, в админке, при просмотре списка товаров Управление сайтом -> Расширения -> Market -> Администрирование (market.admin.php) добавляет колонку с перечислением всех категорий, в которых находится товар.
Использует функцию multicatmarket_get_cat_titles() и выводит тег ADMIN_PAGE_MULTICATS.
7. multicatmarket.market.delete.first.php → хук market.delete.first
Выполняется до удаления товара. Удаляет все записи из cot_market_multicats для данного page_id.
Необходим, чтобы не оставалось «висячих» связей.
8. multicatmarket.market.edit.import.php → хук market.edit.update.import
Выполняется на этапе импорта данных из формы редактирования карточки товара.
Если в $_POST['rcat'] пришли выбранные категории — берёт первую из них, находит её код (structure_code) и записывает в стандартное поле fieldmrkt_cat.
Это гарантирует, что основная категория всегда заполнена и все остальные функции продолжают работать.
9. multicatmarket.market.edit.tags.php → хук market.edit.tags
Самый «видимый» хук. Генерирует набор чекбоксов со всеми категориями Market, учитывая права доступа пользователя (cot_auth('market', $code, 'W')).
Создаёт два тега для шаблона:
{MARKET_FORM_MULTICAT} — сами чекбоксы{MARKET_FORM_MULTICAT_HINT} — подсказка «Выберите категории (можно выбрать несколько)»
10. multicatmarket.market.edit.update.done.php → хук market.edit.update.done
Выполняется после успешного обновления товара в БД.
Если в POST пришли rcat — вызывает multicatmarket_save_cats() и сохраняет все выбранные связи.
11. multicatmarket.market.list.query.php → хук market.list.query
Самая важная часть плагина — именно здесь реализуется отображение товара в нескольких категориях.
Когда пользователь заходит в категорию с кодом $c, плагин:
- Находит
structure_id этой категории. - Подменяет условие фильтрации по категории:
вместо простого p.fieldmrkt_cat = 'code'
ставит
(p.fieldmrkt_cat = 'code' OR EXISTS (SELECT 1 FROM cot_market_multicats …))
Таким образом запрос возвращает как товары, у которых эта категория основная, так и товары, у которых она дополнительная.
Итог
Плагин полностью решает задачу множественных категорий для модуля Market, сохраняя 100% совместимость с ядром и другими расширениями.
Никаких изменений в ядро Cotonti и в модуль Market не вносится — всё реализовано через стандартные хуки и отдельную таблицу связей.
Если вам нужно, чтобы один и тот же товар отображался в нескольких рубриках — просто установите Multicat Market и добавьте два тега в шаблоны редактирования карточки товара.
Версия: 1.1.0
Дата: 2025-12-05
Автор: webitproff
Совместимость: Cotonti Siena 0.9.26+, модуль Market v5+, PHP 8.1–8.4, MySQL 8.0+
Лицензия: BSD
Репозиторий:https://github.com/webitproff/cotonti-multicatmarket