Exposing custom data to Rules
This documentation needs work. See "Help improve this page" in the sidebar.
Supported data types
The list of data types supported is:
Primitive types
- any
- binary
- boolean
- float
- integer
- string
- uri
- timestamp
- datetime_iso8601
- duration_iso8601
Complex types
- list
- map
drush php-eval "foreach (\Drupal::service('typed_data_manager')->getDefinitions() as \$plugin) {print_r(\$plugin['class'] . \"\n\");}"
Providing new entities and data types
Just as existing data types can be altered, new ones can be added. This is done by implementing hook_rules_data_info(). An example of this is displayed below, where views are being introduced as a data type in Rules.
function mymodule_rules_data_info() {
$data_types = array(
'mymodule_view' => array(
'label' => t('view object'),
'wrap' => TRUE,
'property info' => array(
'machine_name' => array(
'type' => 'text',
'label' => t('Machine name'),
),
'args' => array(
'type' => 'list<text>',
'label' => t('Arguments'),
'setter callback' => 'entity_property_verbatim_set',
),
),
),
);
}Especially note the wrap property, which makes Rules wrap the passed object and make it available for data selection. It is required for any complex data type. Two properties are declared in the property info array, which will make it possible to read these properties in Rules. Also, the args property has a setter callback – meaning that Rules cannot only read but also write the arguments of the view object.
It so happens that the properties’ machine names correspond directly to properties in the view object. If this wasn’t the case, a getter callback would have been required to tell Rules how to read the property, just as it works for entity properties. Now the default callback entity_property_verbatim_get() is used, which like its setter sibling simply writes to the data object using the declared machine name as property name.
New entity types are declared using hook_entity_info(). Its usage is not documented here, but if your entities are declared properly for the Entity API modules, Rules will know about them too.
Non-entity data structures & Entities
Any Drupal module can integrate with Rules by providing new entity types and entity metadata by using the Entity API to describe entity properties or directly by using non-entity data structures. Rules core builds heavily on the data types provided by the Entity API, however it is possible to add support for data structures which are not entities.
Additional data types are registered using hook_rules_data_info(), similar to the definition of "entity" type. This allows Rules to work with variables contained by any data or entity type and integrate at the most direct level. With this hook, you may also define the 'parent' type of a data type, that Rules makes use of for type-matching only. E.g. this is used to make it possible to apply an action working with an "entity" parameter to a node variable. However these data types are not available in Direct Input mode.
The example below uses Rules without Entity API to provide support for watchdog log entries. Property metadata needs to be specified, and a direct input form may be specified.
/**
* Implements hook_rules_data_info() on behalf of the system module.
* @see rules_core_modules()
*/
function rules_system_data_info() {
return array(
'log_entry' => array(
'label' => t('watchdog log entry'),
'wrap' => TRUE,
'property info' => _rules_system_watchdog_log_entry_info(),
),
);
}
/**
* Defines property info for watchdog log entries, used by the log entry data
* type to provide an useful metadata wrapper.
*/
function _rules_system_watchdog_log_entry_info() {
return array(
'type' => array(
'type' => 'text',
'label' => t('The category to which this message belongs'),
),
'message' => array(
'type' => 'text',
'label' => t('Log message'),
'getter callback' => 'rules_system_log_get_message',
'sanitized' => TRUE,
),
'severity' => array(
'type' => 'integer',
'label' => t('Severity'),
'options list' => 'watchdog_severity_levels',
),
'request_uri' => array(
'type' => 'uri',
'label' => t('Request uri'),
),
'link' => array(
'type' => 'text',
'label' => t('An associated, HTML formatted link'),
),
);
}
Token replacement in Rules is handled by token_generate(). To make additional data type properties available for replacement in Rules Actions, you must implement hook_tokens(). Here is an example:
/**
* Implements hook_tokens().
*/
function mydata_tokens($type, $tokens, array $data = array(), array $options = array()) {
if ($type == 'mydata') {
if(isset($data['mydata'])) {
$replacements = array();
$mydata = $data['mydata'];
foreach ($tokens as $name => $original) {
switch ($name) {
case 'name':
$replacements[$original] = $mydata['name'];
break;
case 'address':
$replacements[$original] = $mydata['address'];
break;
}
}
return $replacements;
}
}
}
I don't find any information about how replace hook_rules_data_info. It might be obvious, but please point me in the right direction and consider adding this info to the docs. I'm not skilled enough myself to update the docs.
In Drupal 7 I just had:
[...]
'property info' => array(
'uid' => array(
'type' => 'integer',
'label' => t('User ID'),
),
'timestamp' => array(
'type' => 'integer',
'label' => t('Timestamp'),
),
'name' => array(
'type' => 'text',
'label' => t('Name'),
)
);How do you properly define the samething? As a subclass of \Drupal\Core\TypedData\Plugin\DataType\Map? How?
Yes, that's now covered by the Typed Data API. Thus, you'd define a new data type using typed data. You can then use it in Rules. For structures like that, you'd need to define a complex data type, i.e. you can extend from the Map base class in the ComplexDataDefinition base class. The definition class needs to be used for defining the structure, for the actual instance class you can use whatever fits your use case. Could be that Map is already perfectly fine for your use case.
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion