This originates from #3636853: Provide a CAPTCHA integration point for (anonymous) flagging and unflagging
Problem/Motivation
The logic that picks the CAPTCHA point for a form lives inline in captcha_form_alter(): the point for the form ID, then the base form ID if that point is missing or disabled, then a point built on the fly when "enable globally" is set, plus the "skip CAPTCHA" permission check.
Other modules sometimes need this answer before a form is built, to decide whether to show it at all. Example: Flag (#3636853) sends users to a confirm form, or opens it in a modal, only when a CAPTCHA would be shown there, and keeps one-click links for everyone else. Today such modules have to copy the lookup and can drift from CAPTCHA's behaviour.
A related point: CaptchaPoint declares list_cache_tags = ['rendered'], so saving any point clears the entire render cache. Callers that cache their decision can't use a narrower tag.
Proposed resolution
- Move the lookup into a service method on
captcha.helper, for example:
getCaptchaPointForForm(string $form_id, ?string $base_form_id = NULL, ?AccountInterface $account = NULL, ?RefinableCacheableDependencyInterface $cacheability = NULL): ?CaptchaPointInterface
It would return the enabled point that applies, or NULL, and add the cacheability metadata it depends on:user.permissions, the point list tag andcaptcha.settings. - Use it from
captcha_form_alter(), so there is one source of truth. - Optionally, decide whether the IP whitelist and the admin-route condition for "enable globally" belong in the method or stay in the form alter. They depend on the request, not only on the form.
- Optionally, in a separate follow-up: use the default
config:captcha_point_listcache tag instead ofrendered.
Remaining tasks
- Agree on the method signature.
- Implement it and refactor
captcha_form_alter()to use it. - Add kernel tests for the lookup order (form ID, base form ID, disabled points, enable globally, skip permission).
API changes
A new public method on the CAPTCHA helper service. No behaviour change.
Issue fork captcha-3636870
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
anybodyComment #3
anybodyMR drafted using AI (Claude Opus)
Comment #5
anybodyDoesn't look bad and also starts cleaning up the large .module file already by splitting this into a service. So I'd say this could be a win-win.
If other maintainers agree with that general approach, I'd proceed here and review it more in detail. Thanks!!