it-swarm-es.com

¿Hay alguna forma de alterar la implementación de un gancho proporcionado por un módulo de terceros o un módulo principal?

Tengo un módulo que debería reemplazar la implementación de un gancho realizado por otro módulo.
¿Es posible hacerlo, con Drupal 7? Si es posible, ¿bajo qué condiciones es posible?

Por reemplazando la implementación de un gancho hecho por otro módulo, me refiero a usar una función que es llamada automáticamente por Drupal cuando ese módulo está habilitado. Por ejemplo, si el El módulo de encuesta está habilitado, entonces Drupal debe llamar a poll_user_restriction_info() o poll_metatags_info() (donde hook_user_restriction_info() y hook_metatags_info() son ganchos personalizados utilizados por mi módulo) función presente en mis archivos de módulo.
Podría usar una función en mi módulo que cargue algunos archivos de inclusión desde el directorio de mi módulo (por ejemplo, poll_custom_hooks.inc) basándose en los módulos habilitados, pero estoy buscando un sistema que permita Drupal para cargar automáticamente dichos archivos.

4
kiamlaluno

Solo es posible cuando el módulo está implementando el gancho en un archivo que no es el archivo del módulo, y el módulo que quiere anular esa implementación del gancho lo está implementando en su archivo de módulo. En este caso, es posible implementar hook_module_implements_alter () para informar a Drupal que la implementación del gancho no está contenida en un archivo externo (es decir, la implementación del gancho es contenido en el archivo del módulo).

function mymodule_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'token_info') {
    $implementations['poll']['group'] = FALSE;
  }
}

En el caso de que el módulo para el cual se sobrescriba la implementación del gancho lo implemente en el archivo del módulo, entonces es imposible hacer nada sin alterar los archivos usados ​​por ese módulo, o agregar un nuevo archivo en el directorio que contiene el módulo que necesita ser "sobrescrito". La razón es que:

  • module_hook () , la función llamada desde module_invoke () está usando el siguiente código.

    function module_hook($module, $hook) {
      $function = $module . '_' . $hook;
      if (function_exists($function)) {
        return TRUE;
      }
    
      // If the hook implementation does not exist, check whether it may live in an
      // optional include file registered via hook_hook_info().
      $hook_info = module_hook_info();
      if (isset($hook_info[$hook]['group'])) {
        module_load_include('inc', $module, $module . '.' . $hook_info[$hook]['group']);
        if (function_exists($function)) {
          return TRUE;
        }
      }
      // ...
    }
    

    Este código llama a module_hook_info() solo cuando la implementación del gancho no está en un archivo ya cargado desde Drupal, por ejemplo, el archivo del módulo. Dado que hook_module_implements_alter() es invocada por module_hook_info(), esto significa que en este caso mi implementación de hook_module_implements_alter() no sería invocada.

  • module_implements() , la función llamada por module_invoke_all() ejecuta el siguiente código.

    foreach ($list as $module) {
      $include_file = isset($hook_info[$hook]['group']) && module_load_include('inc', $module, $module . '.' . $hook_info[$hook]['group']);
      // Since module_hook() may needlessly try to load the include file again,
      // function_exists() is used directly here.
      if (function_exists($module . '_' . $hook)) {
        $implementations[$hook][$module] = $include_file ? $hook_info[$hook]['group'] : FALSE;
      }
      // ...
    }
    

    El código busca el archivo para cargar en el directorio que contiene el módulo que implementa el gancho. Mi código no puede decir Drupal dónde buscar el archivo que contiene el gancho, por lo que podría ponerlo en un archivo Drupal se carga automáticamente, como el módulo archivo de mi módulo.

Anular un enlace de módulo implementado en un archivo de módulo con una función implementada en otro archivo de módulo no funciona, ya que PHP se quejaría de una función definida dos veces.

5
kiamlaluno

Puede usar hook_module_implements_alter () para modificar la lista de módulos que implementan un gancho dado. Así que simplemente implemente el gancho en su módulo también y luego elimine el del módulo que desea reemplazar.

Tenga en cuenta que este gancho debe usarse con mucho cuidado, puede hacer cosas realmente extrañas con él que harán que sea muy difícil de mantener y comprender, entre otras cosas .

7
Berdir