I would like to pass a string of text as a parameter to an event then use that text in a text area in an action. For example, I would like an event which is that an error has occurred and the action is that an email is sent with some text in it. The event has the error string (text) as a parameter. In the email, I would like to embed that text into the body of the email. I can do it if I switch to data selection mode, the parameter is available from the list, but in data input mode the replacement pattern is not available. Is this possible?

/**
  * Implements hook_rules_event_info().
  */
function mymodule_rules_event_info() {
return array(
  'mymodule_processing_failed' => array(
        'label' => t('After processing fails'),
        'group' => t('mymodule'),
        'variables' => array(
          'error_message' => array(
            'type' => 'text',
            'label' => t('The error message'),
          ),
        ),
      ),
    );

function _mymodule_processor() {
  try {
    // Do something that might throw an exception.
  }
  catch (Exception $e) {
      // Invoke the subscription processing failure rule.
      rules_invoke_all('mymodule_processing_failed', $e->getMessage());
  }
}


/**
 * Implements hook_default_rules_configuration().
 */
function mymodle_default_rules_configuration() {
  $items = array();

  $items['rules_processing_failed'] = entity_import('rules_config', '{ "rules_processing_failed" : {
      "LABEL" : "React to processing fail",
      "PLUGIN" : "reaction rule",
      "TAGS" : [ "mymodule" ],
      "REQUIRES" : [ "rules", "mymodule" ],
      "ON" : [ "mymodule_processing_failed" ],
      "IF" : [ { "NOT data_is_empty" : { "data" : [ "error-message" ] } } ],
      "DO" : [
        { "mail" : {
            "to" : "me@example.com",
            "subject" : "Failed processing",
            "message" : "Processing failed.  ... some other information ... The error was: [error-message]",
            "language" : [ "" ]
          }
        }
      ]
    }
  }');

  return $items;
}

What goes into mymodle_default_rules_configuration DO->mail->message? As it is the tag [error-message] is not replaced by the actual error message.

Thanks!
John

Comments

aidanlis’s picture

I've been trying to work out how this is possible too.

aidanlis’s picture

This is how I did it.

First, we create a token:

/**
 * Implements hook_token_info().
 */
function commerce_fulfilment_oms_token_info() {
  $order['tracking-url'] = array(
    'name' => t("Tracking URL"),
    'description' => t("The order tracking URL."),
  );

  return array(
    'tokens' => array('commerce-order' => $order),
  );
}


/**
 * Implements hook_tokens().
 */
function commerce_fulfilment_oms_tokens($type, $tokens, array $data = array(), array $options = array()) {
  $replacements = array();

  if ($type == 'commerce-order' && !empty($data['commerce-order'])) {
    $order = $data['commerce-order'];

    foreach ($tokens as $name => $original) {
      switch ($name) {
        // Simple key values on the order.
        case 'tracking-url':
          $replacements[$original] = $order->tracking_url;
          break;
        }
    }
  }

  return $replacements;
}

Then, just before we fire the event, we set the value that we want to be available:

      $order->tracking_url = $tracking_url; // Wasn't able to find a better way to do this.
      rules_invoke_event('commerce_fulfilment_oms_rules_orderfulfiled_event', $order);

This provides a neat solution, although the tracking-url token won't be accessible unless it was invoked by your event. The work arounds for that are simple enough.

vomitHatSteve’s picture

Hi aidanlis, Could you go into a bit more detail? Maybe post a more generic version of your code or something customized to match Ceng's original example? I'm trying to do something similar but not quite getting it working yet.

Thanks!

aidanlis’s picture

@vomitHatSteve, I think the example I posted is pretty self explanatory, what part are you having trouble with?

vomitHatSteve’s picture

The OP's question was asking how to add a single text field to an action, while yours appears to be modifying a commerce-order object to add a text field to that (within an action), @aidanlis. I'm having trouble mapping elements of your solution back onto @ceng's question.

It seems like the default behavior if you implement hook_rules_event_info to create an event that passes simple variables is that the variables are only visible to actions in "data select" mode and not "direct input" mode. Strangely, complex variables like nodes and users are visible to both.

aidanlis’s picture

@vomitHatSteve, you're not understanding the OPs original question then, it's nothing about adding a text field.

vomitHatSteve’s picture

Sorry. "string parameter" would probably have been a better word choice than "text field".

His string parameter is not available as a replacement pattern to the rule action in direct input mode.

aidanlis’s picture

Right ... so the way I did it was creating a token (hook_token_info, hook_tokens), which then accesses a property on the object being passed. The property is set before the event is triggered. It's a hack, but it works and is a simple enough approach to not cause any heartache.

aidanlis’s picture

Issue summary: View changes

reworded for gramatical error

TR’s picture

Version: 7.x-2.1 » 7.x-2.x-dev
Status: Active » Fixed

Well I don't know what the problem was - this works just fine, at least in the current version of Rules. You don't need to implement hook_tokens() or anything else to get it to work. If an event passes a text parameter, that text parameter shows up in the "Replacement patterns" and you can use it in your conditions and actions in both direct input mode and data selector mode. I replicated the original poster's event and rule, and this is the export of my working Rule. The only differences I see are the ON term in my rule shows a ": []" after the event name, and the token in the "message" is [error-message:value] instead of the original [error-message]

{ "rules_processing_failed" : {
    "LABEL" : "React to processing fail",
    "PLUGIN" : "reaction rule",
    "TAGS" : [ "mymodule" ],
    "REQUIRES" : [ "rules", "mymodule" ],
    "ON" : { "mymodule_processing_failed" : [] },
    "IF" : [ { "NOT data_is_empty" : { "data" : [ "error-message" ] } } ],
    "DO" : [
      { "mail" : {
          "to" : "rme@example.com",
          "subject" : "Failed processing",
          "message" : "Processing failed.  ... some other information ... The error was: [error-message:value]",
          "language" : [ "" ]
        }
      }
    ]
  }
}

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

TR’s picture