Страница карточки товаров MultiStore: Техническое описание
Страница карточки товаров в модуле MultiStore (файл mstore.main.php, Cotonti Siena 0.9.26, PHP 8.4) отображает информацию о конкретном товаре. Доступна пользователям с правом чтения в категории товара, проверяется через cot_auth('mstore', 'any') и cot_block(Cot::$usr['auth_read']). Используется шаблон mstore.[cat_tpl].tpl или mstore.tpl с XTemplate. Ниже описан функционал, данные, теги и процесс обработки с технической точки зрения.
Обработка и доступ
- Импорт параметров:
id: ID товара (INT, из GET).al: Алиас товара (TXT, из GET, экранируется черезCot::$db->prep).c: Код категории (TXT, из GET).pg: Номер вкладки для мульти-табов (INT, из GET).
- Запрос данных:
- SQL:
SELECT p.*, u.* FROM cot_mstore AS p LEFT JOIN cot_users AS u ON u.user_id=p.msitem_ownerid WHERE (p.msitem_alias='[al]' OR p.msitem_id=[id]) AND p.msitem_cat='[c]' LIMIT 1. - Если
idилиalне указаны или товар не найден — ошибка 404 (cot_die_message(404)).
- SQL:
- Проверка прав:
- Проверка чтения в категории товара:
cot_auth('mstore', $item['msitem_cat'], 'R'). - Если товар в состоянии
STATE_PENDING(1) илиSTATE_DRAFT(2) и пользователь не админ (Cot::$usr['isadmin']) и не владелец (Cot::$usr['id'] != $item['msitem_ownerid']) — ошибка 403 с логом (cot_log("Attempt to directly access...", 'sec', 'mstore', 'error')).
- Проверка чтения в категории товара:
Данные и поля карточки
Данные товара берутся из таблицы cot_mstore и cot_users для владельца:
msitem_id: ID товара (int).msitem_alias: Алиас для URL (varchar(255)).msitem_state: Состояние (0=опубликован, 1=на рассмотрении, 2=черновик).msitem_cat: Код категории (varchar(255)).msitem_title: Заголовок (varchar(255)).msitem_desc: Краткое описание (varchar(255)).msitem_metatitle: Мета-заголовок (varchar(255)).msitem_metadesc: Мета-описание (varchar(255)).msitem_text: Полный текст (mediumtext).msitem_costdflt: Цена по умолчанию (decimal(10,2)).msitem_parser: Парсер текста (varchar(64)).msitem_ownerid: ID владельца (int).msitem_date: Дата создания (timestamp, int).msitem_updated: Дата обновления (timestamp, int).msitem_count: Счетчик просмотров (mediumint).- Экстрафилды: Поля с префиксом
msitem_[имя], например,msitem_photo. user_name: Имя владельца изcot_users.
Функции формирования тегов
1. cot_generate_usertags
Генерирует теги пользователя (из модуля users, подключён через cot_incfile('users', 'module')).
- Вызов:
cot_generate_usertags($item, 'MSTORE_OWNER_'), где$itemсодержит данные владельца из JOIN. - Теги:
MSTORE_OWNER_ID: ID владельца (user_id).MSTORE_OWNER_NAME: Имя (user_name).MSTORE_OWNER_FNAME,MSTORE_OWNER_LNAME: Имя и фамилия (user_firstname,user_lastname).MSTORE_OWNER_EMAIL: Email (user_email, скрыт, еслиCot::$cfg['useremailduplicate']).MSTORE_OWNER_COUNTRY,MSTORE_OWNER_REGION,MSTORE_OWNER_CITY: Локация (user_country,user_region,user_city).MSTORE_OWNER_PROFILEURL: URL профиля (cot_url('users', 'm=details&id=' . $item['user_id'])).- Экстрафилды: Например,
MSTORE_OWNER_PHONEизCot::$extrafields[Cot::$db->users].
2. cot_generate_mstoretags
Генерирует теги товара (из mstore.functions.php).
- Вызов:
cot_generate_mstoretags($item, 'MSTORE_', 0, Cot::$usr['isadmin'], Cot::$cfg['homebreadcrumb'], '', $item['msitem_pageurl']). - Обработка:
- Если
$item_data— ID, загружает данные изcot_mstoreпоmsitem_id. - Проверка прав:
cot_auth('mstore', $item_data['msitem_cat'], 'RWA1'), кэшируется в$mstore_auth. - Парсинг текста:
cot_parse($item_data['msitem_text'], $cfg['mstore']['mstoremarkup'], $item_data['msitem_parser']). - Обрезка текста:
cot_cut_more_mstoreиcot_string_truncate(если$textLength > 0). - Хуки:
mstoretags.firstиmstoretags.main.
- Если
- Теги:
MSTORE_URL: URL товара (cot_mstore_url($item_data), например,mstore?c=[cat]&id=[id]илиmstore?c=[cat]&al=[alias]).MSTORE_ID: ID товара (msitem_id, int).MSTORE_TITLE: Заголовок (htmlspecialchars($item_data['msitem_title'], ENT_COMPAT, 'UTF-8')).MSTORE_BREADCRUMBS: Хлебные крошки с категорией и товаром (cot_breadcrumbs(array_merge($pagepath, [[$item_data['msitem_pageurl'], $item_data['msitem_title']]]), $pagepath_home)).MSTORE_BREADCRUMBS_ITEM: Хлебные крошки с главной страницей, модулем, категорией и товаром (cot_breadcrumbs([...], $pagepath_home, false)).MSTORE_ALIAS: Алиас (msitem_alias, varchar).MSTORE_STATE: Код состояния (0=опубликован, 1=на рассмотрении, 2=черновик).MSTORE_STATUS: Статус в виде строки (cot_mstore_status, например, 'published', 'pending', 'draft').MSTORE_LOCAL_STATUS: Локализованный статус (Cot::$L['mstore_status_published'], например, «Опубликован»).MSTORE_CAT: Код категории (msitem_cat, varchar).MSTORE_CAT_URL: URL категории (cot_url('mstore', ['c' => $item_data['msitem_cat']])).MSTORE_CAT_TITLE: Название категории (htmlspecialchars($structure['mstore'][$item_data['msitem_cat']]['title'])).MSTORE_CAT_PATH: Хлебные крошки категории (cot_breadcrumbs(cot_structure_buildpath('mstore', $item_data['msitem_cat']), $pagepath_home, false)).MSTORE_CAT_PATH_SHORT: Ссылка на категорию (cot_rc_link($cat_url, $catTitle)).MSTORE_CAT_DESCRIPTION: Описание категории ($structure['mstore'][$item_data['msitem_cat']]['desc']).MSTORE_CAT_ICON: Иконка категории (cot_rc('img_structure_cat', ['icon' => $structure['mstore'][$item_data['msitem_cat']]['icon'], 'title' => $catTitle, 'desc' => htmlspecialchars($catDescription)])).MSTORE_CAT_ICON_SRC: Путь к иконке категории ($structure['mstore'][$item_data['msitem_cat']]['icon']).MSTORE_DESCRIPTION: Краткое описание (htmlspecialchars($item_data['msitem_desc'])).MSTORE_TEXT: Полный текст после парсинга (cot_parse($item_data['msitem_text'], $cfg['mstore']['mstoremarkup'], $item_data['msitem_parser'])).MSTORE_TEXT_SHORT: Короткий текст без тегов, обрезан до 250 символов (cot_cutstring(strip_tags($item_data['msitem_text']), 250)).MSTORE_TEXT_CUT: Обрезанный текст (cot_cut_more_mstore($text), сcot_string_truncateесли$textLength > 0).MSTORE_TEXT_IS_CUT: Флаг обрезки текста (true, еслиmb_strlen($text) > mb_strlen($text_cut)).MSTORE_DESCRIPTION_OR_TEXT: Описание или полный текст ($item_data['msitem_desc'] ?: $text).MSTORE_DESCRIPTION_OR_TEXT_CUT: Описание или обрезанный текст ($item_data['msitem_desc'] ?: $text_cut).MSTORE_MORE: Ссылка «Подробнее» для обрезанного текста (cot_rc('list_more', ['page_url' => $item_data['msitem_pageurl']])).MSTORE_AUTHOR: Автор (htmlspecialchars($item_data['msitem_author']), если не пусто).MSTORE_OWNER_ID: ID владельца (msitem_ownerid).MSTORE_OWNER_NAME: Имя владельца (htmlspecialchars($item_data['user_name']), из JOIN).MSTORE_COSTDFLT: Цена, форматированная с 2 или 0 знаками после запятой (number_format($item_data['msitem_costdflt'], 2 or 0, '.', ' ')).MSTORE_CREATED: Дата создания в форматеdatetime_medium(cot_date($date_format, $item_data['msitem_date'])).MSTORE_UPDATED: Дата обновления в форматеdatetime_medium(cot_date($date_format, $item_data['msitem_updated'])).MSTORE_CREATED_STAMP: Timestamp создания (msitem_date).MSTORE_UPDATED_STAMP: Timestamp обновления (msitem_updated).MSTORE_HITS: Количество просмотров (msitem_count).MSTORE_ADMIN: Блок админ-ссылок, если$admin_rights(cot_rc('list_row_admin', ['unvalidate_url' => $unvalidate_url, 'edit_url' => $edit_url])).MSTORE_ADMIN_EDIT: Ссылка «Редактировать» (cot_rc_link($edit_url, Cot::$L['Edit']), для админов или владельца).MSTORE_ADMIN_EDIT_URL: URL редактирования (cot_url('mstore', "m=edit&id={$item_data['msitem_id']}")).MSTORE_ADMIN_UNVALIDATE: Ссылка «Утвердить» или «В очередь» в зависимости отmsitem_state(cot_rc_link($validate_confirm_url or $unvalidate_confirm_url, Cot::$L['Validate'] or Cot::$L['Putinvalidationqueue'], 'class="confirmLink"')).MSTORE_ADMIN_UNVALIDATE_URL: URL валидации/отмены (cot_confirm_url($validate_url or $unvalidate_url, 'mstore', 'mstore_confirm_validate or mstore_confirm_unvalidate')).MSTORE_ADMIN_DELETE: Ссылка «Удалить» (cot_rc_link($delete_confirm_url, Cot::$L['Delete'], 'class="confirmLink"'), для админов).MSTORE_ADMIN_DELETE_URL: URL удаления (cot_confirm_url($delete_url, 'mstore', 'mstore_confirm_delete')).MSTORE_ADMIN_CLONE: Ссылка «Клонировать» (cot_rc_link($clone_url, Cot::$L['mstore_clone']), если есть права на запись в 'mstore').MSTORE_ADMIN_CLONE_URL: URL клонирования (cot_url('mstore', "m=add&c={$item_data['msitem_cat']}&clone={$item_data['msitem_id']}")).MSTORE_[UPPER_FIELD]: Экстрафилд товара (cot_build_extrafields_data('mstore', $exfld, $item_data['msitem_' . $exfld['field_name']], $item_data['msitem_parser'])).MSTORE_[UPPER_FIELD]_TITLE: Название экстрафилда (cot_extrafield_title($exfld, 'mstore_')).MSTORE_[UPPER_FIELD]_VALUE: Значение экстрафилда без парсинга ($item_data['msitem_' . $exfld['field_name']]).MSTORE_CAT_[UPPER_FIELD]: Экстрафилд категории (cot_build_extrafields_data('structure', $exfld, $structure['mstore'][$item_data['msitem_cat']][$exfld['field_name']])).MSTORE_CAT_[UPPER_FIELD]_TITLE: Название экстрафилда категории (cot_extrafield_title($exfld, 'structure_')).MSTORE_CAT_[UPPER_FIELD]_VALUE: Значение экстрафилда категории ($structure['mstore'][$item_data['msitem_cat']][$exfld['field_name']]).
Функционал карточки товаров
- SEO и мета-данные:
- Заголовок страницы:
- Для категории 'system':
Cot::$out['subtitle'] = $item['msitem_metatitle'] ?: $item['msitem_title']. - Иначе:
cot_title(Cot::$cfg['mstore']['mstoretitle_page'], ['TITLE' => $item['msitem_metatitle'] ?: $item['msitem_title'], 'CATEGORY' => $cat['title']]).
- Для категории 'system':
- Мета-описание:
Cot::$out['desc'] = strip_tags($item['msitem_metadesc'] ?: $item['msitem_desc']). - Ключевые слова:
Cot::$out['keywords'] = strip_tags($item['msitem_keywords'])(если не пусто). - Канонический URL:
Cot::$out['canonical_uri'] = cot_url('mstore', ['c' => $item['msitem_cat'], 'id' => $id or 'al' => $al, 'pg' => $pg]). - Последнее изменение:
Cot::$env['last_modified'] = $item['msitem_updated'](timestamp). - Noindex: Отключен (
Cot::$sys['noindex'] = false,Cot::$R['code_noindex'] = '').
- Заголовок страницы:
- Счетчик просмотров:
- Увеличивается (
msitem_count++), если пользователь не админ илиCot::$cfg['mstore']['mstorecount_admin']включено. - Без кэша: Обновление в БД через
Cot::$db->update(cot_mstore, ['msitem_count'], 'msitem_id=?'). - С кэшем (для гостей,
Cot::$usr['id'] === 0,Cot::$cfg['cache_mstore']): Асинхронный запрос черезResources::embedFooter(fetch(...))наmstore?e=mstore&m=counter&a=views&id=[id].
- Увеличивается (
- Мульти-табы:
- Текст (
msitem_text) делится на вкладки по тегу[newpage](explode('[newpage]', $t->vars['MSTORE_TEXT'], 99)). - Обработка вкладок:
- Удаление пустой первой вкладки, если есть.
- Проверка заголовков вкладок через
[title]...[/title], иначеmsitem_titleдля первой,Mstore Nдля остальных. - Очистка текста от
[newpage]и лишних<br />.
- Теги:
MSTORE_MULTI_TABNAV: Пагинация вкладок черезcot_pagenav('mstore', 'id=[id] or al=[al]', $item['msitem_tab'], $item['msitem_totaltabs'], 1, 'pg').MSTORE_MULTI_TABTITLES: Ссылки на вкладки (cot_rc_linkс классомmstore_tabtitle).MSTORE_MULTI_CURTAB: Текущая вкладка (msitem_tab + 1).MSTORE_MULTI_MAXTAB: Количество вкладок (msitem_totaltabs).MSTORE_TEXT: Текст текущей вкладки (msitem_tabs[$msitem_tab]).
- Парсинг: Если
msitem_parserуказан, текст обрабатывается черезcot_parse(BBCode, HTML и т.д., см.Cot::$cfg['mstore']['mstoreparser']).
- Текст (
- Админ-блок:
- Парсинг блока
MAIN.MSTORE_ADMIN, если пользователь — админ (Cot::$usr['isadmin']) или владелец (Cot::$usr['id'] == $item['msitem_ownerid']). - Теги:
MSTORE_ADMIN_EDIT,MSTORE_ADMIN_DELETE,MSTORE_ADMIN_UNVALIDATE,MSTORE_ADMIN_CLONE.
- Парсинг блока
- Кэширование:
- Статический кэш включается, если: гость (
Cot::$usr['id'] === 0), включеноCot::$cfg['cache_mstore'], нет сообщений (cot_check_messages()), категория не в чёрном списке (Cot::$cfg['cache_mstore_blacklist']). - Запись кэша:
Cot::$cache->static->write()в конце.
- Статический кэш включается, если: гость (
- Сообщения: Ошибки/уведомления отображаются через
cot_display_messages($t).
Шаблон и отображение
- Шаблон:
cot_tplfile(['mstore', $cat['tpl']]), где$cat['tpl']— шаблон категории изCot::$structure['mstore'], илиmstore.tpl. - Основные теги:
MSTORE_TITLE,MSTORE_DESC,MSTORE_TEXT: Основные данные товара.MSTORE_COSTDFLT: Цена с валютой (Cot::$cfg['mstore']['mstore_currency'], например, "RUB").MSTORE_OWNER_NAME: Имя владельца.MSTORE_MULTI_*: Теги для мульти-табов (еслиmsitem_totaltabs > 1).
- Хуки:
mstore.first: Перед загрузкой данных.mstore.main: Перед рендерингом шаблона.mstore.tags: После формирования тегов.
Визуализация процесса обработки карточки
Схема этапов загрузки и отображения:
____________________________
| 1. Импорт параметров |
| (id, al, c, pg) |
|__________________________|
|
|
V
____________________________
| 2. Загрузка данных |
| (SQL: cot_mstore) |
|__________________________|
|
|
V
____________________________
| 3. Проверка прав |
| (cot_auth, state) |
|__________________________|
|
|
V
____________________________
| 4. Счетчик просмотров |
| (msitem_count++) |
|__________________________|
|
|
V
____________________________
| 5. SEO и мульти-табы |
| (subtitle, tabs) |
|__________________________|
|
|
V
____________________________
| 6. Генерация тегов |
| (mstoretags, usertags)|
|__________________________|
|
|
V
____________________________
| 7. Рендеринг шаблона |
| (mstore.[cat].tpl) |
|__________________________|