Подскажите пожалуйста как реализовать такое:
При создании или обновлении материала срабатывает правило отправить mail.
Но нужно чтобы это правило срабатывало только тогда, когда у свойства Отправить письмо стоит галочка.
Создал в правиле Условия "И" и выбрал php код и там вставил такое вот:
<?php
[node-unchanged:field_send_main_ob] == 1
?>
Но не срабатывает !
Комментарии
Это не PHP-код, а похоже какой-то токен.
В теории, если уж из PHP, то следует обращаться к объекту Node. Но я не знаю, как его можно получить при использовании Rules.
Если бы была реализация задачи через модуль, то можно было бы использовать хук hook_node_presave(), типа:
<?php
/**
* Implements hook_node_presave()
*/
function mymodule_node_presave(\Drupal\Core\Entity\EntityInterface $node) {
$node_original = $node->original; // Предыдущее состояние ноды (до текущего сохранения).
if ($node_original->get('field_send_main_ob')) {
// Делайте тут, что хотите...
}
}
?>
PS. Ну и тип $node в коде хука тоже следует проверить в этом случае. Я уже не стал добавлять это.
хм...подписка реализована модулем Subscriptions.
выходит данный модуль тоже после нажатия на сохранить вызывает уже свою функцию, но после хука hook_node_presave ?
Можно ка кто посмотреть какие вообще функции или хуки вызываются после обновления материала ?
https://www.php.net/manual/ru/function.debug-backtrace.php
https://www.php.net/manual/ru/function.debug-print-backtrace.php
Или, если установлен Devel, то есть такое:
https://api.drupal.org/api/devel/devel.module/function/ddebug_backtrace/...
Я уж извиняюсь ) вообщем сделал я свой модуль ! Но никак не могу разобраться почему не работает такое вот:
$node_original = $node->original;
if (($node_original->get('field_send_main_ob')) && ($node->type =='article')) {
drupal_set_message(t("Don't panic!"), 'warning');
}
}
при сохранении пишет:
На сайте произошла непредвиденная ошибка. Пожалуйста, повторите попытку позже.
Я извиняюсь, недопечатал: метод должен быть
$node_original->get('field_send_main_ob')->value
.Строго говоря, $node_original я здесь ввёл из-за того, что в вашем исходном сообщении фигурировал токен
node-unchanged
. Только из-за этого я сделал предположение, что вам нужно проверять состояние чекбокса ПЕРЕД сохранением ноды (т.е. до внесения изменений). А так, если нет разницы, то можно читать и текущийи экземпляр Node (как он приходит в хук hook_presave). В общем, судя по всему, как-то так:<?php
function before_save_node_presave($node) {
$node_original = $node->original; // Или просто $node, если не нужно состояние перед сохранением.
// Неправильно для D8^.
//if (($node_original->get('field_send_main_ob')) && ($node->type =='article')) {
// Правильно для D^8. Внимание на $node->bundle().
if (($node_original->get('field_send_main_ob')->value) && ($node->bundle() =='article')) {
// Неправильно для D8^.
//drupal_set_message(t("Don't panic!"), 'warning');
// Правильно для D8^.
\Drupal::messenger()->addWarning("Don't panic!");
}
}
?>
Вообще, вам следует уточнить, под какой именно версию Друпала вы это делаете. Разница в API D7 и D8 очень существенная.
не может получить данные из текстового поля видимо drupal так вот ->get
таким вот способом получил значение поля пользовательского:
$rt = $node->field_send_main_ob['und'][0]['value'];
Вообщем вышло так вот:
if ($node->type =='article' && $node->field_send_main_ob['und'][0]['value'] == 1) {
drupal_set_message(t("Условие выполнено подписка не отправляется"), 'warning');
//drupal_set_message(t($rt), 'warning');
}
else{
drupal_set_message(t("Подписка отправляется подписчикам"), 'warning');
}
}
Теперь встал вопрос как делать дальше ?
Просто отключить через sql запрос модуль subscriptions_mail если условие выполняется ?
или может есть какой то более лучший способ ?
Какая у вас версия Друпала? Стоит начать с этого.
Спасибо ! 7 версия !
сейчас сделал так вот:
function before_save_node_presave($node) {
if ($node->type =='article' && $node->field_send_main_ob['und'][0]['value'] == 1) {
$q = db_update('system');
$q->condition('name','subscriptions_mail');
$q->fields(array('status' => 0));
$q->execute();
drupal_set_message(t("Условие выполнено подписка не отправляется"), 'warning');
//drupal_set_message(t($rt), 'warning');
}
else{
drupal_set_message(t("Подписка отправляется подписчикам"), 'warning');
$q = db_update('system');
$q->condition('name','subscriptions_mail');
$q->fields(array('status' => 1));
$q->execute();
}
}
Но это не верно ! выходит в базе модуль выключается. И для другого типа материалов подписка тоже перестанет работать !
Не подскажите как сделать более верно ?
Конечно, это не верно.
Вообще-то, если уж задача простирается дальше, чем просто проверка чекбокса на PHP и требуется вмешательство в email-подписку через Rules (хотя мне не совсем понятно, как вы собирались решать это на PHP из управления правилами в админке), то возможно работать тогда будет удобнее через хуки Rules:
https://api.drupal.org/api/rules/rules.api.php/group/rules_hooks/7.x-2.x
Модуль devel установлен, но через него не удалось вывести хуки которые вызываются при обновлении материала.
В итоге как же это можно сделать )
Капец как сложно ! Может можно записывать обновлённые данные в материал, но не назначать ему статус обновленного ?
Я решил сделать так вот :
if ($node->type =='article' && $node->field_send_main_ob['und'][0]['value'] == 1) {
$num_deleted = db_delete('subscriptions_queue')
->execute();
drupal_set_message(t("Условие выполнено подписка не отправляется"), 'warning');
}
Но почему то таблица с очередью не очищается ?
Вообщем итоговый код рабочий такой вот:
if ($node->type =='page' && $node->field_send_main_ob['und'][0]['value'] == 1) {
drupal_set_message(t("Условие выполнено подписка не отправляется !!!"), 'warning');
drupal_register_shutdown_function('delete_och', $node);
}
else{
drupal_set_message(t("Подписка отправляется подписчикам !!!"), 'warning');
/*$q = db_update('system');
$q->condition('name','subscriptions_mail');
$q->fields(array('status' => 1));
$q->execute();
$num_deleted1 = db_delete('cache_bootstrap')
->condition('cid', 'system_list')
->execute();*/
//$nodeinfo = print_r($node, TRUE);
//drupal_set_message($nodeinfo);
}
}
function delete_och($node){
db_delete('subscriptions_queue')
->execute();
drupal_set_message(t("Очередь удалена"), 'warning');
}
очищает таблицу очереди cron после нажатия СОХРАНИТЬ
А если в очереди были письма, которые надо было отправить, но этого пока не произошло - на то она и очередь?
Выполняется крон каждую минуту. Так что такая ситуация мало вероятна. Другого решения найти я не смог. Есть варианты ?
Закон Мерфи суров, но это закон.
В условиях рула добавить проверку на существование у ноды (сущности) требуемого поля - это даст в дальнейшем доступ к значениям этого поля.
И следующая проверка - на значение этого поля.
PHP не нужен.
Что-то там модуль тупит и половина правил не срабатывает даже на начальном этапе их формирования.
Типа такие ошибки вылазят:
Поле "Селектор данных" обязательно для заполнения.
Поле "Значение" обязательно для заполнения.
Отсутствует настройка для параметра entity.
Как говорится И ТАК СОЙДЁТ )