Change drupal_alter() to use only one context variable

Created on 1 March 2012, over 13 years ago
Updated 16 May 2025, 23 days ago

First of all I want to state that I can understand the logic behind the 6.x->7.x API change in #593522: Upgrade drupal_alter() β†’ .

However, what is the use of passing three variables by reference, when the documentation says (paraphrased):
"Oh, and if you need more variables, you should make the last one an associative array with passed-by-reference values."

If you're going to use that logic anyway, why not change the function to:

  function drupal_alter($type, &$data, $context) {
    // Same logic, only pass just one context
  }

Note: As part of this suggestion, I changed the context variable to no longer be passed by reference. If you want to pass something by reference, you could use the array technique currently described in the docs for $context2.

Reasoning behind this change is that if you want to allow a certain variable to be altered by other modules, based on a certain context, you may not want that context to be alterable as well. By changing $context to a not-passed-by-reference value, you give people the choice.

So in short:

  1. What this issue is about: 2 similar variables that could be replaced by just one
  2. What this issue further suggests: make the $context parameter optionally passed by reference, not forced
✨ Feature request
Status

Postponed: needs info

Version

11.0 πŸ”₯

Component

base system

Created by

πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

Live updates comments and jobs are added and updated live.
  • stale-issue-cleanup

    To track issues in the developing policy for closing stale issues, [Policy, no patch] closing older issues

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Thank you for sharing your idea for improving Drupal.

    We are working to decide if this proposal meets the Criteria for evaluating proposed changes. There hasn't been any discussion here for over 8 years which suggests that this has either been implemented or there is no community support. Your thoughts on this will allow a decision to be made.

    Since we need more information to move forward with this issue, the status is now Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.

    Thanks!

  • πŸ‡ΊπŸ‡ΈUnited States nicxvan
  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    Well the issue still persists.

    We are allowing people to call ModuleHandlerInterface::alter() with any number of unspecified variables. This in itself is a code smell, but for the sake of argument let's assume we want to go with the original proposal. We'd have to reduce the amount of extra parameters to 1, typehint it as an array and release a CR detailing this BC break.

    That said, I'm not a fan at all of jamming all data we need to pass into a magic array either. A better way would be to find a way to be able to call specific (alter) hooks and know what these hooks' signature is. So perhaps in the future we could do something like this instead:

    
    class MyModuleApi {
    
      /**
       * Full hook information goes here, like it would in *.api.php
       *
       * @param $arg1
       * @param $arg2
       * @param $arg3
       *
       * @return void
       */
      public static function myAmazingHook($arg1, &$arg2, $arg3): void {
        \Drupal::moduleHandler()->invokeAll('my_amazing_hook', func_get_args());
      }
    
    }
    

    So rather than call module handler's invoke(), invokeAll(), alter(), etc. we would make those functions only to be called by these MyModuleApi classes. People who'd want to invoke a specific hook would now call MyModuleApi::myAmazingHook(1, 2, 3) instead.

    This would make it so the public API has all the right type-hints and reference handles, but the internal API, i.e.: ModuleHandler, can still accept any number of arguments and loop over all hook implementations, passing said arguments along. IIRC, func_get_args() should be able to keep references on those parameters that were passed by reference. We could probably pull this off with minimal BC break too, given how we can reuse most ModuleHandler methods as is, just troublemakers like alter() would need to have an updated signature.

    If there is no support for this in a few months, we can still close this. I just really dislike that we can call any (alter) hook with no real signature. It's served its purpose but we should try to do better in this modern age of php. Also, if you think this goes too far off topic of the original IS, we could close this one and open a new one.

Production build 0.71.5 2024