Описание работы поиска в модуле MultiStore
Это описание предназначено для администраторов и разработчиков, работающих с модулем MultiStore в Cotonti Siena (версия 0.9.26, PHP 8.4). Оно объясняет, как работает поиск в списке товаров (файл mstore.list.php), включая интерфейс, логику обработки запросов и технические детали. Поиск реализован на фронтенде и интегрирован в интерфейс списка товаров, позволяя фильтровать товары по заголовку (msitem_title) и тексту (msitem_text).
Для администратора: Как работает поиск
Поиск в MultiStore помогает находить товары по словам в их названии или описании. Он доступен на странице списка товаров (URL: mstore) и используется для быстрого поиска контента.
- Где находится поиск: На странице списка товаров есть форма с текстовым полем для ввода запроса и выпадающим списком категорий. Поле ввода — это строка с автоматическим фокусом (атрибут
autofocus), а список категорий использует библиотеку Select2 для удобного выбора. - Что можно искать: Поиск находит товары, где введенное слово или фраза встречаются в заголовке или полном тексте описания. Например, запрос "самокат" покажет все товары, где это слово есть в названии или тексте.
- Фильтрация по категориям: Вы можете выбрать категорию (например, "Электросамокаты") или искать по всем категориям. Это ограничивает результаты только выбранной категорией, что удобно для узкого поиска.
- Результаты: После ввода запроса и нажатия Enter отображается список подходящих товаров. Если товары найдены, показывается сообщение, например: "5 позиций найдено по запросу: самокат". Если ничего не найдено, сообщение будет: "По запросу самокат ничего не найдено".
- Пагинация: Если результатов много, они разбиваются на страницы (по умолчанию 10 товаров на страницу, задается в настройке
mstoremaxlistsperpage). Вы можете переключаться между страницами с помощью ссылок "Далее", "Назад", "Первая", "Последняя". - Права доступа: Администратор видит все опубликованные товары, а также свои товары в состоянии "на рассмотрении" или "черновик". Это зависит от прав доступа к категориям (проверяется через
cot_auth('mstore', $c, 'R')). - Управление: Поиск помогает администратору найти товары для проверки, редактирования или удаления. Например, можно найти товар на рассмотрении и валидировать его через админ-панель.
Для разработчика: Техническая реализация поиска
Поиск реализован в файле mstore.list.php. Ниже описана логика обработки запросов, SQL-запросы и интеграция с шаблоном.
- Импорт запроса: Поисковый запрос импортируется из GET-параметра
sqс помощью функцииcot_import('sq', 'G', 'TXT'). Запрос обрезается функциейtrim($sq), чтобы удалить начальные и конечные пробелы. Если параметрsqне задан (равенnull), устанавливается пустая строка:$sq = ($sq !== null) ? trim($sq) : '';. SQL-условие поиска: Если запрос не пустой (
!empty($sq)), в массив условий SQL добавляется:$where['search'] = "p.msitem_title LIKE :sq OR p.msitem_text LIKE :sq";Это означает, что поиск ищет подстроку в полях
msitem_titleилиmsitem_text. Значение запроса передается в массив параметров как$params['sq'] = "%$sq%";для безопасного использования с оператором LIKE.Фильтрация по категории: Категория импортируется через
cot_import('c', 'G', 'TXT'). Если категория выбрана и существует в структуре (Cot::$structure['mstore'][$c]), добавляется условие:$where['cat'] = 'msitem_cat = ' . Cot::$db->quote($c);Иначе поиск охватывает все категории модуля:
$where['cat'] = "msitem_cat IN (SELECT structure_code FROM $db_structure WHERE structure_area = 'mstore')";Список категорий генерируется функцией
cot_mstore_selectcat_select2($c, 'c'), которая создает выпадающий список с Select2, включая "Все категории" и отступы для подкатегорий.Права доступа: Условие для видимости товаров ограничивает результаты:
$where['state'] = '(msitem_state = ' . MstoreDictionary::STATE_PUBLISHED . ' OR (msitem_state = ' . MstoreDictionary::STATE_PENDING . ' AND msitem_ownerid = ' . Cot::$usr['id'] . '))';Это позволяет администратору видеть опубликованные товары и свои товары в состоянии "на рассмотрении" или "черновик".
SQL-запрос: Основной запрос для получения товаров:
SELECT p.*, u.* $join_columns FROM $db_mstore AS p $join_condition LEFT JOIN $db_users AS u ON u.user_id = p.msitem_ownerid $where_sql GROUP BY p.msitem_id ORDER BY $orderby LIMIT $d, $maxItemRowsPerPageЗдесь
$where_sqlобъединяет все условия (поиск, категория, права) черезAND, а$paramsпередает значениеsqдля LIKE.Подсчет результатов: Количество товаров определяется отдельным запросом:
$sql_item_count = "SELECT COUNT(DISTINCT p.msitem_id) FROM $db_mstore AS p $join_condition LEFT JOIN $db_users AS u ON u.user_id = p.msitem_ownerid $where_sql"; $totallines = $db->query($sql_item_count, $params)->fetchColumn();Сообщение о результатах: После выполнения запроса формируется сообщение:
if (!empty($sq)) { $countResults = count($sqllist_rowset); if ($countResults > 0) { $searchMsg = cot_declension($countResults, ['позиция', 'позиции', 'позиций']) . ' найдено по запросу: <strong>' . htmlspecialchars($sq) . '</strong>'; } else { $searchMsg = 'По запросу <strong>' . htmlspecialchars($sq) . '</strong> ничего не найдено'; } } else { $searchMsg = ''; } $t->assign('MSTORE_SEARCH_RESULT_MSG', $searchMsg);Сообщение отображается в шаблоне через тег
MSTORE_SEARCH_RESULT_MSG.Форма поиска: Форма генерируется в шаблоне с тегами:
$t->assign([ "MSTORE_SEARCH_ACTION_URL" => cot_url('mstore', '', '', true), "MSTORE_SEARCH_SQ" => cot_inputbox('text', 'sq', !empty($sq) ? htmlspecialchars($sq) : '', 'class="schstring form-control" autofocus'), "MSTORE_SEARCH_CAT_SELECT2" => cot_mstore_selectcat_select2($c, 'c') ]);-
MSTORE_SEARCH_ACTION_URL: URL формы указывает на текущий список товаров. -MSTORE_SEARCH_SQ: Текстовое поле с классамиschstring form-controlиautofocus. Значение экранируется черезhtmlspecialchars($sq). -MSTORE_SEARCH_CAT_SELECT2: Выпадающий список категорий с Select2, с учетом прав, черного списка и текущей категории.- Пагинация: Поиск работает с пагинацией (параметр
d, лимит из конфигурации категории или по умолчанию 10). Пагинация формируется черезcot_pagenavи учитывает$totallines. Сохранение контекста: Параметры поиска (
sq,c,s,w) сохраняются в URL через$list_url_path:if (!empty($sq)) { $list_url_path['sq'] = $sq; }Категория сохраняется в сессии:
$_SESSION['cat'] = $c;.- Кэширование: Для неавторизованных пользователей результаты кэшируются, если включен
cache_mstoreи пользователь не авторизован (Cot::$usr['id'] === 0). - Шаблон: Поиск интегрирован в шаблон
mstore.list.tpl(или кастомныйmstore.list.[tpl]). Теги формы и результата используются для вывода интерфейса.
Визуализация процесса поиска
Ниже представлена схема этапов обработки поискового запроса, выполненная с использованием символов _, | и -.
____________________________
| 1. Пользователь вводит |
| запрос в поле (sq) |
|__________________________|
|
|
V
____________________________
| 2. Запрос отправляется |
| через GET-параметр sq |
|__________________________|
|
|
V
____________________________
| 3. Проверка прав доступа |
| (cot_auth, state) |
|__________________________|
|
|
V
____________________________
| 4. Формирование SQL с |
| LIKE (:sq в title/text)|
|__________________________|
|
|
V
____________________________
| 5. Выполнение SQL-запроса|
| и подсчет результатов |
|__________________________|
|
|
V
____________________________
| 6. Отображение результатов|
| в шаблоне (список, |
| сообщение, пагинация) |
|__________________________|