
Витрина брокера: автономное представительство на базе Cyclos API

Каждый брокер платформы «СЭП Регион» — это отдельная история, своя аудитория и свой стиль. Но технически все они живут в одном портале. Когда брокеру нужна персональная посадочная страница с объявлениями, новостями и формой регистрации, возникает дилемма: либо клонировать весь проект и поддерживать его отдельно, либо довольствоваться ссылкой на общий ресурс.
Ни то ни другое нас не устроило. Мы построили третий путь — лёгкий автономный движок, который формирует представительство брокера на лету, получая данные исключительно через API Cyclos.
Архитектура: MVC-lite без фреймворочного жира
Движок написан на чистом PHP 8.3 + MySQL + Bootstrap 5. Никаких Laravel, Symfony или Composer. Осознанный выбор: задача узкая, зависимости должны быть минимальными, а порог входа для поддержки — нулевым.
Ядро состоит из пяти классов:
- Engine — оркестратор. Загружает конфиги, резолвит брокера по домену, инициирует запросы к Cyclos, передаёт управление роутеру.
- Router — диспетчеризация по чистым URL. Ленивая загрузка обработчиков: файл маршрута подключается только при обращении.
- Builder — сборщик HTML. Получает контракт (заголовок, блоки, модальные окна) и отдаёт готовую страницу. Не знает ничего о бизнес-логике.
- CyclosClient — синглтон-аккумулятор данных. Все ответы API оседают в статическом хранилище, доступном любому блоку через
getData(). - BrokerResolver — маппинг
HTTP_HOST→ запись в БД → плоский массив с префиксомdb_. Добавление колонок в таблицу не требует правки кода.
Контент собирается из блоков: Navbar, Stats, Media, MarketplaceGrid, News, Reviews, Subscribe, Footer. Каждый блок — самодостаточный класс с методом render(). Порядок блоков определяется в маршруте, а не в шаблоне.
Данные: один запрос — всё представительство
При первом хите Engine выполняет четыре запроса к Cyclos:
- UI-метаданные платформы (название, rootUrl, версия).
- Профиль брокера (организация, контакты, координаты, кастомные поля).
- Счётчик пользователей.
- Объявления с файловым кэшированием.
Результаты аккумулируются в памяти и доступны всем блокам без повторных обращений к API. Кэш объявлений живёт в /data/adv_{broker}.json, TTL задаётся в конфиге. При сбое API отдаётся просроченный кэш — витрина никогда не показывает пустоту.
Запись кэша атомарна: сначала пишется временный файл, затем rename(). Это исключает race condition при параллельных запросах — читатель видит либо старый, либо новый файл, никогда не обрезанный.
Мультидоменность без мультисайта
Движок не знает, сколько брокеров он обслуживает. Резолвинг происходит по HTTP-заголовку Host. Таблица brokers хранит привязку домена к логину Cyclos. Новый брокер = новая строка в БД + DNS-запись. Код не меняется, конфиги не правятся, деплой не нужен.
Это не мультисайт в понимании WordPress. Здесь нет общих таблиц контента, плагинов или тем. Есть один механизм рендеринга и изолированные данные для каждого представительства.
Безопасность и изоляция
Описание профиля брокера приходит из Cyclos в формате richText. Это пользовательский HTML, который может содержать что угодно. Перед выводом в модальном окне он проходит санитизацию: удаляются <script>, <iframe>, обработчики событий on*, глобальные CSS-селекторы. Контент оборачивается в изолирующий контейнер со своими стилями.
Поле field_secret фильтруется на уровне CyclosClient и никогда не попадает в память, логи или JSON-ответы API. Пароли и токены хранятся только в .env вне webroot.
Оформление: фирменная палитра вместо шаблона
Вместо чёрного bg-dark и стандартных синих кнопок Bootstrap — два акцентных цвета кооперативной платформы: стальной синий #2795c4 и янтарный #d9851e.
Навбар получил glassmorphism-эффект: полупрозрачный градиент с backdrop-filter: blur(16px) saturate(1.8). Кнопки — янтарный градиент с объёмом через inset box-shadow. Фон страницы — многослойный CSS-паттерн из пересекающихся ромбов на пастельном градиенте. Без анимации скролла, без тяжёлых картинок, без мерцания.
Все кастомные стили изолированы префиксом sem-. Bootstrap не перезаписывается, конфликтов нет.
Почему не фреймворк
Cyclos API возвращает специфическую структуру данных, которая не ложится на ORM без костылей. Бизнес-логика проекта — это по сути маппинг и рендеринг, а не CRUD. Фреймворк добавил бы сотни файлов, зависимость от обновлений и сложность отладки ради задачи, которая решается пятью классами.
Чистый PHP здесь — не экономия, а точность. Каждый компонент делает ровно одно дело, тестируется глазами, деплоится копированием файлов.
Что дальше
Движок работает в продакшене на orsk.coopteam.ru. В планах — форма регистрации через API Cyclos прямо на сайте брокера, фильтрация объявлений по категориям и интеграция с AI-сервисами ADVIZOR для генерации описаний товаров.
Но главное уже сделано: каждый брокер получил своё лицо, не потеряв связь с общей платформой. Кооперация — это когда общее усиливает частное, а не поглощает его.