Summary

Convert all procedural hook implementations in term_glossary.module and term_glossary_per_node.module to OOP classes using #[Hook] attributes (introduced in Drupal 10.3).

This also drops Drupal 9 support by bumping core_version_requirement from ^9 || ^10 || ^11 to ^10 || ^11 in all 4 info.yml files.

Scope

term_glossary.module — 5 hooks + 1 private helper:

  • hook_help
  • hook_theme
  • hook_field_formatter_third_party_settings_form
  • hook_field_formatter_settings_summary_alter
  • hook_preprocess_field
  • _term_glossary_check_formatter() helper → private method

term_glossary_per_node.module — 5 hooks + 2 helpers:

  • hook_help
  • hook_entity_bundle_field_info
  • hook_form_node_type_form_alter
  • hook_entity_base_field_info
  • hook_form_node_form_alter
  • term_glossary_per_node_form_node_type_form_builder() entity builder → private method
  • _term_glossary_per_node_node_validate_handler() validation handler → private method

4 info.yml files:

  • term_glossary.info.yml
  • term_glossary_per_node.info.yml
  • term_glossary_abbr.info.yml
  • term_glossary_tippy.info.yml

Approach

  • Create src/Hook/TermGlossaryHooks.php and modules/term_glossary_per_node/src/Hook/TermGlossaryPerNodeHooks.php
  • Inject services via constructor (e.g. term_glossary.manager, renderer, entity_type.manager, current_user)
  • Keep .module files with #[LegacyHook] delegating to hook classes for Drupal 10.x backward compatibility
  • Entity builder and validation handler callbacks become private methods on the hook class, referenced as [$this, 'method'] in form alter
Command icon 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

mably created an issue. See original summary.

mably’s picture

Status: Active » Needs review

OOP hooks conversion

Converted all procedural hooks in term_glossary and term_glossary_per_node to OOP classes using #[Hook] attributes, with #[LegacyHook] delegations in the .module files for Drupal 10.x backward compatibility. Dropped Drupal 9 support (core_version_requirement bumped to ^10.3 || ^11).

New files

src/Hook/TermGlossaryHooks.php — main module hook class with constructor-injected TermGlossaryManagerInterface and RendererInterface. Hooks converted:

  • hook_help
  • hook_theme
  • hook_field_formatter_third_party_settings_form
  • hook_field_formatter_settings_summary_alter
  • hook_preprocess_field

The old _term_glossary_check_formatter() helper becomes a private method on the class.

modules/term_glossary_per_node/src/Hook/TermGlossaryPerNodeHooks.php — submodule hook class with constructor-injected EntityTypeManagerInterface and AccountProxyInterface. Hooks converted:

  • hook_help
  • hook_entity_bundle_field_info
  • hook_form_node_type_form_alter
  • hook_entity_base_field_info
  • hook_form_node_form_alter

The old procedural callbacks (form_builder, validate_handler) become public methods on the class (required because they are referenced as [$this, 'method'] callables).

Modified files

  • term_glossary.module — rewritten to #[LegacyHook] stubs delegating to TermGlossaryHooks.
  • modules/term_glossary_per_node/term_glossary_per_node.module — same pattern, delegating to TermGlossaryPerNodeHooks.
  • term_glossary.services.yml — added interface alias (TermGlossaryManagerInterface: '@term_glossary.manager') so autowiring can resolve the dependency, and explicit registration of TermGlossaryHooks for Drupal 10.x compatibility (on 11.x, HookCollectorPass auto-registers it but the manual entry is harmless).
  • 4 *.info.yml files — core_version_requirement changed from ^9 || ^10 || ^11 to ^10.3 || ^11 (main module + 3 submodules).

New file

modules/term_glossary_per_node/term_glossary_per_node.services.yml — registers TermGlossaryPerNodeHooks with autowire: true for Drupal 10.x compatibility.

Unit tests

tests/src/Unit/Hook/TermGlossaryHooksTest.php — 6 tests, 20 assertions covering TermGlossaryHooks:

  • fieldFormatterThirdPartySettingsForm — compatible formatter (text_default) delegates to the manager service; incompatible formatter returns an empty array and the manager is never called.
  • fieldFormatterSettingsSummaryAlter — enabled glossary with an array of vocabularies adds "Term glossary enabled." + "Vocabularies: …" entries; scalar vocabulary string takes the else branch and adds "Vocabulary: …".
  • preprocessField — incompatible formatter short-circuits before getHandler(); full happy path verifies markup replacement, cache tag merging (config + taxonomy term tags), and library attachment.

Dependencies (TermGlossaryManagerInterface, RendererInterface) are mocked — pure unit tests with no Drupal bootstrap.

  • mably committed b3b4b233 on 4.x
    task: #3576064 Convert procedural hooks to OOP #[Hook] attributes, drop...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.