1

I am trying to send a mail to a set of users when a node is created, so I made a users view including VBO field and a rule for it. You can see the settings below. It's about D7.

enter image description here enter image description here

But when the rule gets in action, no mails sent and the following messages appear in admin/reports/dblog:

Unable to evaluate loop.

Unable to get variable entitylistem, it is not defined.

Unable to evaluate action views_bulk_operations_action_load_list.

Unable to get a data value. Error: Invalid data value given. Be sure it matches the required data type and format. Value at user():

What is wrong?

11
  • I've never really had much luck with loading entity objects. I usually fetch the entity ids, then loop and fetch the users with that and then the email field should be available. Mar 7, 2017 at 4:00
  • Thanks for your comment. I have to use VBO since I need to filter the view by a taxonomy term if I could achieve to pass this error.
    – Xtrageik
    Mar 7, 2017 at 9:57
  • Your prior comment was posted while I was preparing my answer. Am I right in assuming that you meen something like "I have to use a view since I ned to filter the view by taxonomy term"? If so then you can perfectly do so using my plan-B answer ... would you agree? Mar 7, 2017 at 10:06
  • @Xtrageik I meant the other VBO action that only loads IDs. Mar 7, 2017 at 10:32
  • @Niall the other option works with no errors but since it only fetchs the entity id's, it's not suitable for my case.
    – Xtrageik
    Mar 7, 2017 at 10:35

4 Answers 4

2

Obviously "something" is wrong in what you're trying to get to work. I suggest you enable the typical the Rules debugging (to find more details about what's happening and causing your error), as detailed in "How can I display the value of a variable inside a condition?". If needed, add a copy of the Rules execution log as an update to your question.

Maybe also checkout the tutorial "How to process the results of a VBO enabled view via Rules?".

Plan B

A possible alternative that should work also, is to get the Views Rules module involved in the puzzle you're trying to solve (instead of using VBO). Some details about this module (from its project page):

Provides Views directly as Rules actions and loops to seamlessly use view result data.

If you're not familiar with Rules (yet), the previous quote may seem a bit cryptic (it may make you think like "so what, how can this help me?"). Therefor some more details about how to move forward using these modules:

  1. Create a view (using Views) so that you have 1 Views result (row) for each user to be eMailed, whereas that view has fields (columns) for each of the fields that you want to use to create your eMail. So your existing view could already be pretty close (if you just remove the VBO field). Important: use a Views display type of "Rules".
  2. Create a custom rule in which you use the Views Rules module to iterate over each of these Views results in a Rules action, using the Rules technique known as a "Rules Loop".
  3. For each iteration step in your Rules loop, perform a Rules Action to ... euh ... right ... Send an eMail. At that point you'll have all data from each column of your Views results available as so called Rules Parameters. So at that point it's a piece of cake to create an appropriate eMail.
  4. The only remaining thing is to decide about the Rules Event to use for this rule to be triggered. But that's up to your own imagination (any Rules Event will do). In your case: your existing Rules Event should also be fine. Optionally, you may also want to add whatever extra Rules Condition(s), also up to your own imagination.

Easy, no?

PS: I'm assuming this question is about D7 ...

1
  • Yeah it's about D7. Your Plan B works like a charm as a component. Now I am dealing with the other parts of the rule. Thanks a lot!
    – Xtrageik
    Mar 7, 2017 at 11:23
2

I would suggest you to simply write your custom rules action like this

function mymodule_rules_action_info() {
 return array(
  '_send_new_content_mail' => array(
    'label' => t('Send Mail to users for new content'),
    'parameter' => array(
    'node' => array('type' => 'node', 'label' => t('Current Node')),
    ),
    'group' => t('custom'),
  ),
 );
}

Define your callback:

