История версий

Здесь мы публикуем информацию о всех обновлениях и изменениях на сайте MarketSkidok.ru.

Версия 2.8.5

Текущая 06 февраля 2026

Главная страница

  • Переделана главная страница: структура блоков, первый экран, CTA и FAQ
  • Кнопка «Оставить заявку» выведена как ключевой CTA
  • Документация: documentations/HOMEPAGE_IMPLEMENTATION.md

Страница товара

  • Доработана страница товара в компании/городе (UX и контентные блоки)
  • Блок «История цен»: данные и ECharts загружаются лениво при прокрутке к блоку (ускорение первой загрузки)
  • Добавлена кнопка «Оставить заявку на товар» (модалка + отправка через AJAX)

Каталог в городе: поиск и фильтры

  • Скорректирован поиск на странице каталога в городе
  • Улучшена работа фильтров на странице каталога в городе (корректность и UX)
  • Документация: documentations/FILTERS_IMPLEMENTATION.md, documentations/SEARCH_IMPLEMENTATION.md

Кнопка «Оставить заявку» и настройки почты

  • На странице компании добавлена кнопка «Оставить заявку» с модальным окном и отправкой через AJAX
  • Заявки доступны гостям (в kalinin_requests допускается user_id = NULL)
  • Добавлены настройки почты в админке: плитка и страница /admin/settings/email.php (SMTP для сообщений и заявок)
  • Документация: documentations/REQUESTS_COMPANY_FORM_UPDATES_2026_01_29.md

AJAX endpoints

  • /ajax/ajax_company_request.php — отправка заявок с сайта (компания/товар), валидация, сохранение, отправка писем
  • /ajax/ajax_price_history.php — данные истории цен для графика (ленивая загрузка)

Версия 2.8.4

Вышла 25 января 2026

Блок "Заявки и тендеры" на странице города

  • Добавлен блок "Заявки и тендеры" на странице города (/{город}/) над блоком компаний
  • Выводятся только актуальные заявки (статусы: new, open) из таблицы kalinin_requests
  • Отображение информации о заявке:
    • Заголовок заявки: всегда выводится "Заявка #ID", если указано поле title, оно выводится справа от ID через тире серым цветом
    • Дата создания и дедлайн
    • Имя пользователя
    • Состав заказа (товары, количество, единицы измерения, комментарии)
    • Комментарий к заявке
  • Функционал для представителей компаний (company_rep):
    • Кнопка "Показать контакты" — загрузка контактных данных через AJAX
    • Кнопка "Откликнуться" — открытие модального окна с формой отклика
    • Модальное окно с полями: комментарий, стоимость, доставка (цена), тип доставки, ETA
    • Плашка "Предложено" для заявок, на которые уже откликнулся представитель компании
  • Для неавторизованных пользователей: редирект на страницу авторизации при попытке просмотра контактов или отклика
  • Счетчик актуальных заявок в правом углу заголовка блока

AJAX endpoints

  • /ajax/ajax_request_contacts.php — получение контактных данных заявки (только для company_rep)
  • /ajax/ajax_request_offer.php — отправка отклика на заявку (только для company_rep)

Изменения в админке

  • В /admin/requests/search.php текст "Откликнулись" заменён на "Предложено"

Версия 2.8.3

Вышла 24 января 2026

Админка: импорт и очередь

  • Добавлены страницы импорта и очереди с плитками в каталоге
  • Очередь импорта: статусы, статистика, фильтр для company_rep
  • Импорт: упрощенный CSV для обновления цен без создания товаров
  • Добавлен экспорт упрощенного CSV и ссылка на текущий файл
  • Полный каталог формируется по крону в /files/prices/prices_full.csv

Технические детали

  • Очередь: kalinin_import_queue + крон cron/import_company_prices.php
  • Экспорт упрощенного CSV: /admin/catalog/export_prices_simple.php
  • Полный каталог: cron/build_full_prices.php

Версия 2.8.2

Вышла 23 января 2026

Админка: каталог товаров

  • Раздел каталога перестроен: плитки входа, отдельные страницы категорий и товаров
  • Список товаров: поиск, фильтры категорий 1–3, фильтры характеристик с догрузкой значений
  • Пагинация 100/500/1000 и массовое удаление товаров с каскадом по ценам
  • Создание товара: WEBP‑изображения 1000px, опциональная цена, проверка дубликатов по названию
  • Редактирование товара: управление ценами (добавить/обновить/удалить) + история цен
  • company_rep: режим "Весь каталог", редактирование своих товаров, массовое удаление цен компании
  • Экспорт цен компании в CSV с сохранением файла на сервере
  • Админ/менеджер: экспорт CSV по выбранной компании через модальное окно

Технические детали

  • Новые страницы: /admin/catalog/products.php, /admin/catalog/product-create.php, /admin/catalog/product-edit.php
  • AJAX: ajax/ajax_product_property_values.php, ajax/ajax_check_product_name.php

Версия 2.8.1

Вышла 23 января 2026

Админка: роли, заявки и заказы

  • Админ/менеджер: новый раздел "Работа с клиентами" (плитки заявок/заказов/корзины), пункты меню "Заявки/Заказы/Корзина" скрыты
  • Админ/менеджер: удаление заявок и заказов с каскадным удалением связанных данных
  • Админ/менеджер: фильтры заявок по компаниям/пользователям/городам и фильтр заказов по городу
  • Дашборд admin/manager: плитки "Пользователи", "Блог", перегруппировка и разделитель
  • Дашборд company_rep: плитки по заявкам/заказам/доставке/статьям/новостям, обновлён текст навигации
  • Дашборд user: плитки по заявкам/ответам/заказам, обновлён текст навигации
  • Пользователи: добавлены поля фамилия/отчество/название компании/ИНН в БД и формах
  • Заявки: по умолчанию "Актуальные" для user/company_rep/delivery_rep; фильтр по городу в поиске; бейдж "Откликнулись"
  • Заявки: переработан просмотр (заголовок/статусы/даты/бюджет/срок/адрес доставки), выделены контакты/комментарий
  • Заявки/заказы: добавлены единицы измерения в составы (request_items/order_items)
  • Заказы: user может переводить "Доставлен" → "Закрыт" (в списке и карточке)
  • Заказы: для company_rep скрыты водитель/транспорт, стоимость перенесена под состав; в просмотре добавлен итог

Компании

  • Добавлен режим просмотра компании и кнопка "Посмотреть" в списке
  • Галерея изображений компании: мультизагрузка, переименование, ресайз до 1000px, WebP, удаление

Версия 2.8.0

Вышла 22 января 2026

Админка: заявки, заказы и доставка

  • Заявки:
    • Новый раздел заявок в админке с фильтрами и карточкой заявки
    • Состав заявки с товарами (каталог + свободный текст)
    • Обработка общих заявок и выбор предложения
  • Заказы:
    • Создание заказа из заявки/предложения
    • Редактируемый состав заказа и статусы
    • Связь с пользователем, компанией и ответственным представителем
  • Службы доставки:
    • Справочники компаний доставки, типов, моделей и транспорта
    • Привязка водителей и ограничение доступа по ролям

Документация

  • Добавлено описание процесса и таблиц в documentations/REQUESTS_ORDERS_DELIVERY.md

Версия 2.7.13

Вышла 20 января 2026

Каталог города: фильтры по характеристикам

  • Вывод фильтров в категории города:
    • Фильтры по характеристикам включены на странице категории в городе
    • Блок доступен в сайдбаре и в мобильной версии
  • Корректные счетчики:
    • Пагинация и бейдж «Товаров» учитывают выбранные характеристики
    • Мета-счетчики используются только если нет фильтров по характеристикам

Технические детали

  • Измененные файлы:
    • templates/pages/catalog/catalog_city_category.php — включение фильтров и корректный COUNT

Версия 2.7.12

Вышла 20 января 2026

Каталог: единый компактный листинг

  • Новый вид списка:
    • Строчный список вместо плитки (1 товар = 1 строка)
    • Компактная карточка с единой разметкой для каталога города и категории
    • Кнопка корзины: иконка на десктопе, полноразмерная на мобильных
  • Цены:
    • Добавлен вывод price_type, price_2 и price_2_type
    • При price = 0 отображается «уточнить»
    • Старая цена выводится под основной
  • Даты:
    • Вместо «Акция действует…» выводится «обновлено {дата}»
  • Блок компании:
    • Название компании — ссылка, добавлен телефон справа
    • Hover-стили для названия и телефона
    • Лого/название/телефон оформлены через классы из общего CSS

Технические детали

  • Перенос инлайн-стилей в templates/css/pages.css (классы ms-product-*)
  • Синхронизация состояния кнопок корзины для списка и AJAX
  • Обновлены шаблоны и AJAX endpoints каталогов
  • Основные файлы:
    • templates/pages/catalog/catalog_city.php
    • templates/pages/catalog/catalog_city_category.php
    • templates/pages/company/company_city.php
    • templates/pages/company/company_city_catalog.php
    • ajax/ajax_catalog_products.php
    • ajax/ajax_company_products.php
    • templates/css/pages.css
    • js/main.js

