bug: #3571915 Filter Field Widget Action automator processing to the selected automator ID
Description
Closes #3571915 (closed).
Field Widget Actions can target a specific automator by ID, but
AiAutomatorEntityModifier::saveEntity() had no way to isolate a single
automator when more than one is configured on the same field (possible by
duplicating an automator config with a different ID suffix — not exposed by
the default UI, but not prevented either). Clicking one Field Widget Action
button would run every automator configured for that field, so two buttons
like Translate and Summarize on the same field would run both, or overwrite
each other's output.
Changes:
AiAutomatorEntityModifier::saveEntity()gains an optional$specificAutomatorIdparameter. When set, processing is filtered to the matching automator config entity ID before any processor runs. This filter must run before the existingusort()call, which reindexes the configs array to sequential integer keys and would otherwise silently defeat a key-based filter.AutomatorFieldWidgetActionTrait::populateAutomatorValues()(used byAutomatorBaseAction) now passes the configuredautomator_idthrough tosaveEntity(), and guards againstsaveEntity()returningNULL(no matching automator) instead of calling a method onNULL.AutomatorRefinableBaseAction::generateContent()had the identical bug in the "refine" feature's content-seeding path (added after this issue was filed) — fixed the same way, with the sameNULLguard.
Testing instructions
- Enable
ai,ai_automators, andfield_widget_actions. - Configure two AI automators for the same field (e.g.
node.article.body) by duplicating an automator config with a different ID suffix. - Add both automators as Field Widget Actions on the form display.
- Edit a node and click one of the automator buttons.
- Expect: only the selected automator runs. Before this fix, all automators configured for that field would run.
Automated coverage: added testSaveEntityFiltersBySpecificAutomatorId() and
testSaveEntityReturnsNullForUnmatchedAutomatorId() to
TextToImageMediaFieldWidgetProcessingTest. The first creates two automators
on the same field — the second deliberately misconfigured with a nonexistent
rule ID, which fatally errors if ever invoked — and asserts that filtering by
the first automator's ID succeeds without ever touching the second.
Checklist
- I have linked the related issue in the MR title or description
- I have performed a self-review of my own code
- I have added or updated tests, or explained in the description why this change is not covered by tests
- I have updated documentation for any new or changed functionality
- I have written testing instructions and verified them locally
- I have noted any required post-merge steps (config imports, cache rebuilds, manual changes)
- This MR contains no breaking API or hook changes, or they are explicitly documented in the description
saveEntity()'s new parameter is optional and appended last, so no existing
call site needs to change.
AI Compliance
Note
- AI Generated Code
Mainly generated by AI, reviewed and approved by a human before this MR was created.