Рекомендуемая замена modifyClass("model:composer") при переопределении save()

Я перехожу от устаревшего api.modifyClass("model:composer", ...).

В моей текущей переопределённой реализации Composer#save условно изменяется поведение сохранения, но в остальных случаях необходимо вызывать super.save(opts).

Я вижу новые API addModelMethod / addModelCallback, но не могу найти в ядре пример использования addModelMethod для переопределения существующего метода с сохранением доступа к исходной реализации.

Предназначен ли addModelMethod для переопределения существующих методов модели таким образом? Если да, как плагин должен делегировать вызов исходной реализации save()?

Или существует другая точка расширения, которую следует использовать для этого случая с Composer?

Думаю, это зависит от того, что именно вы хотите сделать, переопределяя метод сохранения…

Если вы хотите предотвратить сохранение на основе какого-либо условия, вы можете использовать наш преобразователь значений composer-service-cannot-submit-post

Если вы хотите выполнить какое-то действие после создания поста, есть api.onAppEvent("post:created")

Если вы добавляете поле, есть api.serializeOnCreate

Подходит ли что-то из этого под ваши задачи?

Спасибо! Я уже использую composer-service-cannot-submit-post — он обрабатывает проверку на уровне сервиса. Но метод save() модели композера также проверяет cantSubmitPost, который включает условие missingReplyCharacters > 0, поэтому пустое тело сообщения всё равно блокируется там.

onAppEvent("post:created") срабатывает слишком поздно, потому что сообщение так и не создаётся, а serializeOnCreate лишь добавляет поля в запрос, поэтому он не помогает с валидацией длины тела сообщения.

Таким образом, остаётся проблема обхода проверки missingReplyCharacters / cantSubmitPost для первого сообщения. Есть ли поддерживаемая точка расширения для этого?

Вот текущий инициализатор для справки:

@david, буду признателен за любые соображения относительно наилучшего подхода в данном случае.

Лучшим решением было бы добавить новый хук в ядро Discourse, который позволит вам реализовать нужную функциональность поддерживаемым способом. Как вам такой вариант:

Тогда ваш плагин будет выглядеть так:

api.registerValueTransformer(
  "composer-minimum-post-length",
  ({ value, context: { composer } }) => {
    if (
      composer.siteSettings.discourse_optional_topic_body_enabled &&
      composer.topicFirstPost
    ) {
      return 0;
    }

    return value; // Сохраняем логику ядра
  }
);

Дайте знать, если это сработает для вашего случая, и я уберу PR из статуса черновика, чтобы его можно было просмотреть и объединить.

Спасибо, Дэвид! Я протестировал трансформер composer-minimum-post-length, и он работает — темы с пустым содержимым успешно создаются.

Однако я заметил одну вещь: редактор по-прежнему выводит сообщение «Сообщение не может быть пустым», так как в composer-editor валидация содержит жёстко заданную проверку replyLength < 1, которая не учитывает minimumPostLength.

Можно ли так же, чтобы эта проверка учитывала трансформер, или пропускалась, когда minimumPostLength равно 0?

Звучит хорошо — добавил в PR :+1:

Теперь всё работает идеально. Большое спасибо за добавление этой функции, @david! :raising_hands: