Add Support for OOP hooks

Created on 12 August 2025, about 1 month ago

Problem/Motivation

In a D11 site here hooks have been converted to OOP implementation, we are getting the following error:

Call to undefined function indiecommerce_blog_scheduler_node_publish_process()

The error is legit, because the function does not exist. However, we have the following code in our Hooks class:

  /**
   * Implements hook_scheduler_ENTITY_TYPE_publish_process() for node.
   */
  #[Hook('scheduler_node_publish_process')]
  public function nodePublishProcess(NodeInterface $node): int {
    [..]
  }

Schedule module is capable to discover the hook implementation, however, it tries to execute the procedural hook instead of the implemented OOP version.

Steps to reproduce

Install a D11 site with Scheduler
Implemnt Scheduler hooks in OOP
Confirm that unexpected missing function errors are thrown

Proposed resolution

Fix it!

Remaining tasks

User interface changes

API changes

Data model changes

🐛 Bug report
Status

Active

Version

2.2

Component

Code

Created by

🇪🇸Spain plopesc Valladolid

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @plopesc
  • Merge request !250Issue #3540892: Add Support for OOP hooks → (Open) created by plopesc
  • 🇪🇸Spain plopesc Valladolid

    Created MR that allows to execute both OOP and traditional procedural hooks.

  • Pipeline finished with Success
    about 1 month ago
    #570815
  • 🇬🇧United Kingdom jonathan1055

    Hi plopesc,
    Thanks for raising this issue and for creating the MR. Yes this looks a good thing to do. Can you give a link to the documentation/explanation of how the OOP hooks work in Drupal, and in particular, why the line you changed

    $all_hook_implementations[] = $module . "_" . $hookName; 
    

    no longer needs the $module name?

    We also would need test coverage for this new feature, but I can look at that if you like.

  • 🇪🇸Spain plopesc Valladolid

    @jonathan1055 Thank you for taking a look into this.

    It is not necessary to custom build the callable string concatenating the $module and the $hookName variables when we already have the $hook variable that does it for you.

    Example for procedural hooks:

    • $module = 'my_module'
    • $hookName = 'hook'
    • $hook = '\my_module_hook'
    • $module . "_" . $hookName = 'my_module_hook'

    There is no difference and hook is invoked because the custom variable represents the same function as $hook.

    Example for OOP hooks:

    • $module = 'my_module'
    • $hookName = 'hook'
    • $hook = [
      '\Drupal\my_module\Hook\MyModuleHooks',
    • 'hook',

      ]

    • $module . "_" . $hookName = 'my_module_hook'

    The custom variable points to an undefined function instead of the actual method that implements the hook.

  • 🇬🇧United Kingdom jonathan1055

    Thanks. I have also added a link to the core change record.

    I will add test coverage for this too, before merging.

    Also in the long term, it might be good to look at convertiing Scheduler's own hook implementations into OOP hooks, but that's for later.

Production build 0.71.5 2024