Rules-provided entity variables: Where are my field properties? Rules-provided entity variables: Where are my field properties?

Posted by mradcliffe on 2013.02.19 @ 16:08

Filed under:

At times I am confused by behavior in the powerful Rules module. Sometimes Rules data selectors for entities have their fields listed and sometimes they do not. I did not find documentation about this behavior.

So I dug through code…

I thought that perhaps the following would provide a variable of an entity_type:

  'provides' => array(
    'my_variable' => array(
      'type' => 'my_entity_type',
      'label' => t('My entity type'),
    ),
  ),

However if the entity type provides bundle support, then the bundle must be explicitly defined beforehand. It does not look like it is possible for Rules to dynamically load field properties based on the returned data. This makes sense because without a known bundle, then Rules would need to load all possible fields as possible data selectors. This would be confusing to users when they would try one, and it just wouldn’t work.

I found an example of the peculiar way in which this works in rules/modules/entity.eval.inc:rules_action_entity_create_info_alter(). A rules action info_alter hook is defined in the above documentation page about providing variables. This info_alter hook extends the configuration of the action as defined in rules/modules/entity.rules.inc:rules_entity_action_info().

The alter_info implementation adds an additional parameter for the bundle dynamically based on the entity type, and then tells what bundle to use based on that configuration. The important idea to take away is that you should define a bundle parameter in your action info:

  'bundle' => array(
    'type' => 'my_bundle_entity_type', // see Entity API
    'label' => t('Bundle'),
    'description' => t('Set the bundle'),
  ),

…and then implement an info_alter function for that action that sets the bundle parameter to the provided variable:

function my_module_action_info_alter(&$element_info, RulesAbstractPlugin $element) {
  $element_info['provides']['bundle'] = $element->settings['bundle'];
}

The action just needs to return the entity metadata wrapper of the loaded entity.

Well, you just need to define your variabel like that.

provides’ => array( ‘my_variable’ => array( ‘type’ => ‘my_entity_type’, ‘label’ => t(‘My entity type’), ‘bundle’=> ‘my bundle’, ), ),

and Rules will pick it up.

In the case of the entity-create example shown above things are more complex as the bundle has to be computed based upon the configuration of the action.

As an alternative you can always use the “data comparison” condition to check the bundle property, e.g. node:type, term:vocabulary, .. and fielsd will appear. We’ll also add an entity-is-of-bundle condition to ease that a bit.

Thanks for the tip about the data comparison. My memory is fuzzy, but I haven’t seen as consistent results using that to get the provided wrapper. It probably depends on the entity implementation (or my memory is confused).