Полное руководство по функции cot_market_enum()
Функция cot_market_enum() — это мощный генератор списков товаров для модуля Market в Cotonti. Она позволяет вывести товары в любом месте сайта: на главной странице, в сайдбаре, в профиле пользователя, в произвольном плагине и т.д. Возвращает готовую HTML-строку, которую можно вывести напрямую или передать в шаблон.
1. Что делает функция?
cot_market_enum() формирует SQL-запрос к таблице товаров cot_market, применяет заданные фильтры (категории, условия, статус, даты), сортировку, при необходимости ограничивает количество и пагинацию, затем рендерит результаты через шаблон market.enum.tpl (или пользовательский) и возвращает итоговый HTML.
Она объединяет в себе:
- выборку из базы данных;
- обработку категорий (включая подкатегории и чёрный список);
- фильтрацию по активности (опубликованные, дата начала/окончания);
- поддержку дополнительных условий;
- постраничную навигацию;
- кэширование;
- интеграцию с комментариями (если плагин активен);
- вызов хуков для расширения.
2. Сигнатура и параметры
function cot_market_enum(
$categories = '',
$count = 0,
$template = '',
$order = '',
$condition = '',
$active_only = true,
$use_subcat = true,
$exclude_current = false,
$blacklist = '',
$pagination = '',
$cache_ttl = null
)2.1. $categories (string|array)
Категории, товары которых нужно показать.
- Если
''— будут выбраны товары из всех категорий. - Можно указать строку с кодами категорий через запятую:
'electronics,books'. - Можно передать массив:
['electronics', 'books']. - Внутри функция преобразует строку в массив, убирает дубликаты.
- Если
$use_subcat = true(по умолчанию), то к каждой указанной категории будут добавлены все её подкатегории (рекурсивно). Для этого используетсяcot_structure_children(). - Если
$blacklistне пуст, то категории из чёрного списка будут исключены из итогового списка.
// Только категория 'electronics' и её подкатегории
cot_market_enum('electronics', 10);
// Категории 'electronics' и 'books' без подкатегорий
cot_market_enum(['electronics', 'books'], 10, '', '', '', true, false);2.2. $count (int)
Количество товаров для вывода.
0— вывести все товары, удовлетворяющие условиям (если пагинация выключена).- Если
$paginationзадан (не пустая строка), то$countинтерпретируется как количество товаров на одну страницу. - Если
$count > 0и пагинация выключена, будет выведено только указанное количество (обычно последние/первые в зависимости от сортировки).
// Показать 5 последних товаров
cot_market_enum('', 5);
// Показать все товары (осторожно, может быть много)
cot_market_enum('', 0);2.3. $template (string)
Имя части шаблона или путь к файлу шаблона для рендеринга виджета.
- Если
''или не указан, используется стандартный шаблон модуля:market.enum.tpl. - Рекомендуемый способ: передайте имя части шаблона, например
'sidebar'. Функция вызоветcot_tplfile(['market', 'enum', 'sidebar'], 'module'), который сначала ищет файл в теме (themes/ваша_тема/modules/market/enum.sidebar.tpl), а затем в модуле (modules/market/tpl/market.enum.sidebar.tpl). Такой подход позволяет легко переопределять шаблоны в теме. - Можно указать и полный путь к файлу (например,
'modules/market/tpl/market.enum.custom.tpl'), если файл существует. Однако этот метод менее гибкий и привязывает к конкретному расположению.
// Рекомендуется: указать имя части шаблона
cot_market_enum('', 5, 'sidebar'); // будет искать market.enum.sidebar.tpl
// Альтернатива: полный путь (работает, но менее предпочтительно)
cot_market_enum('', 5, 'modules/market/tpl/market.enum.sidebar.tpl');2.4. $order (string)
SQL-выражение для сортировки.
- Если не задано (
''), используется'ORDER BY fieldmrkt_date DESC'— сначала новые. - Вы можете указать любое валидное SQL-выражение после
ORDER BY. Например:'fieldmrkt_costdflt ASC'— по возрастанию цены;'fieldmrkt_title ASC'— по алфавиту;'fieldmrkt_updated DESC'— по дате обновления.
Важно: поле должно существовать в таблице cot_market. Стандартные поля: fieldmrkt_id, fieldmrkt_title, fieldmrkt_desc, fieldmrkt_text, fieldmrkt_costdflt, fieldmrkt_date, fieldmrkt_updated, fieldmrkt_count и другие.
cot_market_enum('', 10, '', 'fieldmrkt_costdflt DESC'); // дорогие сверху2.5. $condition (string)
Дополнительное SQL-условие (без слова WHERE).
- Позволяет фильтровать товары по любым полям.
- Строка будет вставлена в секцию
WHEREв дополнение к остальным условиям. - Нужно следить за экранированием и корректностью SQL.
// Только товары дороже 100
cot_market_enum('', 0, '', '', 'fieldmrkt_costdflt > 100');
// Товары с определённым артикулом
cot_market_enum('', 5, '', '', "fieldmrkt_pcod = 'ABC123'");2.6. $active_only (bool)
Показывать только опубликованные и активные товары.
- Если
true(по умолчанию), добавляются условия:fieldmrkt_state = 0— опубликован;fieldmrkt_begin <= {текущее время}— дата начала публикации уже наступила;fieldmrkt_expire = 0 OR fieldmrkt_expire > {текущее время}— срок окончания не истёк.
- Если
false, будут показаны все товары, включая черновики, на модерации и просроченные (будьте осторожны с правами доступа).
// Показать все товары без ограничений (например, для админки)
cot_market_enum('', 10, '', '', '', false);2.7. $use_subcat (bool)
Включать подкатегории при выборке по категориям.
- Если
true(по умолчанию), для каждой указанной категории будут добавлены все её потомки (на любую глубину). - Если
false, будут выбраны товары только из точно указанных категорий.
// Только родительская категория, без подкатегорий
cot_market_enum('electronics', 10, '', '', '', true, false);2.8. $exclude_current (bool)
Исключить текущий просматриваемый товар.
- Работает только если константа
COT_MARKETопределена и мы не на странице списка (COT_LISTне определена). - Использует глобальную переменную
$id(ID текущего товара). - Полезно на странице товара, чтобы показывать "похожие товары" без самого товара.
// На странице товара: показать 5 товаров из той же категории, кроме текущего
cot_market_enum($item_data['fieldmrkt_cat'], 5, '', 'fieldmrkt_date DESC', '', true, true, true);2.9. $blacklist (string|array)
Чёрный список категорий.
- Категории, которые нужно исключить из выборки.
- Можно передать строку с кодами через запятую:
'system,drafts'или массив:['system', 'drafts']. - Если категории не заданы (первый параметр пуст), то товары из этих категорий будут исключены из общего списка.
- Если категории заданы, то чёрный список применяется к ним (удаляет указанные коды).
// Показать все товары, кроме служебных категорий
cot_market_enum('', 10, '', '', '', true, true, false, 'system,drafts');2.10. $pagination (string)
Имя GET-параметра для постраничной навигации.
- Если пустая строка
''— пагинация отключена. - Если задано, например
'p', функция будет:- обрабатывать параметр
pиз URL для определения текущей страницы; - выводить только
$countтоваров на текущей странице; - генерировать HTML пагинации (ссылки на другие страницы).
- обрабатывать параметр
- Параметр передаётся в
cot_pagenav(), поэтому в URL появятся ссылки вида?p=2.
// Пагинация по 5 товаров, параметр 'p'
cot_market_enum('', 5, '', 'fieldmrkt_date DESC', '', true, true, false, '', 'p');2.11. $cache_ttl (int|null)
Время жизни кэша в секундах.
- Если
nullили0— кэширование отключено. - Если
> 0, то сгенерированный HTML сохраняется в дисковый кэш Cotonti (если он включён) с указанным TTL. - Ключ кэша зависит от шаблона, языка и SQL-запроса (с заменой текущего времени на
_time_), поэтому при изменении данных товаров кэш может устареть. Рекомендуется использовать умеренные значения (например, 300–3600 секунд).
// Кэшировать на 10 минут
cot_market_enum('', 5, '', 'fieldmrkt_date DESC', '', true, true, false, '', '', 600);3. Как функция работает внутри (краткий обзор)
- Обработка чёрного списка: строка преобразуется в массив.
- Обработка категорий:
- Если
$categoriesне пуст, преобразуется в массив. - Если
$use_subcatвключён, для каждой категории вызываетсяcot_structure_children()для получения всех потомков. - Применяется чёрный список.
- Формируется условие
fieldmrkt_cat IN (...). - Если категории не указаны, но есть чёрный список, формируется условие
fieldmrkt_cat NOT IN (...).
- Если
- Дополнительное условие
$conditionдобавляется в WHERE. - Исключение текущего товара (если включено).
- Фильтр активности (если
$active_only): добавляются условия по статусу и датам. - Пагинация: если
$paginationзадан, вычисляется смещение$dчерезcot_import_pagenav(). - Выбор шаблона: если
$templateне пуст и файл существует (или имя части шаблона), используется он; иначе стандартныйmarket.enum.tpl. - Хук
market.enum.query: позволяет модифицировать запрос (таблицы, колонки). - Подключение комментариев (если активен плагин): добавляется подзапрос для подсчёта количества комментариев.
- Формируются SQL-запросы:
$sql_total— для подсчёта общего количества (для пагинации);$sql_query— для выборки данных (с JOIN пользователей).
- Кэширование: проверяется наличие кэша; если найден — возвращается готовый HTML.
- Выполнение запроса выборки и цикл по результатам:
- для каждого товара генерируются теги через
cot_generate_markettags()(префиксMARKET_ROW_); - добавляются дополнительные теги:
MARKET_ROW_NUM,MARKET_ROW_ODDEVEN,MARKET_ROW_RAW; - генерируются теги владельца (
MARKET_ROW_OWNER_...); - хук
market.enum.loop; - если комментарии активны, добавляются теги
MARKET_ROW_COMMENTS_LINKиMARKET_ROW_COMMENTS_COUNT; - блок
MAIN.MARKET_ROWпарсится.
- для каждого товара генерируются теги через
- Пагинация: если включена, строится
cot_pagenav()и присваиваются теги пагинации. - Хук
market.enum.tags. - Финальный парсинг блока
MAIN, сохранение в кэш (если нужно) и возврат HTML.
4. Примеры использования
4.1. В PHP-коде (контроллер, плагин)
Простой вывод последних 5 товаров
$html = cot_market_enum('', 5);
echo $html;Вывод товаров из категории "electronics" с подкатегориями
$html = cot_market_enum('electronics', 10);
echo $html;Передача в шаблон
$t->assign('MARKET_LATEST', cot_market_enum('', 5, '', 'fieldmrkt_date DESC'));Виджет для сайдбара: популярные товары (по просмотрам)
$sidebar_market = cot_market_enum('', 5, '', 'fieldmrkt_count DESC');
$t->assign('SIDEBAR_MARKET', $sidebar_market);Товары со скидкой (цена < 50), отсортированные по цене
$html = cot_market_enum('', 10, '', 'fieldmrkt_costdflt ASC', 'fieldmrkt_costdflt < 50');
echo $html;Исключить текущий товар на странице товара
if (defined('COT_MARKET') && !defined('COT_LIST')) {
$html = cot_market_enum($item_data['fieldmrkt_cat'], 5, '', 'fieldmrkt_date DESC', '', true, true, true);
echo $html;
}Использование в плагине
// Внутри вашего плагина
function myplugin_show_market_widget() {
if (cot_module_active('market')) {
require_once cot_incfile('market', 'module');
return cot_market_enum('', 5, '', 'fieldmrkt_date DESC');
}
return '';
}4.2. В шаблонах Cotonti (через тег {PHP|...})
Внимание: в шаблонах можно вызывать функцию напрямую, но лучше это делать в PHP и передавать переменную, чтобы не смешивать логику и представление. Однако для простых случаев возможно.
<!-- 5 последних товаров -->
<div>{PHP|cot_market_enum('', 5, '', 'fieldmrkt_date DESC')}</div>
<!-- 6 товаров из категории 'books' с пагинацией по 3 (параметр p) -->
<div>{PHP|cot_market_enum('books', 3, '', 'fieldmrkt_date DESC', '', true, true, false, '', 'p')}</div>Примечание: в теге {PHP|...} нельзя использовать echo. Функция должна возвращать строку, которая будет выведена автоматически.
5. Настройка шаблонов виджета
Стандартный шаблон находится в modules/market/tpl/market.enum.tpl. Вы можете:
- Переопределить в теме: создайте файл
themes/yourtheme/modules/market/enum.tpl— он будет использован автоматически. - Указать другой файл через параметр
$template(имя части шаблона или полный путь).
Внутри шаблона доступны блоки:
<!-- BEGIN: MAIN --> ... <!-- END: MAIN -->— основной контейнер.<!-- BEGIN: MARKET_ROW --> ... <!-- END: MARKET_ROW -->— повторяется для каждого товара.
Внутри MARKET_ROW можно использовать теги, сгенерированные cot_generate_markettags() с префиксом MARKET_ROW_. Например:
{MARKET_ROW_TITLE}— заголовок товара (экранирован){MARKET_ROW_URL}— ссылка на товар{MARKET_ROW_TEXT_SHORT}— краткое описание{MARKET_ROW_COSTDFLT}— цена{MARKET_ROW_CAT_TITLE}— название категории- и другие (полный список в функции
cot_generate_markettags)
Дополнительные теги, добавляемые функцией cot_market_enum:
{MARKET_ROW_NUM}— порядковый номер{MARKET_ROW_ODDEVEN}—oddилиeven{MARKET_ROW_RAW}— массив данных товара (для отладки){MARKET_ROW_OWNER_NAME}и другие теги владельца, если используетсяcot_generate_usertags(){MARKET_ROW_COMMENTS_COUNT},{MARKET_ROW_COMMENTS_LINK}— если активен плагин comments
Пример минимального шаблона:
<!-- BEGIN: MAIN -->
<div class="market-widget">
<!-- BEGIN: MARKET_ROW -->
<div class="item {MARKET_ROW_ODDEVEN}">
<a href="{MARKET_ROW_URL}">{MARKET_ROW_TITLE}</a>
<div class="price">{MARKET_ROW_COSTDFLT}</div>
</div>
<!-- END: MARKET_ROW -->
</div>
<!-- END: MAIN -->6. Важные замечания и возможные ошибки
- Безопасность: параметр
$conditionвставляется в SQL-запрос как есть. Не передавайте в него неэкранированные пользовательские данные. Используйте подготовленные выражения, если нужно. - Права доступа: функция не проверяет права пользователя на чтение категорий. Если вы используете её на публичной странице, убедитесь, что
$active_only = true, чтобы не показывать скрытые товары. Для админки можно ставитьfalse. - Производительность: при большом количестве товаров и выключенном кэше функция может создавать нагрузку. Используйте кэш (
$cache_ttl) для статичных виджетов. - Пагинация: если включена, обязательно укажите
$count > 0. В противном случаеcot_pagenav()может работать некорректно. - Совместимость: функция использует глобальные переменные
$db,$db_marketи др. Убедитесь, что модуль Market подключён (require_once cot_incfile('market', 'module');). - Хуки: если вы пишете плагин, вы можете влиять на выборку через хуки
market.enum.query,market.enum.loop,market.enum.tags.
7. Как вывод
cot_market_enum() — гибкий инструмент для отображения списков товаров. Освоив её параметры и принципы работы, вы сможете легко встраивать товарные виджеты в любые части сайта, не написав ни строчки SQL. Для сложных сценариев используйте комбинацию параметров, хуков и собственных шаблонов.
8. Вызов функции cot_market_enum() прямо в шаблонах Cotonti
Cotonti использует шаблонизатор CoTemplate (класс XTemplate), который поддерживает вставку PHP-функций через тег {PHP|...}. Внутри таких тегов можно вызывать любые глобальные функции, в том числе cot_market_enum(). Функция должна возвращать строку, которая будет автоматически выведена в месте вызова. Использование echo внутри тега не требуется и приведёт к ошибке.
Общая форма вызова в шаблоне:
{PHP|cot_market_enum(аргументы)}Все параметры функции передаются так же, как в PHP-коде, но в одной строке. Для удобства чтения можно переносить аргументы? В шаблонах переносы внутри тега возможны, но лучше держать всё в одной строке.
8.1. Простые примеры
<!-- Показать 5 последних товаров из всех категорий -->
<div class="latest-products">
{PHP|cot_market_enum('', 5, '', 'fieldmrkt_date DESC')}
</div>
<!-- Показать 6 товаров из категории 'electronics' и её подкатегорий -->
<div class="electronics-products">
{PHP|cot_market_enum('electronics', 6, '', 'fieldmrkt_date DESC')}
</div>
<!-- Показать товары с пагинацией по 4 на страницу (параметр p) -->
<div class="paged-products">
{PHP|cot_market_enum('', 4, '', 'fieldmrkt_date DESC', '', true, true, false, '', 'p')}
</div>
8.2. Примеры с дополнительными условиями
<!-- Товары дороже 100, сортировка по цене -->
<div class="expensive-products">
{PHP|cot_market_enum('', 8, '', 'fieldmrkt_costdflt ASC', 'fieldmrkt_costdflt > 100')}
</div>
<!-- Товары из категории 'books' без подкатегорий, только опубликованные -->
<div class="books-no-subcat">
{PHP|cot_market_enum('books', 5, '', 'fieldmrkt_date DESC', '', true, false)}
</div>
8.3. Исключение текущего товара
Если шаблон используется на странице товара (когда определена константа COT_MARKET и не определена COT_LIST), можно вывести похожие товары, исключив текущий:
<div class="related-products">
{PHP|cot_market_enum(PHP.cat, 5, '', 'fieldmrkt_date DESC', '', true, true, true)}
</div>Внимание: здесь предполагается, что в шаблоне доступна переменная {PHP.cat} с кодом текущей категории. Если это не так, лучше подготовить значение в PHP-коде и передать в шаблон, а затем вызвать функцию с этим значением.
8.4. Использование кэширования
<div class="cached-widget">
{PHP|cot_market_enum('', 5, '', 'fieldmrkt_date DESC', '', true, true, false, '', '', 600)}
</div>8.5. Важные замечания при вызове в шаблоне
- Функция
cot_market_enum()должна быть доступна в области видимости шаблона. Она определена в файлеmodules/market/inc/market.functions.php, который подключается при загрузке модуля Market. Убедитесь, что модуль активен и файл функций загружен. - Все строки с кавычками внутри аргументов должны быть корректно экранированы для HTML. Используйте одинарные кавычки для строк в PHP-вызове, чтобы не конфликтовать с двойными кавычками атрибутов HTML.
- Не используйте
echoвнутри{PHP|...}. Результат функции выводится автоматически. - Для сложных условий и передачи массивов лучше предварительно вычислить результат в PHP-коде и передать его в шаблон через
assign(). Прямой вызов в шаблоне подходит для простых случаев, когда параметры статичны. - Если вы используете пагинацию, убедитесь, что в URL передаются все необходимые параметры. Функция сама построит ссылки на основе текущего URL, но лучше тестировать.
- Производительность: каждый вызов в шаблоне порождает отдельный SQL-запрос. Для часто используемых виджетов рекомендуется кэширование (
$cache_ttl).
Таким образом, вы можете быстро добавить списки товаров в любые части шаблонов вашей темы без изменения PHP-кода, если модуль Market уже загружен.