Версия 2.7.11

Вышла 21 января 2026

Оптимизация запросов каталога: ускорение в 80 раз

  • Проблема:
    • Медленная загрузка товаров на страницах каталога (/{city-slug}/catalog/) и категорий (/{city-slug}/catalog/{category-slug}/)
    • Время выполнения запроса: ~1.2 секунды для 20 товаров
    • Полное сканирование таблицы kalinin_products (ALL scan) при каждом запросе
    • Сложная логика с CTE (Common Table Expressions) и оконными функциями ROW_NUMBER()
  • Решение:
    • Использование id_city напрямую: Убрана необходимость в дополнительном запросе к kalinin_company_addresses, теперь фильтрация идет напрямую по id_city в таблице kalinin_product_prices
    • Оптимизация структуры запроса: Заменены CTE с ROW_NUMBER() на простой GROUP BY + MAX(id) для выбора последней цены товара
    • Применение STRAIGHT_JOIN: Принудительный порядок JOIN для оптимального использования индексов — начинаем с подзапроса, уже отфильтрованного по городу
    • Упрощение фильтра "актуальные": Вместо сложной логики с проверкой date_end теперь простое условие: date_start >= 30 дней назад
  • Результат:
    • Время выполнения запроса снижено с ~1.2 секунды до ~0.015 секунды (улучшение в ~80 раз)
    • Устранено полное сканирование таблицы kalinin_products — теперь используются эффективные индексы (eq_ref joins)
    • Упрощена логика запросов — код стал проще и понятнее
    • Улучшена производительность страниц каталога для пользователей
  • Технические детали:
    • Используются индексы: idx_city_product_id на kalinin_product_prices(id_city, id_product, id)
    • Запрос начинается с подзапроса latest, который уже отфильтрован по городу и выбран последний ID цены
    • Затем последовательно выполняются JOIN с использованием PRIMARY KEY на всех таблицах
    • Фильтры "актуальные" и "со скидкой" добавляются как простые условия в подзапрос
  • Затронутые файлы:
    • templates/pages/catalog/catalog_city.php — каталог товаров в городе
    • templates/pages/catalog/catalog_city_category.php — категория каталога в городе

Версия 2.7.10

Вышла 21 января 2026

Исправление фильтров по характеристикам товаров

  • Проблема:
    • На странице каталога компании в городе (например, /moskva/company/a-grupp/catalog/) количество товаров в фильтрах не совпадало с количеством товаров на странице
    • В фильтрах показывалось больше товаров, чем реально отображалось при применении фильтра
  • Причина:
    • При подсчете количества товаров в фильтрах не учитывался id_city в таблице kalinin_product_prices
    • Функция ms_get_product_ids_for_filters() при фильтрации по company_id не добавляла условие по pr.id_city
    • На странице товары фильтровались и по id_company, и по id_city, а в фильтрах — только по id_company
  • Решение:
    • Добавлен city_id в контекст фильтров при вызове ms_load_property_filters_data() в company_city_catalog.php
    • В функции ms_get_product_ids_for_filters() добавлено условие по id_city при фильтрации по компании
    • Обновлена передача city_id в AJAX запросах (ajax_filter_values.php, ajax_filter_names.php)
    • Обновлена передача city_id в шаблоне фильтров (product_filters.php)
  • Результат:
    • Количество товаров в фильтрах теперь точно соответствует количеству товаров на странице
    • Оба запроса (подсчет в фильтрах и отображение товаров) учитывают и id_company, и id_city
    • Исправлена проблема несоответствия количества товаров при применении фильтров
  • Затронутые файлы:
    • templates/pages/company/company_city_catalog.php — добавлен city_id в контекст фильтров
    • include/product_filters.php — добавлено условие по id_city
    • ajax/ajax_filter_values.php — передача city_id в контекст
    • ajax/ajax_filter_names.php — передача city_id в контекст
    • templates/partials/product_filters.php — передача city_id в AJAX параметрах

Версия 2.7.9

Вышла 21 января 2026

Синхронизация 23met: стабильность и ускорение цен

  • Маппинги и товары:
    • Корректное сопоставление городов и компаний при синхронизации цен
    • Добавлено поле shortname для товаров (запись из name)
  • Цены:
    • Текущие цены берутся из истории, а не из таблицы парсера
    • Инкрементальная логика по parser_id для ускорения
    • Обработка свежих цен потоком без загрузки всех записей в память
    • Поля unit_price, unit_price_type, old_price не заполняются
  • Надежность:
    • Переподключение к БД при разрывах соединения
    • Батч-обновления и логирование прогресса

Версия 2.7.8

Вышла 14 января 2026

Рефакторинг кода: вынос JavaScript и CSS в отдельные файлы

  • Вынос JavaScript в отдельный файл:
    • Весь JavaScript код (около 350 строк) вынесен из templates/footer.php в отдельный файл js/main.js
    • Код включает функции для работы с cookies, управления городом, переключения темы, рейтинга, галереи фото и корзины
    • В footer.php оставлена только строка подключения: <script src="/js/main.js"></script>
    • Улучшена организация кода, читаемость и возможность кэширования браузером
  • Вынос CSS стилей футера в дизайн-систему:
    • Все стили футера (около 65 строк) перенесены из inline блока в templates/css/design-system.css
    • Стили добавлены в раздел "ФУТЕР" в конце файла дизайн-системы
    • Блок <style> полностью удален из footer.php
    • Централизация всех стилей компонентов в одном месте для лучшей организации
  • Преимущества рефакторинга:
    • Кэширование: JavaScript и CSS файлы кэшируются браузером отдельно, уменьшая размер HTML
    • Организация: Код в отдельных файлах, проще поддерживать и редактировать
    • Производительность: При повторных визитах файлы загружаются из кэша браузера
    • Читаемость: footer.php стал значительно короче и понятнее
    • Консистентность: Стили используют переменные дизайн-системы и находятся в правильном месте
  • Обратная совместимость:
    • Функциональность не изменилась, все функции работают идентично предыдущей версии
    • Полностью сохранена обратная совместимость, никаких изменений в API или поведении

Версия 2.7.7

Вышла 06 февраля 2026

Управление согласием на cookies: рефакторинг и исправления

  • Исправление загрузки счетчиков:
    • Исправлена критическая проблема с загрузкой скриптов счетчиков (Яндекс.Метрика, Google Analytics)
    • Проблема: использование insertAdjacentHTML() не выполняло скрипты, код вставлялся как текст
    • Решение: реализована функция injectHTML(), которая создает DOM элементы для скриптов через createElement('script')
    • Теперь скрипты счетчиков корректно выполняются после загрузки
  • Рефакторинг кода:
    • Код cookie consent вынесен в отдельные файлы для улучшения организации
    • Создан partial файл templates/partials/cookie_consent.php с PHP логикой и HTML разметкой
    • Создан JavaScript файл js/cookie-consent.js со всей логикой управления согласием
    • Файл templates/footer.php стал значительно короче и понятнее
    • Улучшена читаемость, поддерживаемость и возможность кэширования JavaScript
  • Улучшения логики работы:
    • Добавлена проверка согласия перед загрузкой счетчиков в режиме delayed
    • Если пользователь отключил аналитику, код не загружается даже при запущенном таймере
    • Улучшено логирование в консоль для диагностики проблем
    • Конфигурация передается из PHP в JavaScript через window.msCookieConsentConfig
  • Архитектура кода:
    • Четкое разделение ответственности: PHP, HTML и JavaScript в отдельных файлах
    • Переиспользование: partial можно подключить в других местах при необходимости
    • Кэширование: JavaScript файл кэшируется браузером отдельно
    • Тестируемость: JavaScript код можно тестировать независимо

Корзина отслеживания: доработка дизайна

  • Улучшения интерфейса:
    • Доработан дизайн страницы корзины (/cart/)
    • Улучшена адаптивность для мобильных устройств
    • Оптимизировано отображение элементов на разных размерах экранов

Технические детали

  • Измененные файлы:
    • templates/partials/cookie_consent.php — новый файл с PHP логикой и HTML разметкой
    • js/cookie-consent.js — новый файл с JavaScript кодом управления согласием
    • templates/footer.php — упрощен, теперь только подключает partial
    • templates/pages/cart/cart.php — доработка дизайна
  • Технологии:
    • DOM API для корректной вставки и выполнения скриптов
    • Модульная архитектура с разделением PHP, HTML и JavaScript
    • JSON для передачи конфигурации из PHP в JavaScript

Версия 2.7.6

Вышла 15 января 2026

