Срабатывание плагина, если tv изменился
Приветствую.
Подскажите, есть ли возможность проверить, изменилось ли значение tv-параметра ресурса и (если изменилось) выполнить плагин по onDocFormSave (например)?
Ситуация: для раздела есть поле скидка. При его изменении — изменяется цена товаров данного подраздела.
Нужно запустить плагин (выполнить изменение цен) только тогда, когда значение скидки изменилось (чтобы не нагружать сервак просто так).
Подскажите, есть ли возможность проверить, изменилось ли значение tv-параметра ресурса и (если изменилось) выполнить плагин по onDocFormSave (например)?
Ситуация: для раздела есть поле скидка. При его изменении — изменяется цена товаров данного подраздела.
Нужно запустить плагин (выполнить изменение цен) только тогда, когда значение скидки изменилось (чтобы не нагружать сервак просто так).
Комментарии: 20
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Или для этих же целей можно использовать:
как то так…
Вот чуть измененный вариант
В сниппете RecalcPrice меняешь цены согласно новой скидке для ресурсов из раздела, указанном в параметре parent.
А еще подскажи пжлста, как в сниппете RecalcPrice получить пришедшие переменные?
Раньше не доводилось вызывать runSnippet
И есть еще массив всех переменных сниппета $scriptProperties. Можно через него $scriptProperties['discount'] и т.п.
Если они отличаются — выполнять свой код по обновлению цен. Можно прям в этом событии, а можно поставить флаг в сессию, выполнить код в OnDocFormSave (то есть, уже после сохранения новой цены в ТВ) и удалить флаг до следующего раза.
В любом случае, нужно слушать события изменения документа, потому что все сохранения ТВ — там.
Но вот как получить ТВ по событию OnBeforeDocFormSave (кроме предложенного выше решения)?
ТВ в $_POST, если я не ошибаюсь, получаются как tv_id, то есть:
В OnBeforeDocFormSave новые (сохраняемые) значения TV можно получить следующими способами:
1) Из массива $_POST (как указал Василий). Но этот вариант работает только при вызове коннекторов (сохранение ресурса в админке). Если процессор вызывается из собственного кода, то никаких параметров в запросе не будет.
2) Из массива data, который также передаётся плагину (не задокументирован). В этом массиве лежат все новые (сохраняемые) параметры — и стандартные, и ТВ. Ключ стандартного параметра = имени параметра, ключ ТВ = tvID.
В OnBeforeDocFormSave старые (исходные) значения TV можно получить методом getTVValue (извлекает данные непосредственно из БД).
Самый корректный вариант, имхо, — это OnBeforeDocFormSave + массив data + getTVValue.
0. При работе с сессиями в любом виде, на странице (в админке), в которой производится изменение скидки, выводится "../www/core/components/shopkeeper/elements/tv/output/".
1. От Сергея modx.pro/help/4600/#comment-33447
OnDocFormRender не выполняется при сохранении значения, только при перезагрузке страницы (вполне логично).
2. От Василия modx.pro/help/4600/#comment-33439
$_POST тоже приходит только при перезагрузке страницы + приходится пользоваться переменной сессии.
3. От Cyrax_02 modx.pro/help/4600/#comment-33448 Не смог добраться до массива data.
В итоге остановился на варианте №1. Указанные ограничения победить пока не удалось.
код:
По OnDocFormRender значение изменяется, но не обнуляется.
Думаю, с $_POST тоже самое.
Навскидку могу предположить, что:
а) ты его «искал» в тот момент, когда у тебя плагин не был подписан на событие OnDocFormSave и (или) OnDocFormRender. Массив $data передаётся только обработчику OnBeforeDocFormSave
б) получить к нему доступ ты пытался в разделе case 'OnDocFormRender' или case 'OnDocFormSave' оператора switch. С массивом $data нужно работать в case 'OnBeforeDocFormSave'
Ещё раз по порядку:
1) Подписываешь плагин на событие OnBeforeDocFormSave
2) В плагине в разделе case 'OnBeforeDocFormSave' пишешь:
3) Загружаешь страницу (именно ту, которая вызывает плагин)
4) Смотришь логи modx: там увидишь все НОВЫЕ стандартные и ТВ-параметры, которые содержит массив $data. Также увидишь их ключи (как к ним обращаться).
События OnBefore...FormSave генерируются до физического сохранения новых значений и только в обработчиках этого события можно одновременно получить доступ и к старым значениям полей, и к новым. Именно для этого в OnBefore...FormSave и передаётся массив новых значений $data, которые будут физически сохранены после этого события.
P.S. У варианта OnBeforeDocFormSave + массив data + getTVValue пока не вижу никаких ограничений. Полная свобода.
Именно поэтому, если в период между загрузкой страницы ресурса и сохранением ресурса сессия истечёт, то при сохранении ресурса (будет запрошена авторизация) в массиве $_SESSION значение discount_before установлено не будет.
Более того, если другой пользователь (с другой сессией) изменит значение скидки в период между загрузкой страницы ресурса и сохранением ресурса, то в OnDocFormRender будут получены старые значения (имевшие место в момент открытия страницы ресурса). Впрочем, в вашем случае, к проблемам это не приведёт, но во многих других задачах, где требуется обязательно получать актуальные на текущий момент значения, этот факт делает данный способ получения старых (исходных) значений неприменимым.
В массиве $_POST данные передаются именно в момент сохранения ресурса (скрипт сохранения вызывает коннектор путём отправки самостоятельного http-запроса к серверу).
Для получения старых (исходных) значений необходимо:
а) в OnBeforeDocFormSave — метод getTVValue()
б) в OnDocFormSave — только через ранее «запомненные» значения (например, через переменные сессии)
В любом случае, как я уже говорил, новых значений в POST-параметрах запроса не будет, если ресурс сохраняется из собственного кода. Кроме того, от версии к версии формат передаваемых в $_POST данных может меняться, поскольку эти данные предназначены исключительно для внутренних нужд modx (для коннекторов).
Попробовал ваш метод — действительно, все просто.
Только вот проблема теперь с shopkeeper'ом (тестировал на нескольких сайтах).
Непонятно, почему, но
выдает ошибку "../www/core/components/shopkeeper/elements/tv/output/".
Отписал разработчику shopkeeper'a. После устранения проблемы буду использовать ваш метод.
Для автоматического заполнения опции price_oct_day
Но при сохранении — тв поле price_oct_day не меняется =(
Подскажите где косяк?