¿Por qué algunos ganchos no funcionan dentro del contexto de clase?

16

Estoy bastante perplejo con este. Estoy usando add_action dentro de mi clase de complemento para hacer ciertas cosas: agregar scripts y estilos a la cabeza, wp_ajax, etc. Aquí están las acciones, en la construcción __:

function __construct(){
    add_action('admin_menu', array($this, 'sph_admin_menu'));
    add_action('sph_header', array($this, 'sph_callback'));
    add_action('sph_header_items', array($this, 'sph_default_menu'), 1);
    add_action('sph_header_items', array($this, 'sph_searchform'), 2);
    add_action('sph_header_items', array($this, 'sph_social'), 3);

    //Below here they don't work. I have to call these outside of the class (but I need class variables within the functions)
    add_action('wp_print_styles', array(&$this, 'sph_stylesheets'));
    add_action('wp_print_scripts', array(&$this, 'sph_scripts'));
    add_action( 'wp_ajax_nopriv_add_to_list', array(&$this, 'le_add_to_list'));
    add_action( 'wp_ajax_add_to_list', array(&$this, 'le_add_to_list'));
    add_action('init', array(&$this, 'register_menu'));
}

¿Alguien ha encontrado algo como esto? Realmente me gustaría saber cómo usar dichos ganchos desde dentro de una clase, ¡es muy complicado tener acciones fuera de la clase!

Harley
fuente
3
¿Dónde creas una instancia de esta clase? Ej: $my_plugin = new MYClass();ya que he usado estos mismos ganchos desde dentro de una clase sin problemas.
Bainternet
1
Además, asegúrese de que las funciones que sirven como ganchos tengan publicvisibilidad.
Joseph Leedy
Bainternet, sí, lo estoy. @Joseph eso podría ser. puede construir ser público? Saludos
Harley
@Harley: bainternet preguntaba dónde creas una instancia.
Stephen Harris
@Harley si no incluye un modificador de visibilidad, se establece automáticamente en público. Me refería a la función real que realiza cualquier acción que se enganche.
Joseph Leedy

Respuestas:

10

A veces, ciertos ganchos necesitan ser disparados en ciertos momentos. Ejemplo, algunos ganchos necesitan ser disparados en init .

Agregue esto a su __construct()

add_action('init', array(&$this, 'init'));

A continuación, agregue esta función, que contendrá todos los ganchos que deben activarse en init .

public function init(){
    add_action('hook_name', array(&$this, 'your_method_name'));
    add_action('hook_name', array(&$this, 'your_method_name'));
    add_action('hook_name', array(&$this, 'your_method_name'));
    add_action('hook_name', array(&$this, 'your_method_name'));
}

Otro ejemplo:

add_action( 'init', function () {

    add_action( 'hook_name', 'function_name', 10, 3 );
    add_action( 'hook_name', __NAMESPACE__ . '\namespaced_function_name', 10 );
    add_action( 'hook_name', '\specific\namespace\function_name', 5 );

}, 1 );

Querrá leer sobre los ganchos y cuándo se disparan. Para que sepa cuándo y dónde activar sus acciones. Complemento API / Referencia de acción

Michael Ecklund
fuente
3

Esta es una pregunta bastante antigua, pero en caso de que alguien esté buscando una respuesta, tuve un problema similar. Tuve una clase

class Plugin{
  function __construct(){
    add_action('init', array(&$this, 'init'));
  }

  function init(){
    // code...
  }
}

Plugin :: init () nunca fue llamado. Entonces me di cuenta de mi error. Para crear una instancia de la clase, estaba haciendo esto:

if(class_exists('Plugin')){
    add_action("init", "plugin_init");
    function socialsports_init() {
      global $plugin;
      $plugin = new Plugin;
    }
}

Para solucionarlo, acabo de cambiar el código de instanciación a:

if(class_exists('Plugin')){
    add_action("init", "plugin_init");
    function socialsports_init() {
      global $plugin;
      $plugin = new Plugin;
      $plugin->init();
    }
}

La otra opción sería usar un gancho diferente en el constructor:

function __construct(){
  add_action('wp_loaded', array(&$this, 'init'));
}

O un gancho anterior en la instanciación:

add_action("plugins_loaded", "plugin_init");
Jake
fuente