Корзина отслеживания: переработка дизайна и адаптивность

  • Новый дизайн листинга:
    • Переработан дизайн страницы корзины (/cart/) под дизайн из админки
    • Табличный вид на десктопе с использованием CSS Grid
    • Адаптивная блочная верстка для мобильных устройств
    • Улучшенная визуальная структура с четким разделением колонок
  • Структура отображения:
    • Колонки: Товар, Цены, Статус и даты, Действия
    • Удален столбец "Добавлено" для упрощения интерфейса
    • Отображение информации о компании (логотип, телефон, сайт)
    • Показ статуса актуальности цены и дат действия
    • Бейджи "Лучшая цена" для товаров с минимальной стоимостью
  • Альтернативные предложения:
    • Возможность просмотра альтернативных предложений по товару
    • Развертывание/сворачивание списка альтернативных цен
    • Отображение информации о компаниях с альтернативными ценами
    • Сравнение цен с текущим предложением
  • Адаптивность:
    • На десктопе (≥992px): табличный вид с фиксированными колонками
    • На мобильных (<992px): вертикальное расположение блоков с подписями полей
    • Автоматическое скрытие заголовков таблицы на мобильных устройствах
    • Оптимизированное отображение кнопок и элементов управления
  • Улучшения интерфейса:
    • Кнопки действий содержат только иконки (без текста) для компактности
    • Исправлена проблема с видимостью кнопок на десктопе
    • Улучшена обработка overflow для корректного отображения всех элементов
    • Добавлена горизонтальная прокрутка при необходимости

Технические детали

  • Измененные файлы:
    • templates/pages/cart/cart.php — полная переработка верстки (табличная → блочная с Grid)
    • ajax/ajax_cart.php — добавлены дополнительные поля (company_slug, company_logo, company_phone, company_site) для альтернативных предложений
  • Технологии:
    • CSS Grid для табличного вида на десктопе
    • Media queries для адаптивности
    • JavaScript для динамического рендеринга и управления состоянием

Версия 2.7.5

Вышла 14 января 2026

Страница акции: улучшение интерфейса и навигации

  • Хлебные крошки:
    • Добавлены хлебные крошки на странице акции (/{city-slug}/company/{company-slug}/action/{id}/)
    • Навигация: Город → Компании → Компания → Акция
    • Все элементы хлебных крошек кликабельны (кроме текущей страницы)
    • Стилизация соответствует дизайну хлебных крошек на странице товара
  • Плашка с количеством дней до завершения акции:
    • Добавлена плашка "Акция действует еще X день/дня/дней"
    • Отображается справа от дат действия акции
    • Показывается только для активных (не истекших) акций
    • Корректное склонение слова "день" в зависимости от числа
  • Формат даты:
    • Изменен формат отображения дат с "12.01.2026" на "12 января 2026"
    • Применено как для основной акции, так и для списка других акций компании
    • Используется функция ms_format_date_ru_full() для единообразного форматирования

Админка блога: доработки редактирования статей

  • Загрузка изображений:
    • Добавлена возможность переименования картинок при загрузке
    • Улучшен процесс обработки изображений в редакторе статей
  • Удаление статей:
    • Добавлена возможность удаления статьи из страницы редактирования
    • Исправлены баги при удалении статей из листинга
    • Улучшена обработка ошибок при удалении

SEO-настройки: доработка инструмента

  • Доработаны пункты в инструменте /admin/settings/seo.php
  • Улучшена функциональность управления SEO-шаблонами

Технические детали

  • Измененные файлы:
    • templates/pages/action/action_company_city_single.php — страница акции (хлебные крошки, плашка с днями, формат даты)
    • admin/blog/edit.php — страница редактирования статьи (переименование картинок, удаление)
    • admin/blog/create.php — страница создания статьи (переименование картинок)
    • admin/settings/seo.php — инструмент SEO-настроек (доработки)

Версия 2.7.4

Вышла 13 января 2026

Фильтры по характеристикам товаров

  • Реализована система фильтрации товаров по характеристикам:
    • Добавлены фильтры на странице каталога компании (/{city-slug}/company/{company-slug}/catalog/)
    • Добавлены фильтры на странице "категория в городе" (/{city-slug}/catalog/{category-slug}/)
    • Фильтры отображаются в боковом сайдбаре под меню категорий
    • Показываются только характеристики с флагом filter = 1 из таблицы kalinin_product_property
    • Каждая характеристика может быть развернута/свернута (Bootstrap Collapse)
  • Функциональность фильтров:
    • Асинхронная загрузка значений фильтров через AJAX после загрузки страницы
    • Ленивая загрузка названий характеристик — при первой загрузке загружаются только первые 15, остальные подгружаются асинхронно
    • Поиск по значениям фильтров (клиентская фильтрация)
    • Отображение количества товаров для каждого значения фильтра
    • Можно выбрать несколько значений одной характеристики (логика OR)
    • Разные характеристики объединяются через AND
    • Работает совместно с другими фильтрами (актуальные, скидки, категории, поиск)
    • Фильтры работают в AJAX-загрузке товаров — при нажатии "показать еще" фильтры применяются корректно
  • Мобильная версия:
    • Добавлена кнопка с иконкой фильтра рядом с кнопкой категорий
    • При открытии одного меню (категории/фильтры) другое автоматически закрывается
    • Полная функциональность фильтров доступна в мобильной версии
  • Оптимизация производительности:
    • Использование id_category напрямую — запросы фильтруют по категориям без JOIN с kalinin_products
    • Оптимизация для страницы города — характеристики получаются напрямую по категориям, без предварительного получения productIds
    • Оптимизация для страницы компании — используется фильтрация по productIds компании
    • Составной индекс — добавлен индекс idx_category_property на (id_category, id_property) для ускорения запросов
    • Ограничение количества категорий — лимит до 500 категорий в IN для предотвращения слишком длинных запросов
    • Оптимизация запросов на получение товаров — использование company_ids напрямую вместо JOIN
    • Результат: время загрузки страницы улучшено в 2-4 раза (с 2+ секунд до 0.5-1 секунды)
  • Дизайн:
    • Стилизация соответствует дизайну меню каталога
    • Поле поиска закреплено под заголовком фильтра (sticky)
    • Поддержка темной темы
    • Адаптивная верстка

Технические детали

  • Новые файлы:
    • include/product_filters.php — PHP функции для работы с фильтрами
    • ajax/ajax_filter_values.php — AJAX endpoint для загрузки значений
    • ajax/ajax_filter_names.php — AJAX endpoint для загрузки дополнительных названий характеристик
    • templates/partials/product_filters.php — шаблон фильтров
  • Интеграция:
    • templates/pages/company/company_city_catalog.php — страница каталога компании
    • templates/pages/catalog/catalog_city_category.php — страница "категория в городе"
  • Миграции БД:
    • cron/migrations/20260112_add_id_category_to_product_specifics.sql — добавлено поле id_category для оптимизации запросов
    • cron/migrations/20260113_add_composite_index_category_property.sql — добавлен составной индекс idx_category_property на (id_category, id_property)
  • Формат URL: ?prop[property_id][]=value_id1&prop[property_id][]=value_id2&filters=1
  • Оптимизация: использование EXISTS подзапросов, индексов, асинхронная загрузка значений, ленивая загрузка названий
  • Подробная документация: documentations/FILTERS_IMPLEMENTATION.md

Версия 2.7.3

Вышла 10 января 2026

Выбор города: улучшение пользовательского опыта

  • Сохранение текущей страницы при подтверждении города:
    • При нажатии "Да, верно" в баннере выбора города пользователь остается на той же странице, на которой он находился
    • К текущему URL добавляется префикс города, что позволяет сохранить контекст просмотра
    • Примеры работы:
      • На странице /catalog/ → после подтверждения → /moskva/catalog/
      • На странице /blog/article/slug/ → после подтверждения → /moskva/blog/article/slug/
      • На странице /company/some-company/ → после подтверждения → /moskva/company/some-company/
    • Для глобальных страниц (/cities/, /contacts/, /about/, /changelog/) выполняется перезагрузка страницы без изменения URL
    • Служебные пути (/admin/, /ajax/ и т.д.) также перезагружаются без изменения структуры
  • Сохранение query-параметров:
    • При редиректе сохраняются все GET-параметры из текущего URL
    • Пример: /catalog/?q=поиск&page=2/moskva/catalog/?q=поиск&page=2
  • Корректная обработка структуры URL:
    • Сохраняются завершающие слеши для страниц без расширения файла
    • Обрабатываются зарезервированные сегменты (catalog, blog, company и т.д.)
    • Учитываются уже существующие города в URL (замена на новый город при необходимости)

Технические детали

  • Изменения реализованы в функции window.msConfirmCityYes() в файле templates/footer.php
  • Добавлена логика определения типа пути (служебный, глобальный, с зарезервированным сегментом)
  • Реализована корректная обработка всех сценариев навигации с сохранением контекста пользователя

