Проверить свойства поля через rules

Главные вкладки

Аватар пользователя morgusha morgusha 27 января в 19:42

Подскажите пожалуйста как реализовать такое:
При создании или обновлении материала срабатывает правило отправить mail.
Но нужно чтобы это правило срабатывало только тогда, когда у свойства Отправить письмо стоит галочка.
Создал в правиле Условия "И" и выбрал php код и там вставил такое вот:

<?php
[node-unchanged:field_send_main_ob] == 1
?>

Но не срабатывает !

Лучший ответ

Аватар пользователя morgusha morgusha 1 февраля в 10:37

Вообщем итоговый код рабочий такой вот:

function before_save_node_update($node) {

  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 после нажатия СОХРАНИТЬ

Комментарии

Аватар пользователя OldWarrior OldWarrior 29 января в 2:08
1

morgusha wrote: [node-unchanged:field_send_main_ob]

Это не 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 в коде хука тоже следует проверить в этом случае. Я уже не стал добавлять это.

Аватар пользователя morgusha morgusha 29 января в 23:31

хм...подписка реализована модулем Subscriptions.
выходит данный модуль тоже после нажатия на сохранить вызывает уже свою функцию, но после хука hook_node_presave ?
Можно ка кто посмотреть какие вообще функции или хуки вызываются после обновления материала ?

Аватар пользователя morgusha morgusha 30 января в 19:19

Я уж извиняюсь ) вообщем сделал я свой модуль ! Но никак не могу разобраться почему не работает такое вот:

function before_save_node_presave($node) {
  $node_original = $node->original;
  if (($node_original->get('field_send_main_ob')) && ($node->type =='article')) {
      drupal_set_message(t("Don't panic!"), 'warning');
  }
}

при сохранении пишет:
На сайте произошла непредвиденная ошибка. Пожалуйста, повторите попытку позже.

Аватар пользователя OldWarrior OldWarrior 30 января в 23:36

Я извиняюсь, недопечатал: метод должен быть $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 очень существенная.

Аватар пользователя morgusha morgusha 30 января в 22:39

Вообщем вышло так вот:

function before_save_node_presave($node) {

  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 если условие выполняется ?
или может есть какой то более лучший способ ?

Аватар пользователя morgusha morgusha 30 января в 23:47

Спасибо ! 7 версия !
сейчас сделал так вот:

<?php

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();
  }
}

Но это не верно ! выходит в базе модуль выключается. И для другого типа материалов подписка тоже перестанет работать !
Не подскажите как сделать более верно ?

Аватар пользователя OldWarrior OldWarrior 31 января в 0:21

Конечно, это не верно.

Вообще-то, если уж задача простирается дальше, чем просто проверка чекбокса на PHP и требуется вмешательство в email-подписку через Rules (хотя мне не совсем понятно, как вы собирались решать это на PHP из управления правилами в админке), то возможно работать тогда будет удобнее через хуки Rules:

https://api.drupal.org/api/rules/rules.api.php/group/rules_hooks/7.x-2.x

Аватар пользователя morgusha morgusha 31 января в 15:50

Модуль devel установлен, но через него не удалось вывести хуки которые вызываются при обновлении материала.
В итоге как же это можно сделать )
Капец как сложно ! Может можно записывать обновлённые данные в материал, но не назначать ему статус обновленного ?

Аватар пользователя morgusha morgusha 31 января в 17:52

Я решил сделать так вот :

function before_save_node_update($node) {

  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');
         
         
         
  }

Но почему то таблица с очередью не очищается ?

Аватар пользователя morgusha morgusha 1 февраля в 10:37

Вообщем итоговый код рабочий такой вот:

function before_save_node_update($node) {

  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 после нажатия СОХРАНИТЬ

Аватар пользователя Andruxa Andruxa 1 февраля в 11:08

А если в очереди были письма, которые надо было отправить, но этого пока не произошло - на то она и очередь?

Аватар пользователя morgusha morgusha 1 февраля в 11:16

Выполняется крон каждую минуту. Так что такая ситуация мало вероятна. Другого решения найти я не смог. Есть варианты ?

Аватар пользователя Andruxa Andruxa 1 февраля в 12:31

morgusha wrote: Так что такая ситуация мало вероятна

Закон Мерфи суров, но это закон.

morgusha wrote: Есть варианты ?

В условиях рула добавить проверку на существование у ноды (сущности) требуемого поля - это даст в дальнейшем доступ к значениям этого поля.
И следующая проверка - на значение этого поля.
PHP не нужен.

Аватар пользователя morgusha morgusha 1 февраля в 14:16

Что-то там модуль тупит и половина правил не срабатывает даже на начальном этапе их формирования.
Типа такие ошибки вылазят:
Поле "Селектор данных" обязательно для заполнения.
Поле "Значение" обязательно для заполнения.
Отсутствует настройка для параметра entity.

Как говорится И ТАК СОЙДЁТ )