Last updated March 16, 2012. Created by fago on August 10, 2010.
Edited by August1914, Paul Simard. Log in to edit this page.

When providing an action, you need to declare all parameters needed in hook_rules_action_info(). Consider the action to add or remove user roles, which needs the user account object as well as the roles to add or remove as parameter. Roles are represented by their ids (integer), thus the data type for the parameter containing multiple roles is list<integer>. For the user to be able to easily select the roles, an 'options list' callback is specified.

Then the action execution callback gets the parameters passed as defined - regardless of whether the user provided the roles via the direct input form using the options list, or selected a compatible data source like the user roles of another user.

<?php
/**
* Implements hook_rules_action_info() on behalf of the user module.
*/
function rules_user_action_info() {
 
$defaults = array(
  
'parameter' => array(
     
'account' => array(
       
'type' => 'user',
       
'label' => t('User'),
       
'description' => t('The user whose roles should be changed.'),
       
'save' => TRUE,
      ),
     
'roles' => array(
       
'type' => 'list<integer>',
       
'label' => t('Roles'),
       
'options list' => 'entity_metadata_user_roles',
      ),
    ),
   
'group' => t('User'),
   
'access callback' => 'rules_user_role_change_access',
  );
 
$items['user_add_role'] = $defaults + array(
   
'label' => t('Add user role'),
   
'base' => 'rules_action_user_add_role',
  );
 
$items['user_remove_role'] = $defaults + array(
   
'label' => t('Remove user role'),
   
'base' => 'rules_action_user_remove_role',
  );
  return
$items;
}
/**
* Action: Adds roles to a particular user.
*/
function rules_action_user_add_role($account, $roles) {
  if (
$account->uid) {
   
// Get role list (minus the anonymous)
   
$role_list = user_roles(TRUE);
    foreach (
$roles as $rid) {
     
$account->roles[$rid] = $role_list[$rid];
    }
  }
  else {
    return
FALSE;
  }
}
?>

Note that you may also implement the ACTION_form_alter($form, $form_state) callback for customizing the form, but be aware that only the settings of declared parameters will be saved. Then any necessary validation logic should reside in ACTION_validate($element), as that way the settings (accessed via $element->settings) can be validated independently of a form submission. In order to prepare the action settings for evaluation, implement the ACTION_process($element) callback.

Altering action info

If the configuration of the action requires the action info to be updated/altered, you can implement the 'info_alter' callback. This callback can be used to alter the action information dependent on the configuration settings.
Note: in case the altered action info would lead to changes to the generated configuration form, you need to take care of re-loading the form whenever necessary (via AJAX or not). E.g. the entity_create action configuration form looks different depending on the entity type, which is chosen in the first step. The 'info alter' callback is used to properly update the action's parameter information that lets Rules generate the remaining part of the configuration form. So the 'form alter' callback is used to reload the form every time the entity type changes, so that the user gets the updated configuration form.

For an 'info alter' example this or study the examples provided by Rules in modules/data.rules.inc).

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

Here is how you would implement the validate hook:

<?php
rules_action_user_add_role_validate
($element) {
  if (empty(
$element->settings['roles'])) {
    throw new
RulesIntegrityException(t('Please select at least one role.'), array($element, 'parameter', 'roles'));
  }
}
?>