Кабинет
Как устроен пакет

#События

Решения не вызывают друг друга напрямую. Вместо этого одно объявляет событие, а другое на него подписывается.

плохо:  Форма  →  CRM::создатьЗаявку()
хорошо: Форма  →  событие form.submitted
        CRM    →  слушает form.submitted → создаёт заявку
Почему так

Разница не в красоте. При прямом вызове форма перестаёт работать, если CRM не установлена: класса нет, вызов падает. Через событие форма не знает, слушает её кто-нибудь или нет, и работает одна.

#Какие события есть

СобытиеКто объявляетКогда
form.submittedФормыпосетитель отправил форму
crm.lead.createdCRMпоявилась заявка
crm.lead.status_changedCRMзаявка перешла в другой статус
task.createdЗадачисоздана задача
task.status_changedЗадачизадача сменила статус
task.completedЗадачизадача завершена
module.renderedядроблок нарисован — можно дописать разметку
admin.record.renderedядрооткрыта запись в панели — можно добавить блок

#Кто на что подписан сейчас

РешениеСлушаетЧто делает
CRM и формыform.submittedзаводит заявку из отправленной формы
admin.record.renderedпоказывает связь с заявкой в карточке
Задачи по сделкамcrm.lead.createdсоздаёт задачу на новую заявку
crm.lead.status_changedсоздаёт задачу при переходе статуса
Формыmodule.renderedдописывает в блок формы её поля
Примечание

Последняя строка показывает, зачем событие module.rendered нужно ядру. Набор полей формы заранее в вёрстке не перечислить — их заводит человек. Ядро при этом не должно знать про формы: кто хочет дописать разметку — тот подписывается.

#Как подписаться

В манифесте своего решения:

"listeners": {
  "crm.lead.created": "MoiKlass::onLead"
}

Обработчик — метод класса из src/ решения:

class MoiKlass
{
    public static function onLead(array &$payload)
    {
        // $payload['lead'] — номер заявки
        // Данные можно дополнить: они вернутся тому, кто объявил событие.
    }
}

Данные передаются ссылкой: слушатель вправе их дополнить. Так CRM возвращает форме номер созданной заявки, а форма показывает его посетителю.

#Защита от кольца

Событие, вызванное из обработчика того же события, ушло бы в бесконечную рекурсию. Такой вызов отклоняется, а в журнал сервера уходит строка «кольцо на событии …».

#Журнал событий сайта

Отдельно от шины событий сайт ведёт журнал — что и когда менялось. Туда попадают:

module_created       модуль заведён
module_updated       вёрстка модуля или вида изменена
template_restored    нажата «Вернуть исходный код»

Первый вопрос при «сайт вдруг сломался» — что менялось и когда. Журнал на него отвечает.