Версия 2.7.2

Вышла 10 января 2026

Страница города: доработка интерфейса

  • Количество товаров со скидкой в плитках компаний:
    • Добавлен вывод количества товаров со скидкой для каждой компании в плитке
    • Данные берутся из таблицы kalinin_meta_counts с ключом count_co_catalog_sale и id_city=0
    • Бейдж отображается только если информация доступна, иначе не выводится
  • Поиск по товарам:
    • Добавлен блок поиска по товарам под заголовком страницы (как на главной)
    • Форма ведет на /{city-slug}/catalog/ с параметром q
  • Блок "Журналы акций":
    • Добавлена панель заглавия с заголовком "Журналы акций" и кнопкой "Все акции"
  • Блок "Новости {rod_p}":
    • Добавлен блок новостей города под блоком "Журналы акций"
    • Выводятся последние 6 новостей с привязкой к городу (id_city)
    • В каждой плитке: название, дата (ММ.ДД.ГГ), количество просмотров, время на чтение
    • Вывод в два столбца (упрощенный шаблон как на /blog/news/)
    • Используется поле rod_p из таблицы kalinin_city для формирования заголовка
  • Блок "Магазины":
    • Заголовок изменен с "Категории магазинов" на "Магазины"
    • Справа добавлен бейдж с количеством магазинов в городе
  • Блок "Товары со скидками":
    • Добавлен блок под блоком "Магазины" (аналогично главной странице)
    • Выводятся товары со скидкой от компаний города (топ 6)
    • Отображается название, цена, старая цена (зачеркнутая), бейдж со скидкой
  • Блок "Скидки в категориях":
    • Добавлена панель заглавия с заголовком и кнопкой "Все категории" (как на главной)
    • Настроен вывод картинок категорий из поля image таблицы kalinin_product_category
    • Если поле image не пусто, используется путь /images/upload/{название}
    • Если картинки нет или файл отсутствует — показывается заглушка /images/files/no_image.jpg
  • Блок "Блог {rod_p}":
    • Добавлен блок блога под блоком "Скидки в категориях"
    • Выводятся последние 6 статей с привязкой к городу (id_city)
    • В каждой плитке: миниатюра изображения (80x80px), название, дата, время на чтение, количество просмотров
    • Вывод в два столбца
    • Миниатюры выводятся только в блоке блога, в блоке новостей — без миниатюр
  • Блок "Отзывы о магазинах":
    • Добавлен блок отзывов под списком компаний
    • Выводятся последние 5 отзывов о компаниях в городе
    • Каждый отзыв содержит: имя автора, звездный рейтинг, название компании со ссылкой, текст отзыва, фотографии (до 6 штук), дату
    • Фильтрация по компаниям, которые имеют адреса в городе

Технические детали

  • Все изменения реализованы в файле templates/pages/city/city_single.php
  • Использован EXISTS для проверки наличия адресов компаний в городе при загрузке отзывов
  • Добавлены SQL-запросы для загрузки новостей, статей блога и отзывов с фильтрацией по id_city
  • Улучшена обработка путей к картинкам категорий с проверкой существования файлов

Версия 2.7.1

Вышла 10 января 2026

Журналы акций: поле «Описание»

  • Добавлено текстовое поле description в kalinin_actions (миграция cron/migrations/20260110_add_description_to_kalinin_actions.sql).
  • В форме создания/редактирования акции (/admin/actions/edit.php) появилось поле «Описание»; сохраняется при создании и обновлении.
  • Детальная страница акции (templates/pages/action/action_company_city_single.php) выводит блок «Описание акции» под галереей, если поле заполнено.

Версия 2.7.0

Вышла 10 января 2026

Cookies: баннер согласия и управление счетчиками

  • Новый раздел админки /admin/settings/cookies.php: текст баннера и режим загрузки счетчиков (`strict`/`delayed`).
  • На главной и внутренних страницах появилось окно согласия в правом нижнем углу с кнопками «Согласен» и «Настроить» и панелью настроек («Обязательные», «Аналитика и маркетинг»).
  • Два режима работы:
    • strict — счетчики не загружаются до согласия; после согласия подключаются с задержкой 1 c.
    • delayed — счетчики загружаются через 1 c до выбора; при отказе на следующих визитах код не выводится.
  • Согласие фиксируется в cookie ms_cookie_consent; отдельная таблица не используется. Авторизованным баннер не показывается, счетчики подключаются сразу.
  • Стили баннера и панели добавлены в templates/css/design-system.css; коды счетчиков из настроек подключаются через JS в templates/footer.php.

Версия 2.6.9

Вышла 10 января 2026

Блог: кнопка "Применить" на страницах создания и редактирования

  • Добавлена кнопка "Применить" на странице редактирования статьи (/admin/blog/edit.php):
    • При нажатии "Применить" данные сохраняются в базу, но пользователь остается на странице редактирования
    • При нажатии "Сохранить" данные сохраняются и выполняется переход на страницу листинга статей
    • После применения статьи отображается сообщение об успехе без редиректа
    • Статья перечитывается из базы для отображения актуальных данных после сохранения
  • Добавлена кнопка "Применить" на странице создания статьи (/admin/blog/create.php):
    • При нажатии "Применить" создается новая статья и выполняется переход на страницу редактирования созданной статьи
    • При нажатии "Сохранить" создается статья и выполняется переход на страницу листинга статей
    • После создания через "Применить" отображается сообщение "Статья создана" на странице редактирования
    • ID созданной статьи получается через $mysql->insert_id для корректного редиректа
  • Улучшен пользовательский опыт редактирования статей:
    • Возможность быстро применить изменения и продолжить редактирование без потери контекста
    • Удобная работа с несколькими статьями подряд при создании
    • Меньше кликов для перехода к редактированию только что созданной статьи

Единый визуальный редактор для блога: доработки

  • Рефакторинг кода редактора:
    • CSS-стили вынесены в отдельный файл /admin/blog/wysiwyg-editor.css
    • JavaScript-логика вынесена в отдельный файл /admin/blog/wysiwyg-editor.js
    • Оба файла подключаются в edit.php и create.php через <link> и <script>
    • Обеспечено единообразие редактора на страницах создания и редактирования статей
  • Форматирование HTML:
    • При переключении в HTML-режим код автоматически форматируется с переносами строк и отступами для удобного чтения
    • Используется функция formatHtml() для добавления отступов и переносов строк
    • Установлены моноширинный шрифт (Courier New) и правильные настройки для чтения кода
    • tab-size: 2 для удобных отступов
  • Нормализация HTML:
    • Функция normalizeHtml() очищает HTML от лишних пробелов и пустых тегов
    • Удаляются множественные пробелы между тегами
    • Очищаются пустые параграфы (<p></p>) и избыточные <br> теги
    • Сохраняются пробелы вокруг инлайн-тегов (strong, em, u и т.д.) через систему защиты пробелов
    • При переключении в визуальный режим HTML нормализуется для предотвращения лишних отступов
  • Сохранение пробелов вокруг инлайн-тегов:
    • Реализована функция protectInlineSpaces() для защиты пробелов вокруг тегов <strong>, <em>, <u> и т.д.
    • При переключении режимов пробелы сохраняются, предотвращая склеивание текста с форматированием
    • Используется система неразрывных пробелов (\u00A0) как временных маркеров
  • Визуальный режим:
    • При нажатии Enter всегда создаются теги <p> вместо <div>
    • Реализована трехуровневая защита от создания div'ов: MutationObserver, обработчик input, периодическая проверка
    • Используется document.execCommand('defaultParagraphSeparator', false, 'p') для установки формата по умолчанию
    • Обработчики событий beforeinput и keydown перехватывают Enter и создают параграфы явно
    • Минимальная высота визуального редактора увеличена до 500px (было 320px)
    • Высота textarea в HTML-режиме увеличена до 20 строк (было 10)
  • Панель инструментов (toolbar):
    • Все кнопки toolbar теперь работают в HTML-режиме для вставки HTML-тегов
    • Bold — вставляет <strong>текст</strong>
    • Italic — вставляет <em>текст</em>
    • Underline — вставляет <u>текст</u>
    • Списки — вставляет <ul><li>...</li></ul> или <ol><li>...</li></ol>
    • Ссылки — запрашивает URL и вставляет <a href="url">текст</a>
    • Выравнивание — вставляет <div style="text-align: left/center/right">текст</div>
    • Remove Format — удаляет HTML-теги, оставляя только текст
    • После вставки HTML автоматически форматируется для удобного чтения

Версия 2.6.8

Вышла 10 января 2026