function _send_new_content_mail($node) {
  global $base_url;
  $query = db_select('users', 'u');
  $query->join('users_roles', 'r', 'u.uid = r.uid');
  $query->leftJoin('field_data_field_first_name', 'n', 'u.uid = n.entity_id');
  $query->leftJoin('field_data_field_last_name', 'l', 'u.uid = l.entity_id');
  $query->fields('u', array('mail', 'name'));
  $query->fields('n', array('field_first_name_value'));
  $query->fields('l', array('field_last_name_value'));
  $query->condition('r.rid', ROLE_ID, '=');
  $result = $query->execute()->fetchAll();

  foreach ($result as $val) { 
    $alias = drupal_get_path_alias('node/' . $node->nid);
    $data = 'Hi ' . $val->field_first_name_value . ' ' . $val->field_last_name_value . ', new content has been published of your interest. ';
    $data .= 'Click ' . l('here', $base_url . '/' . $alias) . ' to see the content.';
    $key = 'new_content_mail';
    $subject = 'New content published';
    $to = $val->mail;
    _get_mail_content($data, $to, $key, $subject);
  }
}

Now define your mail content function:

function _get_mail_content($data, $to, $key, $subject) {
  $mail_content = _mail_content($data, $key);
  $params = array(
   'body' => $mail_content,
   'subject' => $subject,
  );
  $mail = drupal_mail('module_name', $key, $to, language_default(), $params, '[email protected]', TRUE);
  if ($mail['result']) {
   return TRUE;
  }
  else {
    $error_msg = 'Failed to send the email!';
    watchdog('new-content-email', $error_msg, array(), WATCHDOG_ALERT);
    return FALSE;
  }
}

Define _mail_content:

 function _mail_content($data , $key) {
   switch ($key) {
    case 'new_content_mail':
      return theme('mymodule_new_content_mail', array('data' => $data));
    break;
   }
 }

Now define the template file in your hook_theme() and print $data inside it.

function mymodule_theme() {
  return array(
    'mymodule_new_content_mail' => array(
      'template' => 'mymodule-new-content-mail',
      'path' => drupal_get_path('module', 'mymodule') . '/templates',
      'variables' => array('data' => NULL),
    ),
  );
}

Now add new rule, select the event node-after publishing new content, add the node type in the condition for which you want to send mail and select _send_new_content_mail in action which will be present under 'custom'.

5
  • 1
    Interesting alternative for those who prefer to build their custom module for this. I haven't tested it (have you?), but IMO there is at least 1 (possible 2) errors near the top: (1) hook_ cannot be correct and (2) are you sure there is nothing missing to invoke the _send_new_content_mail function (I think something is missing, no)? Mar 7, 2017 at 12:06
  • thanks for reminding. Yes I have implemented this and hook obviously needs to be replaced with your module name. Mar 7, 2017 at 12:38
  • My question was not if you implemented this, bit if you "tested" this. And the main reason why I doubted is exactly because of the (appropriate!) correction you now applied in revision 2 of your answer. How about you try to make it perfect by changing the "hook_" to "mymodule_" also (like you already did for the theme function in the end). If you do, you get my +1 (because I like it as a sample to illustrate another solution using custom code). OK? Mar 7, 2017 at 12:46
  • Well that's your choice whether you give +1 or not :). Hope you understand the functionality that how its working. Mar 7, 2017 at 12:58
  • merci for accepting my suggestion! Mar 7, 2017 at 13:11
1

It is very well possible that your "issue" (the errors produced in your first Rules Action) is because of the Rules Event you're using (= "after saving new content"), which might simply not be the right event. Don't believe me ... yet ... read on to get surprised ...

Have a look at issue # 430274, about an event which is a variation of your event here, and somehow explains that After saving something actually happens ... Before saving something (which is not a bug, simply how the Rules module works ...).

A possible compromise to avoid these kind of issues, is to transform what's you're trying to do into a Rules Component, so that your original Rule "schedules the execution" (using the Rules Scheduler submodule) of that Rules Component (eg X secs or mins "after saving that new user account" ... if your cron job runs frequent enough, if not it'll be next time cron runs). This compromise will ensure that at the time the Rules Component is executed, the content is for sure saved ... (so that can't be the reason anymore then why it would still be empty ...).

1
  • Yeah I did tHat before, I set the whole thing as a component and executed manually. The result is same. When I am asking the question, to be clear and ask about the next steps easily, I asked as if I am doing this in a triggered rule. :)
    – Xtrageik
    Mar 7, 2017 at 11:20
0

There seems to be a bug in the latest version of VBO.

Check out https://groups.drupal.org/node/516374#comment-1153591 for a fix

1
  • This might be considered a link-only answer though probably correct. Thank you for adding it and hopefully it is useful to others.
    – mradcliffe
    Apr 21, 2017 at 11:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.