Skip to content

Что такое pbFavorites ​

pbFavorites — закладки на любую модель для сайтов на PageBlocks 3.x. Товар, заявку, статью, компанию, человека: модель называется в вызове, а не зашита в компонент.

Пакет бесплатный и магазина не требует — в этом его смысл. Закладка на что угодно универсальна: её хочет блог, каталог услуг, справочник организаций, доска объявлений. Избранное выросло внутри pbShop и умело один товар; теперь оно живёт отдельно и умеет что угодно.

Это не самостоятельное приложение. Без PageBlocks компонент пишет ошибку в лог и выключается: оттуда приходят таблицы, роутинг, контроллеры, файловые шаблоны, миграции, шаблонизатор и — отдельно важное — механика анонимной сессии.

Нужен PageBlocks alfa24 или новее

Гостевое владение по cookie (Support\GuestToken) живёт во фреймворке с alfa24. На версии старше пакет выключается с записью в лог, а не работает «только для вошедших»: молча урезанное избранное хуже выключенного — кнопка есть, нажатие проходит, список пуст.

Что делает компонент и чего не делает ​

Это главная мысль, и дальше вся документация поделена именно по ней.

Компонент хранит и переключает. Таблица, уникальность пары «владелец + объект», гость по токену, слияние при входе, предел списка, чистка брошенного, счётчик, прогрев страницы.

Поставщик модели отвечает на три вопроса, потому что ответить на них может только тот, чьи это строки:

ВопросУ товараУ заявки на груз
Что считать видимымвыложен (published())не просрочена и не снята
Как нарисовать строкуцена «от», наличие, «в корзину»маршрут, дата, вес
Какой у записи адресот главной категории, которой может не бытьот номера заявки

Без этого разделения универсальное избранное либо печатает удалённое, либо заводит вторую копию правила видимости — и та однажды разойдётся с первой.

Один результат — два пути ​

php
// Вёрстка — шаблон MODX
[[!pbFavoriteButton? &model=`pbshop.product` &id=`[[+id]]`]]

// Вёрстка — Fenom в файловом шаблоне
{'!pbFavoriteButton' | snippet: ['model' => 'pbshop.product', 'id' => $product->id]}

// Разработчик — прямой вызов, сниппет не нужен вовсе
$favorites = modx()->services->get('pbfavorites');

$favorites->has('pbshop.product', $product->id);

Ни один путь не «правильнее» и не проходит через другой: верстальщик не обязан открывать IDE, разработчик не обязан пользоваться сниппетами.

Паритет двусторонний и проверяется тестом: срез и порядок (&limit, &offset, &sortby, &sortdir) считает сервис, а сниппет их только разбирает — поэтому возможности, доступной лишь в шаблоне, у пакета нет.

Свою логику вокруг закладок сайт вешает событиями — добавлено, убрано, отказано, очищено, слито при входе, — а не правкой компонента.

Словарь параметров — тот же, что у pbShop

&tpl, &tplWrapper, &tplEmpty, &limit, &offset, &sortby, &sortdir, &outputSeparator, &toPlaceholder, &showLog. Своих имён пакет не вводит и синонимов не плодит: выучивший вызов в магазине пишет вызов в закладках, не открывая документацию.

⚠️ Реестр моделей — это безопасность, а не удобство ​

Короткий ключ (pbshop.product) приезжает из браузера: он в теле запроса и в атрибуте кнопки. Без белого списка любой желающий пошлёт model=modxUser&id=1 и получит строку в таблице, а поставщик вывода однажды напечатает из неё то, что печатать не должен.

Поэтому модель обязана быть зарегистрирована компонентом вместе со своим поставщиком, а незнакомый ключ — отказ, а не «заведём строку и разберёмся потом». Снаружи ключ короткий, в базе лежит полное имя класса: ключ из запроса не превращается в произвольный класс, а модель находится однозначно.

Гость — наравне с вошедшим ​

«Сначала войдите» на кнопке — это отказ по нажатию, то есть ровно то, чего избранное должно избегать: закладку ставят раньше, чем решают заводить учётную запись.

Гость опознаётся токеном в cookie pb_wish (180 дней). При входе его список переезжает на учётную запись, дубли выбрасываются. Слияние предел не проверяет: выбросить закладки, которые человек ставил сам, ради ровного числа хуже, чем список на сто один объект.

Токен выдаётся только на первом действии. Страница сама по себе cookie не заводит — иначе она появлялась бы у каждого прохожего, и HTTP-кеш перестал бы работать на всём сайте.

Откуда он такой ​

Пакет собран из двух работавших реализаций, а не написан с нуля, и у каждой половины своя причина быть:

ОткудаЧто дало
универсальное избранное живого проекта (грузы, транспорт, компании, консультанты, люди)морф-таблица, белый список моделей, прогрев страницы одним запросом, счётчик наблюдателей, insertOrIgnore против гонки двух вкладок
pbShopгость по токену, предел, слияние при входе, чистка брошенного

Ни одна из двух не покрывала другую: у первой не было гостей, у второй — ничего, кроме товара.

Куда идти дальше ​

  • Быстрый старт — установить, напечатать кнопку, собрать страницу списка. Без PHP.
  • Разработчику — контракт поставщика, реестр, сервис, события, схема, крон.

pbFavorites — закладки на любую модель, бесплатно