Problem/Motivation

Right now there are various places that allow developers to specify a some kind of callback or method as part of defining some behaviour. A few examples are:

  • The options module allowed_values_function
  • FieldConfigInterface::setDefaultValueCallback
  • The routing system:
    • The controller callback of a route
    • The optional title callback of a route
  • Various parts of Form and Render API:
    • #process
    • #after_build
    • #pre_render
    • #lazy_builder

There are a bunch of ways to capture a callback and invoke it. A few are:

  • Using plain $method() (doesn't support static methods)
  • Using call_user_func (doesn't support service notation for values such as current_user:id)
  • Using the controller_resolver service, to support functions, static methods and service notation)

Proposed resolution

  1. #2982949: Introduce CallableResolver to help standardise the DX and error handling for callbacks across various subsystems
  2. Integrate the the new CallbackResolver as named here into various subsystems that might need it

Remaining tasks

User interface changes

API changes

Data model changes

Comments

Sam152 created an issue. See original summary.

sam152’s picture

Issue summary: View changes
joachim’s picture

One of the problems we face in unifying this is that different places use 'ThisClass::thisMethod' to mean different things.

In FieldConfigInterface::setDefaultValueCallback(), a value of 'ThisClass::thisMethod' simply is a PHP callable, representing a static call to thisMethod() on the class ThisClass.

However, in the routing system, putting 'ThisClass::thisMethod' as the controller for a route will cause ControllerResolver to use the DI ClassResolver to instantiate ThisClass, and call thisMethod() on the instance:

  protected function createController($controller) {
    // Controller in the service:method notation.
    $count = substr_count($controller, ':');
    if ($count == 1) {
      list($class_or_service, $method) = explode(':', $controller, 2);
    }
    // Controller in the class::method notation.
    elseif (strpos($controller, '::') !== FALSE) {
      list($class_or_service, $method) = explode('::', $controller, 2);
    }
    else {
      throw new \LogicException(sprintf('Unable to parse the controller name "%s".', $controller));
    }

    $controller = $this->classResolver->getInstanceFromDefinition($class_or_service);

So given that, I think our new CallbackResolver will need two public methods, one for each behaviour: resolveCallbackWithStatic(), and resolveCallbackWithInstantiation()

sam152’s picture

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

sam152’s picture

joachim’s picture

Issue summary: View changes
joachim’s picture

Issue summary: View changes
joachim’s picture

Issue summary: View changes

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.