Helper — это вспомогательный для NpjObject класс, а вернее — дерево классов, позволяющее реализовать множество «псевдотипов» записей, с разными интерфейсами редактирования. Поскольку в итоге в базе хранится компилированный html, то реализации гибкой схемы управления интерфейсом редактирования должно хватить на воплощение большинства функциональных требований.
На архитектуре хелперов построены:
Анонсы;
Дайджесты;
и даже вполне обычные дневниковые посты и документы тоже используют эту архитектуру.
2. Задачи кода хелперов
Программный код хелпера может уметь:
Видоизменить конфигурацию веб-формы «форм-процессора», заполнив её адекватными данными (например, анонсы добавляют целую группу, а «простой черновик дайджеста» лишь заполняет текстовое поле содержимым).
Обработать полученные из формы данные и сохранить их в дополнительные таблицы (например, анонс или рубрикация).
Обработать полученные из формы данные и видоизменить их представление в основной таблице (например, «простой черновик дайджеста»).
Я специально написал «может», потому что как правило код каждого хелпера делает лишь два пункта из трёх. Только дайджесты, кажется, отличились.
3. Иерархия хелперов
Классы хелперов выстроены в иерархию отношением наследования. Вот эта иерархия:
HelperAbstract
HelperRecord
HelperPost
HelperEvent
HelperAnnounce
HelperDocument
HelperDigest
HelperDigestForm
Что умеют/для чего предназначены хелперы? Вот таблица:
HelperAbstract
абстрактный класс
HelperRecord
Добавляет группу «Классификация» / “ref”
Добавляет в эту группу поле «Рубрики»
Обеспечивает рубрикацию через $this->ref[...]
HelperPost
Добавляет в группу “ref” поле “communities” / «Сообщества»
Дополняет $this->ref[...] данными из поля “communities”
HelperEvent
Добавляет группу «Анонс»
Добавляет в группу «Анонс» поле «Анонсировать в сообществах»
Дополняет $this->ref[...] данными из поля «Анонсировать в сообществах»
HelperAnnounce
Добавляет в группу «Анонс» поле «Анонсируемый документ» и сопутствующие
Убираем галочку «блокировать комментирование»
HelperDocument
Обновляем «блокировать комментирование» у всех анонсов этого документа
HelperDigest
Умеет расшифровывать параметры из урла into $this->request_params[]
Умеет проверять валидность параметров и подгонять их (используется также в npj/actions/digest.php)
Вызывает action Feed для получения тела дайджеста
Заполняет body по шаблонам из темы “_digest”
Записывает в $this->rares[...] информацию о дайджесте
HelperDigestForm
Работает на форм-процессоре
4. Методы хелперов и их назначение
У хелпера есть куча методов, они вызываются из разных мест и предназначены для разного. Это сложная, сложная структура =(
Вот это «внешние методы», они вызываются ото разных мест:
TweakForm
На вход ему даётся массив из групп полей формы, а он её коверкает, добавляя/убирая поля или даже группы полей. На выходе — такой же массив групп полей, но другой.
PreSave
На входе $data из record/_save.php, которую он корёжит и возвращает на выходе
Save
На входе $data из record/_save.php, метод делает магические пассы (как правило, заполняет $this->ref, $this->rare) и вызывает внутренние методы. Вот почему, если вы override этот метод, то вам стоит вызвать метод-родитель.
ParseRequest
Новое приобретение. Рассматривает хорошенько $_REQUEST на предмет параметров, которые стоит включить в $params хандлера. На всякий случай записывает их внутрь себя в $this->request_params
А ещё есть внутренние методы, которые что-то проворачивают и их override не стоит
_UpdateRef
Осуществляет сохранение настроек рубрикации и публикации. Иными словами, сохраняет рефы, которые мы надобавляли в $this->ref. Сложный код, проверяются существование рубрики, права доступа, всё такое
_UpdateRare
Осуществляет сохранение «редких полей» из $this->rare в records_rare
Есть ещё метод _Automate, но документации по нему пока нет =( [to be supplied.]
5. Свойства хелперов и их назначение
Самые главные свойства хелперов это, конечно:
$this->ref
npj_address=>array(...)
Ссылки на рубрики, куда нужно опубликовать/срубрицировать запись. Ключ массива — название рубрики, таким образом, дважды публиковать в рубрику не выйдет. Примерное содержание одного элемента $this->ref["kuso@npj:"] например: array( announce => 0, syndicate => 0, «group*"=> XX, server_datetime => XX, need_moderation => 0, keyword => «ЧтоТо/СЧемТо" )
$this->rare
field=>value
Дополнительные поля, которые будут сохраняться в records_rare. Не забудьте, что сохранение происходит в соответствии с $rh->records_rare, который вы найдёте в config_tunes.php, так что если вы там чего не укажете, то и сохраняться оно не будет.
$this->request_params
param=>value
Пожалуй, самое простое. Параметры, вытащенные из URL и скиданные в беспорядке в этот массив, чтобы не потерялись
В дайджестах вы можете столкнуться с:
$this->digest_bodies
Здесь после LoadDigest оказывается содержимое ленты, которую мы вызываем через Unknown action "Feed" с особым параметром, так, что она сразу возвращает массив, заполненный значениями в стилей NpjObject::_PreparseArray(..)
6. Порядок и места вызова хелперов и их методов
Охохох. Всё это происходит в цикле “edit-save”.
SpawnHelper, ParseRequest, а затем TweakForm вызываются в форме !form_record.php, примерно на 5–6 фазе, перед конструктором формы.
SpawnHelper и PreSave вызываются в противофазе_save.php, примерно между фазами 1 и 2. Отметим, что здесь SpawnHelper вызывается «слабым», т.е. не пытается пересоздать, если обнаруживает готовых хелпер (это может привести к проблеме при реплицировании дайджеста. проверить)
Save вызывается в том же _save.php, в фазе 5 примерно.
7. Как написать свой хелпер
Нужно на это решиться.
Придумать, как и где новый хелпер впишется в иерархию. Лучше посоветоваться с kuso@npj.
Создать в npj/classes файл с названием, соответствующим имени класса. Лучше всего скопировать какой-нибудь недалёкий по смыслу готовый хелпер.
Переименовать внутри всё, чтобы класс хелпера назывался нормально, наследовал у кого надо.
Найти NpjObject::SpawnHelper (это в файле npj/classes/NpjObject.php) и вписать туда каким-то образом способ, как будет распознаваться, что должен создаться именно ваш хелпер.
Прописать вторую сторону идентификации в post,add или edit (см. готовые примеры по анонсам или дайджестам)
Если всё продолжает работать — ваш пустой, ничего не делающий хелпер готов!
8. Как написать свой непустой хелпер
Хорошенько подумать
Написать пустой хелпер
Понять, какие методы нужно override (как правило, это TweakForm и Save, может ещё PreSave)
Взять код метода и переписать его. Повторять до иссякания списка из максимум трёх пунктов.