Блог: блоки внимания в редакторе

  • Добавлена функциональность вставки специальных блоков внимания в визуальный редактор статей блога.
  • Реализовано 5 типов блоков внимания с уникальными цветами и иконками:
    • Внимание — желтый цвет, иконка восклицательного знака, для предупреждений
    • Вопрос — синий цвет, иконка вопроса, для обсуждений
    • Отмена — красный цвет, иконка крестика, для запретов
    • Подтверждение — зеленый цвет, иконка галочки, для рекомендаций
    • Информация — фиолетовый цвет, иконка информации, для советов
  • Вставка блоков через модальное окно выбора типа с демо-контентом для замены.
  • Блоки сохраняются как HTML с inline стилями и классами ms-attention-block.
  • Поддержка отображения блоков в визуальном редакторе админки и на детальной странице статьи.
  • Поддержка темной темы с адаптированными цветами для всех типов блоков.

Блог: автоматическое содержание статей

  • Реализована автоматическая генерация содержания (Table of Contents) для статей и новостей на основе заголовков h2-h6.
  • Иерархическая структура с правильными отступами: подзаголовки (h3, h4 и т.д.) отображаются как вложенные элементы.
  • Автоматическое создание уникальных ID (якорей) для всех заголовков с поддержкой кириллицы.
  • Плавная прокрутка к разделам при клике на ссылки в содержании с отступом от верха страницы.
  • Кнопка сворачивания/разворачивания содержания для удобной навигации.
  • Автоматическое скрытие блока содержания, если в статье нет заголовков.
  • Индикатор якоря (символ #) при наведении на заголовки в контенте (только на десктопе).
  • Адаптивный дизайн с упрощенным отображением на мобильных устройствах.

Блог: исправления детальной страницы

  • Исправлено отображение изображений: добавлена проверка существования файла перед использованием изображения в заголовке статьи. Если файл не найден, автоматически используется fallback /images/files/blog_noimage.jpg.
  • Восстановлено затемнение в области заглавия: исправлена структура слоев (z-index) для правильного отображения затемнения поверх фонового изображения, улучшена читаемость текста на любых фоновых изображениях.
  • Добавлены CSS fallback механизмы для надежного отображения изображений.
  • Улучшена обработка пустых значений поля image в базе данных.

Редактор блога: улучшения

  • Исправление лишних тегов: добавлена очистка пустых <p></p> и <br> тегов вокруг блоков внимания при вставке и сохранении.
  • Исправление Enter: предотвращено создание лишних тегов <p><br></p><p></p> при нажатии Enter в визуальном редакторе.
  • Улучшена функция синхронизации между визуальным и HTML режимами для корректной очистки лишних тегов.

Версия 2.6.7

Вышла 9 января 2026

Отзывы: улучшение интерфейса и привязка к пользователям

  • Миграция cron/migrations/20260109_add_user_id_to_reviews.sql — добавлено поле user_id и индекс в kalinin_reviews.
  • Привязка отзывов к пользователям: авторизованные пользователи оставляют отзывы с автоматическим одобрением (approved=1), поля имени/почты скрыты, данные берутся из профиля. Гостям доступна прежняя форма с модерацией.
  • Страница "Товар в городе": блок "Отзывы о товаре" оформлен с заголовком-панелью (средняя оценка, количество отзывов, кнопка "Оставить отзыв"), форма вынесена в модальное окно.
  • Страница "Компания в городе": блок "Отзывы о компании" приведён к единому стилю — заголовок-панель с рейтингом и кнопкой, форма в модалке.
  • Модальные окна отзывов: стили вынесены в templates/css/design-system.css, улучшены внутренние отступы и оформление.
  • Лайки/дизлайки: кнопки перенесены в правую часть блока (рядом со звёздами), убрано подчёркивание у иконок, добавлена подсветка активного состояния при голосовании.
  • Каскадное удаление ответов: При удалении отзыва из админки автоматически удаляются все связанные ответы из таблицы kalinin_review_replies. Это предотвращает появление "висячих" записей в БД.
  • Исправление массового удаления: Исправлена критическая ошибка, при которой удалялись не те отзывы, которые были выбраны пользователем. Теперь JavaScript создаёт новую форму с правильными данными, гарантируя корректную отправку выбранных ID на сервер.

Версия 2.6.6

Вышла 9 января 2026

Ответы на отзывы и лайки

  • Новая таблица kalinin_review_replies (review_id, user_id, company_id, body, likes, dislikes, timestamps).
  • Админка /admin/reviews/index.php: фильтр «Без ответа», модалка для ответа/редактирования/удаления (admin/manager — все; company_rep — только по своей компании и своему ответу). В карточке отзыва добавлен блок ответов.
  • Фронт: ответы и лайк/дизлайк у отзывов и ответов на страницах компании, адреса компании, товара в городе и товара в компании; отображаются имя, роль («Администрация MarketSkidok» или «Представитель компании …»), дата/время.
  • AJAX голосование /ajax/ajax_review_vote.php (type=review|reply, vote=like|dislike) с хранением выбора в сессии.

Версия 2.6.5

Вышла 9 января 2026

Блог

  • Формы создания/редактирования разделены на рабочую область и правую панель настроек; SEO-поля объединены в блок, добавлен выбор города id_city, отображение updated_at, автосчёт времени чтения (200 слов/мин).
  • Создание статьи получило визуальный редактор полного текста (переключатель Визуально/HTML, базовый тулбар, загрузка картинок через /admin/blog/upload_image.php); в списке статей добавлены фильтры по компании и городу, дата формата дд.мм.гггг, фолбэк обложки /images/files/no_image.jpg.

Статические страницы

  • Формы /admin/pages/create.php и /admin/pages/edit.php получили единый SEO-блок (h1/title/meta_description); на создании добавлен визуальный редактор с переключением Визуально/HTML и вставкой картинок через /admin/upload_image.php.

Адреса компаний

  • В /admin/company-addresses/create.php и /admin/company-addresses/edit.php поля сгруппированы в блоки «Адрес и контакты» (адрес, индекс, график, координаты, телефон, сайт, логотип, ID Яндекс.Карт, описание) и «Мессенджеры и соцсети» (Telegram, WhatsApp, VK, OK, Дзен, Facebook, Instagram, Twitter, YouTube, TikTok).

Версия 2.6.4

Вышла 8 января 2026

Изображения категорий каталога

  • В категории каталога добавлено поле image (таблица kalinin_product_category), хранится в /images/upload/.
  • Создание/редактирование категории позволяет загрузить картинку; имя берётся из slug, при совпадении добавляется -company_id, при втором совпадении — суффикс с датой.
  • Картинка автоматически уменьшается до 300px по большей стороне; разрешены JPG/PNG/WEBP, лимит 5 МБ.
  • Список категорий в админке показывает миниатюру; при отсутствии файла выводится /images/files/no_image.jpg.

Версия 2.6.3

Вышла 8 января 2026

Контент-план блога и публикация

  • Новый инструмент /admin/blog/content-plan.php со статусами, пагинацией, редактированием тем (h1, title, meta_description, ключи, конкуренты, промт, модель, статус, лог, плановая дата) и кнопкой публикации в блог.
  • Публикация создаёт запись в kalinin_blog c новыми полями h1/title/meta_description, slug транслитерируется и проверяется на уникальность.
  • Импорт тем из CSV на странице списка: файл, разделитель (по умолчанию «;»), пример-файл, описание структуры. При повторяющихся названиях ключи объединяются, конкуренты собираются списком.

Админка блога

  • В /admin/blog/edit.php добавлены поля h1/title/meta_description; исправлена передача slug (строковый), добавлено точечное логирование при сохранении.

Единый стиль списков в админке

  • Списки в админке приведены к единому шаблону: admin-page-header, admin-toolbar с поиском/фильтрами, admin-table-wrapper + admin-table table-hover, чекбоксы и select-all, бургер-меню действий, иконки в кнопках.
  • Обновлены страницы: блог (/admin/blog/index.php), статические страницы (/admin/pages/index.php), отзывы (/admin/reviews/index.php, массовые действия: одобрить/снять/удалить), компании (/admin/companies/index.php), акции (/admin/actions/index.php), города (/admin/cities/index.php), адреса компаний (/admin/company-addresses/index.php), пользователи (/admin/users/index.php).
  • Для компаний и адресов компаний добавлены чекбоксы и массовое удаление; для пользователей — массовое удаление только для админа с защитой от удаления себя; для адресов и отзывов добавлены выпадающие меню действий.

Версия 2.6.2

Вышла 8 января 2026

Регистрация, подтверждение email и модерация представителей

  • Страницы: регистрация пользователя /admin/register.php (роль user), регистрация поставщика/представителя /admin/register-company.php (роль company_rep, выбор компании обязателен, после подтверждения e-mail требуется одобрение администратора), повторная отправка письма /admin/resend_verification.php, подтверждение /admin/verify.php?token=....
  • Статусы пользователей: status (active, pending_email, pending_moderation, blocked) и moderation_status (not_required, pending, approved, rejected). Проверяются на входе в админку; неактивные и ожидающие модерации не пускаются.
  • Админка пользователей: редактирование показывает статусы на русском, быстрые действия (повтор письма, одобрить/отклонить представителя, активировать/блокировать). Создание ставит активный статус и подтверждённый e-mail.

Дашборд

  • Новая плашка «Представители компаний» с количеством всего и на модерации + кнопка «Управлять» → /admin/users/index.php.

Почта

  • Отправка писем подтверждения через SMTP Beget (по умолчанию smtp.beget.com:465 SSL, noreply@marketskidok.ru). Конфиг в include/auth.php через константы AUTH_SMTP_*; тема кодируется B64 UTF-8. При отключении SMTP используется mail().

Версия 2.6.1

Вышла 8 января 2026

Роутинг товаров

  • Старые пути без города (/product/{id}/, /company/{slug}/product/{id}/) теперь отдают 301-редирект на городские маршруты с выбранным городом (fallback moskva). Исправлена ошибка подключения несуществующего шаблона product_company.php.

Страница товара в компании

  • Хлебные крошки: оставлены только город → компании → компания → каталог → цепочка категорий; последний уровень категории кликабелен при наличии slug, пункт товара убран.
  • Сообщение об отсутствии актуальной цены подставляет название компании и города (родительный падеж через name_rod при наличии).
  • Актуальная цена разрешает «бессрочную» акцию: date_end = '1970-01-01' и date_start не старше 15 дней (или $dateLimit при фильтре «Актуальные»).
  • Добавлен бейдж «Скидка действует еще N дней» для акций с конечной датой; даты в текстах акций форматируются как «день месяц год» через хелпер ms_format_date_ru_full, применён к блоку «Последняя известная цена…».

Авторизация

  • Добавлено «Запомнить меня» (30 дней): cookie ms_remember + таблица kalinin_user_remember_tokens (миграция cron/migrations/20260108_create_auth_remember_tokens.sql).
  • Автовход восстанавливает сессию по токену, ротирует токен при каждом удачном автологине; выход очищает все remember-токены и cookie.
  • Форма входа админки теперь с чекбоксом «Запомнить меня»; сессия фронта/админки унифицирована (записывается $_SESSION['user']).

Документация

  • В разделе «Товары» уточнено поведение старых маршрутов: описан 301-редирект на городские версии.
  • Добавлены детали по странице товара в компании: цепочка категорий, текст об отсутствии цены с названием компании/города, правила «бессрочной» акции, формат дат и бейдж оставшихся дней акции.

Версия 2.6.0

Вышла 4 января 2026

Отслеживание цен (корзина)

  • Миграция kalinin_cart_items (user_id/session_token, price_id, product_id, company_id, is_priority, comment, soft-delete, индексы).
  • API /ajax/ajax_cart.php: add/remove/list, лимит гостя 5 позиций, merge гостевой корзины в user при логине, возвращает альтернативные предложения и лучшую цену.
  • Фронт: кнопка «Отслеживать» в листингах (каталог компании/категории, каталог города/категории, карточки компании) и на деталке товара (fallback на любую доступную цену), страница /cart/ с фильтром по компании, сортировкой, альтернативами и удалением через AJAX.
  • Админка /admin/cart/ (только свои записи): ссылка на товар с учётом выбранного города (cookie selected_city, иначе moskva), текущая цена с датами/актуальностью/скидкой, контакты компании; альтернативы раскрыты по умолчанию с кнопкой «сменить» для обновления price/company/product.
  • Крон cron/cleanup_cart_items.php чистит анонимные записи старше 30 дней.
  • auth_current_user() учитывает админские сессионные ключи (user_id/email/role/…) для корректной записи user_id в корзину при авторизации в админке.

Версия 2.5.9

Вышла 4 января 2026

Журналы акций

  • Новый раздел админки /admin/actions/index.php с фильтрами по компании/городу, миниатюрами, массовым удалением; доступен admin/manager/company_rep (новый capability actions).
  • Массовое удаление: парсерные акции удаляют только запись; админские (id_action=0) также очищают директорию /images/stocks/{id}.

Создание/редактирование акций

  • Форма /admin/actions/edit.php: создание записей с id_action=0, id_image=0, jpeg=0, images=0; поля компания/город/название/даты, служебные поля read-only.
  • Загрузка изображений только для админских акций: множественный выбор, webp, высота ≤1500px, сохранение в /images/stocks/{id}/1.webp, 2.webp…, пересоздание папки и обновление счётчика images.

Фронт акций

  • Если id_action=0, карточки и галереи акций берут изображения из /images/stocks/{id}/{n}.webp; иначе сохраняется путь /images/actions/{id_image}/{n}.jpg|jpeg.
  • Обновлены: templates/pages/actions/actions_city.php, city/city_single.php, company/company_city.php, main.php, action/action_company_city_single.php, ajax/ajax_company_actions.php.

Версия 2.5.7

Вышла 3 января 2026

Роли и доступы в админке

  • Введены роли: admin, manager, company_rep, user; проверки доступа вынесены в admin/bootstrap.php с картой прав и автоматическим запретом 403.
  • Меню админки показывает только разрешённые разделы; пункт «Пользователи» — только для админа.
  • Новый список пользователей (/admin/users/index.php) и создание (/admin/users/create.php), редактирование расширено ролями и привязкой к компании (для представителя).
  • Фильтрация данных для представителя компании: блог/компании/адреса/отзывы показывают и позволяют менять только данные своей компании; отзывы для представителя — только просмотр.

Дашборд по ролям

  • Представитель: только статистика по своей компании (товары из kalinin_product_prices, акции, отзывы, адреса), скрыты блоки cron/безопасности/сообщений/бэкапов.
  • Менеджер: скрыты блоки безопасности и бэкапов.
  • Пользователь: дашборд без плиток и системных блоков.

Технические правки

  • Для логов админки используется единый файл admin/error_log_admin.log (E_ALL).
  • Исправлен подсчёт товаров на дашборде: для компаний берём уникальные id_product из kalinin_product_prices.
  • Исправлен 404 favicon — файл /favicon.ico доступен в корне (копия из каталога /favicon/).

Миграции

  • kalinin_users: столбец company_id (FK на kalinin_company) для привязки представителя к компании.

Версия 2.5.6

Вышла 2 января 2026

Поиск

  • Поиск по каталогу города и категории: нормализация+транслит, релевантность (начало слова), подсказки (товары/категории), «часто ищут», логирование в kalinin_search_keywords, счётчик найденных товаров.
  • Поиск в каталоге компании и категории компании: поиск только по товарам компании, подсказки с company_id, чекбокс «В этой категории» только на страницах категорий, логирование id_company/category, влияние фильтров «Актуальные/Со скидкой» на поиск.
  • Поиск на главной: активная форма отправляет на /{city}/catalog/?q=....

Резервные копии

  • Добавлен инструмент бэкапов в админке: список архивов, создание с доп. исключениями, удаление, сохранение дефолтных исключений (ключ backup_excludes в kalinin_settings).
  • Новый cron cron/backup.php создаёт zip-бэкап с именем из версии /changelog и датой/временем; логируется в kalinin_cron_logs и cron/logs/backup.php.log.
  • Дефолтные исключения включают папку backups; пути вне DOCUMENT_ROOT и симлинки пропускаются, статистика пропусков пишется как skipped_outside_root/skipped_realpath_failed.
  • На странице настроек добавлена карточка «Бэкапы», на дашборде — плашка с количеством и датой последнего бэкапа, в блок статусов cron добавлен backup.php.

Меню категорий

  • Страницы компании и каталога компании: сайдбар категорий упрощён — плоский список .ms-menu, активная категория подсвечена, ссылки «Все категории» и «Назад к родителю», дочерние показываются только внутри выбранной категории.
  • Страницы каталога в городе и категории в городе: меню приведено к тому же стилю, что в каталоге компании (плоский список, активная подсветка, «Все категории», ссылка на родителя, дочерние — в категории).

Документация

  • Обновлён раздел о меню категорий в DOCUMENTATION.md под новый стиль для компании и каталога в городе.

Версия 2.5.5

Вышла 1 января 2026

Каталог в городе / категория в городе

  • Плитка товара теперь показывает логотип компании внизу карточки (под ценой и сроками акции), с fallback на название/бейдж «Компания».
  • Запрос минимальной цены выбирает конкретную запись с ценой и сразу подтягивает компанию (slug, название, логотип) — корректное связывание цены и продавца.
  • Информация о датах акции и статусах (актуально/просрочено/устарело) берётся из той же минимальной цены без дополнительных запросов.
  • Та же логика и разметка применены в AJAX «Показать ещё» для каталога.

Документация

  • В DOCUMENTATION.md добавлено описание вывода логотипов компании в карточках каталога, источники данных и fallback-сценарии.
  • Изучен и задокументирован функционал раздела «Настройки страниц» (/admin/settings/page-meta.php): фильтры по город/компания/категория, пагинация на 40 строк, создание/редактирование/удаление связок kalinin_meta, предупреждения о дубликатах и удаление ключей при очистке полей.

Версия 2.5.4

Вышла 31 декабря 2025

Кастомные мета и тексты из kalinin_meta

  • Страница компании в городе: h1/title/description и тексты берутся из kalinin_meta (id_city, id_company, id_category=0); text_mini под шапкой, text_main под блоком филиалов; карточки текстов без тени по умолчанию, тень только на hover; заголовок отзывов с базовой тенью, форма/заглушка отзывов с hover-тенью.
  • Страница каталога компании в городе: мета и тексты из kalinin_meta (id_city, id_company, id_category); text_mini под шапкой каталога, text_main под товарами.
  • Страница города: мета и тексты из kalinin_meta (id_city, id_company=0, id_category=0); text_mini над блоком «Категории магазинов», text_main под блоком «Скидки в категориях»; карточки текстов с тенью только на hover.
  • Категория каталога в городе: мета и тексты из kalinin_meta (id_city, id_company=0, id_category); text_mini под шапкой страницы перед товарами, text_main под товарами внутри основного контента; hover-тень у текстовых карточек.

Правки верстки

  • Блок основного текста на странице категории каталога в городе перенесён внутрь main (под товары/пагинацию).
  • Фикс undefined index id при загрузке категории каталога в роутере (выборка id в запросе категории).

Версия 2.5.3

Вышла 30 декабря 2025

Страница каталога в городе

  • Тумблер «Актуальные» теперь реально управляет фильтром дат:
    • При выключенном тумблере товары выводятся без ограничения по датам цен.
    • При включённом тумблере — только актуальные цены (как и раньше).
    • Режим «Со скидкой» по-прежнему показывает только актуальные скидки.

Документация

  • Обновлены разделы про фильтры каталога города в DOCUMENTATION.md и PRODUCT_UPDATE_CRONS_DOCUMENTATION.md.

Версия 2.5.2

29 декабря 2025

Страница каталога компании в городе

  • Создана отдельная страница каталога товаров компании в городе:
    • URL: /{city-slug}/company/{company-slug}/catalog/
    • Шаблон: templates/pages/company/company_city_catalog.php
    • Отображает только каталог товаров (без блоков акций, филиалов и отзывов)
    • Поддерживает выбор категории: /{city-slug}/company/{company-slug}/catalog/{category-slug}/
  • Добавлены SEO настройки для новой страницы:
    • Тип страницы: company_city_catalog
    • Доступные переменные: {company_name}, {city_name}, {city_name_pred}
    • Настройки доступны в админ-панели: /admin/settings/seo.php
    • Дефолтные шаблоны определены в include/seo_templates.php
  • Реализован роутинг для новой страницы:
    • Добавлен маршрут в include/router.php для обработки URL каталога компании
    • Маршрут для категории каталога использует тот же шаблон company_city_catalog.php
    • Правильный приоритет маршрутов: каталог обрабатывается до основной страницы компании
  • Функциональность каталога:
    • Боковое меню с категориями товаров
    • Фильтры товаров (актуальные, со скидкой) с сохранением в cookie
    • Сортировка товаров (по умолчанию, дешевле, дороже, по названию, по размеру скидки)
    • Режим "Показать ещё" для подгрузки товаров через AJAX
    • URL категорий генерируются в формате: /{city-slug}/company/{company-slug}/catalog/{category-slug}/
  • Восстановлена загрузка адресов на основной странице компании:
    • На странице /{city-slug}/company/{company-slug}/ снова отображаются филиалы (адреса)
    • Загружаются первые 10 адресов с возможностью подгрузки через AJAX
    • Кнопка "Показать все адреса" отображается, если адресов больше 10
  • Обновлена документация:
    • Дополнен DOCUMENTATION.md описанием новой страницы каталога
    • Добавлена информация о маршрутах, SEO настройках и отличиях от основной страницы компании
    • Обновлен список типов страниц для SEO (теперь 20 типов)

Версия 2.5.1

28 декабря 2025

Оптимизация страниц (компания, город, каталог)

  • Фильтр “Актуальные” на странице компании включён по умолчанию — быстрее первая загрузка; пользователь может отключить.
  • Убраны тяжёлые COUNT(DISTINCT) на каталоге (город/категория) — пагинация через “Показать ещё” по флагу hasMoreProducts.
  • Дублирующие запросы города убраны — используется MS_CITY_FROM_PATH.
  • Категории товаров строятся одним запросом по IN (без цепочек parent-запросов).
  • Цены по городу — JOIN с адресами вместо длинных IN; индексы: kalinin_company_addresses(id_city, id_company), kalinin_product_prices(id_product, id_company, date_end, date_start).
  • Убраны выборки адресов на странице компании (не выводятся); текст “Филиалов…” заменён на “Магазин в городе”.
  • Листинги товаров: убрано поле description из выборок/группировок для снижения нагрузки.

Версия 2.5.0

27 декабря 2025

Улучшения страниц товаров

  • Добавлен блок характеристик товара:
    • Отображается на страницах товара в компании и в городе
    • Характеристики берутся из таблиц: kalinin_product_property, kalinin_product_value, kalinin_product_specifics
    • Адаптивная сетка: 2 колонки на десктопе, 1 на мобильных
    • Значения характеристик выровнены по правому краю, курсив, размер шрифта 14px
    • Блок расположен после блока описания товара
  • Добавлен блок описания товара:
    • Отображается на страницах товара в компании и в городе
    • Показывается только если заполнено поле description из таблицы kalinin_products
    • Текст описания с сохранением переносов строк
    • На странице товара в компании: расположен после блока "Этот товар есть в других компаниях"
    • На странице товара в городе: расположен после блока "Цены в магазинах"
  • Добавлены плашки категорий товара в заглавии:
    • Отображаются между названием компании/города и плашкой "Товар"
    • Выводится цепочка категорий от родительской к дочерней
    • Рекурсивное построение цепочки из таблицы kalinin_product_category
    • Каждая категория - кликабельная плашка со ссылкой на каталог:
      • Для товара в компании: /{city-slug}/company/{company-slug}/catalog/{category-slug}/
      • Для товара в городе: /{city-slug}/catalog/{category-slug}/
    • Плашки имеют стиль bg-info-subtle text-info-emphasis
  • Добавлен рейтинг товара в заглавии:
    • Отображается под заголовком H1 на страницах товара
    • Звезды по 5-балльной шкале с поддержкой половинок
    • Среднее значение рейтинга справа от звезд (формат: 4.5)
    • Количество отзывов со ссылкой-якорем на блок отзывов
    • Если отзывов нет - отображается "Нет оценки"
    • Рейтинг рассчитывается из таблицы kalinin_reviews:
      • Среднее значение по полю rating для отзывов с approved = 1 и id_product = текущий товар
      • Подсчет количества отзывов
    • Блок отзывов имеет якорь id="product-reviews" для навигации
  • Обновлена структура блоков страниц товаров:
    • Страница товара в компании: История цен → Цены в других компаниях → Описание → Характеристики → Отзывы → Смотрите также
    • Страница товара в городе: Цены в магазинах → Описание → Характеристики → Похожие товары → Отзывы

Страница адреса компании

  • Реализована детальная страница адреса компании:
    • URL: /{city-slug}/company/{company-slug}/address/{id}/
    • Шаблон: templates/pages/company/address_city.php
    • Отображает информацию об адресе магазина компании
    • Интеграция с картами для отображения местоположения
    • Ссылки на страницу адреса добавлены в список адресов компании
  • Добавлены SEO настройки для страницы адреса:
    • Настройки доступны в админ-панели: admin/settings/seo.php
    • Тип страницы: address_company_city
    • Доступные переменные для шаблонов:
      • {company_name} - название компании
      • {address_name} - название адреса/филиала
      • {address} - полный адрес
      • {city_name} - название города в именительном падеже
      • {city_name_pred} - название города в предложном падеже
    • Автоматическая генерация SEO мета-тегов на основе шаблонов

Обновление документации

  • Дополнена документация (DOCUMENTATION.md) описанием всех новых функций страниц товаров
  • Добавлены технические детали работы характеристик, категорий и рейтинга
  • Описаны SQL-запросы для получения характеристик и цепочки категорий

Версия 2.4.0

26 декабря 2025

Обновление дизайна админ-панели

  • Полностью обновлен визуальный стиль админ-панели:
    • Градиентный навбар (индиго) с иконками
    • Белый сайдбар с иконками для каждого пункта меню
    • Современные карточки с тенями и скругленными углами
    • Улучшенная типографика и отступы
    • Плавные переходы и hover-эффекты
  • Создан файл admin/css/admin.css с современными стилями:
    • Использует переменные из единой системы дизайна проекта
    • Стили для навбара, сайдбара, карточек, таблиц, форм, кнопок
    • Адаптивный дизайн для мобильных устройств
  • Обновлены компоненты админ-панели:
    • Навбар с градиентом, иконками и информацией о пользователе
    • Сайдбар с иконками для каждого пункта меню и активными состояниями
    • Карточки статистики на дашборде в новом стиле
    • Таблицы с улучшенным отображением и иконками в кнопках
    • Формы с современными стилями полей ввода
  • Обновлена страница входа:
    • Градиентный фон (индиго)
    • Современная карточка с иконкой замка
    • Иконки в полях ввода (email, пароль)
    • Улучшенная форма входа

Технические улучшения

  • Подключены Bootstrap Icons для всех иконок
  • Интеграция с единой системой дизайна проекта (design-system.css)
  • Улучшена навигация и визуальная иерархия
  • Добавлены hover-эффекты и плавные анимации

Новый инструмент "Каталог компаний"

  • Добавлен инструмент управления категориями товаров по компаниям в разделе "Настройки":
    • Список компаний с привязками к категориям каталога
    • Дерево категорий компании с учетом вложенности (родительские → дочерние)
    • Табличное отображение товаров категории с ID, миниатюрой и названием
    • Панель управления категориями с тремя выпадающими списками для трех уровней вложенности
    • Динамическая загрузка дочерних категорий через AJAX
  • Функционал перекладывания товаров между категориями:
    • Массовое изменение категории товаров
    • Логика выбора категории: приоритет последнему выбранному уровню (3-й → 2-й → 1-й)
    • Валидация на клиенте и сервере
    • Подтверждение перед выполнением операции
  • Поиск и сортировка товаров:
    • Поиск товаров по названию
    • Сортировка по имени (возрастание/убывание) с кликабельным заголовком
    • Пагинация (100 товаров на страницу)
  • Созданы новые файлы:
    • admin/settings/company-catalog.php — список компаний
    • admin/settings/company-catalog-company.php — категории компании
    • admin/settings/company-catalog-products.php — товары категории
    • ajax/ajax_category_children.php — AJAX для загрузки дочерних категорий

Улучшения интерфейса

  • Названия компаний и категорий сделаны ссылками для быстрой навигации
  • Улучшена визуализация иерархии категорий с отступами
  • Добавлены информативные сообщения об успехе/ошибке операций
  • Добавлена кнопка "Найти в Яндекс" для каждого товара в списке:
    • Открывает поиск в Яндекс по названию товара в новой вкладке
    • Расположена справа от названия товара
    • Синий hover-эффект с белым текстом

Генерация категорий товаров через нейросеть

  • Добавлена автоматическая генерация категорий для товаров с использованием AI:
    • Кнопка "Сгенерировать разделы" на странице товаров категории
    • Отправка названий товаров в нейросеть через OpenRouter API
    • Получение предложенных категорий от AI и сохранение в БД
    • Отображение AI-категории в таблице товаров
    • Сортировка товаров по AI-категории
  • Настройки API в разделе "Настройки" → "Общие настройки":
    • Поле для ключа OpenRouter (тип: password)
    • Поле для модели нейросети (по умолчанию: openai/gpt-3.5-turbo)
    • Настройки сохраняются в таблице kalinin_settings
  • Настройки прокси-сервера для OpenRouter:
    • Возможность использования прокси-сервера для запросов к OpenRouter API
    • Настройки: включение/выключение, адрес, порт, тип (HTTP/SOCKS4/SOCKS5)
    • Опциональная аутентификация на прокси (логин и пароль)
    • Все запросы к OpenRouter идут через указанный прокси-сервер, если он включен
    • Увеличенные таймауты для работы через прокси (120 сек общий, 30 сек подключение)
    • Детальное логирование работы прокси (verbose вывод cURL, IP адреса, время выполнения)
    • Обработка ошибок прокси с детальными сообщениями
  • Защита от потери данных при сохранении настроек:
    • Ключ OpenRouter не перезаписывается пустым значением при сохранении других настроек
    • Пароль прокси не перезаписывается пустым значением при сохранении других настроек
    • Поля типа `password` сохраняются только если введено новое значение
    • Подсказки в интерфейсе о статусе ключа и пароля (установлен/не установлен, длина ключа)
  • Исправления и улучшения:
    • Исправлена ошибка с дублированием функции логирования, которая вызывала ошибку парсинга JSON
    • Улучшено логирование: добавлена информация о настройках OpenRouter и прокси
    • Улучшен формат заголовка HTTP-Referer (добавлен https://)
    • Добавлен заголовок User-Agent для запросов к OpenRouter
  • Улучшенный поиск товаров при сохранении AI-категорий:
    • Многоуровневый поиск: точное совпадение → нормализация пробелов → игнорирование регистра → частичное совпадение
    • Все попытки поиска логируются для отладки
  • Обработка существующих категорий:
    • При повторной генерации существующие AI-категории перезаписываются (UPDATE)
    • Если категория не существует, создается новая запись (INSERT)
  • Детальное логирование:
    • Логи сохраняются в файлы /logs/ai_categories_YYYY-MM-DD.log
    • Логирование входящих данных, ответа нейросети, распарсенных данных
    • Детали по каждому товару (успешное сохранение, ошибки с типами)
    • Итоговая статистика обработки
  • Умный парсинг ответа нейросети:
    • Извлечение JSON из markdown блоков
    • Обработка обрезанных ответов (извлечение полных JSON объектов)
    • Восстановление незакрытых массивов и объектов
  • Созданы новые файлы:
    • ajax/ajax_generate_categories.php — AJAX эндпоинт для генерации категорий
    • admin/settings/create_ai_product_category_table.sql — SQL скрипт для создания таблицы kalinin_ai_product_category

Реорганизация раздела настроек

  • Функционал управления 301 редиректами перенесен в раздел "Настройки":
    • Созданы файлы admin/settings/redirects.php, redirects-create.php и redirects-edit.php
    • Добавлена карточка "301 редиректы" на главную страницу настроек
    • Улучшена навигация и единый стиль интерфейса
    • Все настройки сайта теперь в одном месте

Версия 2.3.0

26 декабря 2025

Новые функции

  • Реализован поиск компаний на странице списка компаний в городе:
    • Поле поиска в блоке заглавия страницы /{city-slug}/company/
    • Autocomplete с выпадающим списком результатов при вводе
    • Подсветка найденного текста в результатах
    • Поддержка транслитерации (DNS ↔ ДНС)
    • Поиск без учета регистра
  • Реализован живой поиск городов на странице выбора города:
    • Поиск в реальном времени при вводе текста (live search)
    • Autocomplete с выпадающим списком результатов
    • Подсветка найденного текста
    • Отображение региона для каждого города
    • Приоритет точным совпадениям
  • Созданы AJAX-эндпоинты для быстрого поиска:
    • ajax/ajax_search_companies.php — поиск компаний
    • ajax/ajax_search_cities.php — поиск городов
  • Добавлены функции поиска в include/search.php:
    • ms_transliterate() — транслитерация кириллицы в латиницу
    • ms_search_companies() — поиск компаний с поддержкой транслитерации

Технические улучшения

  • Создан SQL скрипт для FULLTEXT индекса на таблице kalinin_company (admin/settings/create_search_indexes.sql)
  • Реализован гибридный подход к поиску:
    • FULLTEXT поиск (если индекс создан)
    • Fallback на LIKE поиск (если индекс не создан)
    • Автоматический поиск без фильтра по городу, если с фильтром ничего не найдено
⚡ Performance Logger 5 запросов | 5.26 ms | 2 MB
Время загрузки страницы
5.26 ms
Количество запросов к БД
5
Общее время запросов
2.90 ms
Среднее время запроса
579 μs
Использование памяти
2 MB
Пиковое использование памяти
2 MB
Запросы к БД (5)
#1 460 μs
SHOW TABLES LIKE 'kalinin_seo_templates'
seo.php:53 __call()
seo.php:136 ms_seo_get_template()
router.php:272 ms_seo_render()
#2 801 μs
SHOW COLUMNS FROM kalinin_seo_templates LIKE 'noindex'
seo.php:59 __call()
seo.php:136 ms_seo_get_template()
router.php:272 ms_seo_render()
#3 1.26 ms
SELECT h1, title, description, noindex FROM kalinin_seo_templates WHERE page_type = ? LIMIT 1
MysqliStmtWrapper.php:125 logQuery()
MysqliStmtWrapper.php:28 trackExecute()
seo.php:76 __call()
#4 310 μs
SHOW TABLES LIKE 'kalinin_settings'
settings.php:81 __call()
header.php:13 ms_get_settings_bulk()
router.php:1229 require_once()
#5 61 μs
SELECT `key`, `value` FROM kalinin_settings WHERE `key` IN (?,?,?)
MysqliStmtWrapper.php:125 logQuery()
MysqliStmtWrapper.php:28 trackExecute()
settings.php:106 __call()