Modules providing ECA events, conditions, or actions must provide a resolvable configuration schema for every plugin ID, including derivatives. Undefined schemas leave configuration undescribed, unvalidated, and vulnerable to incorrect scalar casting during storage.
Required schema names
| Plugin type | Schema name |
|---|---|
| Event | eca.event.plugin.<plugin_id> |
| Condition | eca.condition.plugin.<plugin_id> |
| Action | action.configuration.<plugin_id> |
Event schemas should inherit eca.event.plugin. Condition schemas should inherit eca.condition.plugin, which supplies the common negate property. Action schemas use Drupal's established action.configuration.* namespace.
Even plugins without settings need a concrete, resolvable schema. Every key returned by defaultConfiguration(), accepted by the configuration form, or persisted by submitConfigurationForm() should be represented.
eca.event.plugin.my_module:changed: type: eca.event.plugin label: 'My module: changed' mapping: entity_type: type: string label: 'Entity type' eca.condition.plugin.my_module_value: type: eca.condition.plugin label: 'My module value' mapping: expected: type: string label: 'Expected value' action.configuration.my_module_notify: type: mapping label: 'My module notification' mapping: message: type: text label: 'Message'
Derivative wildcards are acceptable when all derivatives share one configuration shape, but every concrete derivative ID must resolve. Test IDs containing punctuation such as colons or dots.
Event plugin IDs are not event configuration
The base eca.event.plugin schema no longer declares an id property. The plugin ID already lives in the model's outer events.*.plugin value. Do not add id to defaults, forms, or schemas solely to identify the plugin. Declare it only when it is an independent setting used by the plugin.
Use EcaChoice for token-enabled selects
A select marked with '#eca_token_select_option' => TRUE can store _eca_token and, when not required, an empty string. Drupal's normal Choice constraint rejects those values. Use EcaChoice only for these fields:
constraints: EcaChoice: choices: - append - prepend
Callbacks are supported through EcaChoice.callback. Add NotBlank: [] for required elements. requiredKey only requires the mapping key; it does not make the value non-empty. Ordinary selects should retain the normal Choice constraint.
Numeric settings that accept tokens
Plain integer, float, or weight typed configuration can cast token expressions incorrectly. For example, a tokenized weight may become integer 0. Plugin modules should continue declaring the semantic Drupal type:
delay: type: integer weight: type: weight ratio: type: float
ECA alters discovered plugin schemas so integer and weight become eca_integer_or_token, and float becomes eca_float_or_token. This preserves numeric values, token expressions, and _eca_token across configuration storage.
For inherited fields, ECA traverses only shared base schema types whose names begin with eca. Therefore, ECA-specific shared types containing token-capable numeric fields must use an eca...-prefixed name. Do not inherit those fields from generic schema types shared with non-ECA configuration.
Shared schema types
Only plugins that genuinely share configuration should inherit a common schema. Avoid broad inheritance merely to reduce duplication because it can expose unrelated plugins to keys they neither display nor consume.
Recommended tests
- Verify every event, condition, and action definition resolves through
config.typedand is notundefined. - Verify every configuration form builds successfully.
- Verify token-enabled selects accept
_eca_token. - Verify optional token-enabled selects accept an empty string.
- Verify required token-enabled selects reject an empty string through
NotBlank. - Verify tokenized numeric values survive an ECA configuration-entity save and reload round trip.
- Verify ordinary numeric values remain numeric.
Rebuild Drupal caches after schema changes because typed configuration definitions are cached.
Why this matters
Complete schemas provide validation and type checking, prevent destructive scalar casting, support token-select sentinel values, and expose plugin definitions to ECA's catalog and documentation tooling.