depuración register_activation_hook ()

2

Tengo curiosidad por saber si hay un problema conocido con WordPress o PHP donde el entorno puede degradarse a un punto en el que WordPress simplemente ignora las llamadas a register_activation_hook (). Estuve quitándome el pelo durante una hora en mi entorno local ejecutando MAMP cuando hice que un compañero de trabajo probara el código en su máquina; El mismo código exacto funciona en una máquina pero no en la otra.

En este caso, simplemente quería adjuntar mensajes al archivo de registro que estoy siguiendo en tiempo real.

error_log("Plugin code is being processed");

register_activation_hook( __FILE__, 'myplugin_activate' );

function myplugin_activate()
{
    error_log("Attempting to activate");
    die("Should not activate");
}

La salida en mi máquina ejecutando MAMP y haciendo clic en el enlace "Activar" debajo de mi complemento:

[22-Sep-2011 22:37:16] Plugin code is being processed
[22-Sep-2011 22:37:16] Plugin code is being processed
    
pregunta davidfrey 23.09.2011 - 01:02

3 respuestas

2

Después de pensar un poco más, creo que usar una búsqueda de ruta resuelta podría ser más seguro:

function plugin_symlink_path( $file )
{
    // If the file is already in the plugin directory we can save processing time.
    if ( preg_match( '/'.preg_quote( WP_PLUGIN_DIR, '/' ).'/i', $file ) ) return $file;

    // Examine each segment of the path in reverse
    foreach ( array_reverse( explode( '/', $file ) ) as $segment )
    {
        // Rebuild the path starting from the WordPress plugin directory
        // until both resolved paths match.

        $path = rtrim($segment .'/'. $path, '/');       

        if ( __FILE__ == realpath( WP_PLUGIN_DIR . '/' . $path ) )
        {
            return WP_PLUGIN_DIR . '/' . $path;
        }
    }

    // If all else fails, return the original path.
    return $file;
}
    
respondido por el davidfrey 23.09.2011 - 18:51
4

Me siento un poco denso por no darme cuenta de esto antes, pero finalmente me di cuenta de que el directorio de mis complementos en mi computadora es un enlace simbólico a otra ubicación como lo señaló Kunal Bhalla en enlaces simbólicos con complementos WP . Como __FILE__ resuelve enlaces simbólicos, register_activation_hook() está intentando cargar un archivo fuera de la ruta de los complementos de WordPress.

Si observas la función register_activation_hook() en plugin.php, verás que la magia parece suceder en plugin_basename() :

function register_activation_hook($file, $function) {
    $file = plugin_basename($file);
    add_action('activate_' . $file, $function);
}

Un examen más detallado muestra que plugin_basename() está esencialmente realizando un reemplazo de patrón en un intento de convertir una ruta del sistema en my_plugin/my_plugin.php ; sin embargo, dado que str_replace() está usando WP_PLUGIN_DIR como sujeto, cualquier ruta del sistema fuera de ese directorio de complementos de WordPress no generará una coincidencia con la que reemplazar:

function plugin_basename($file) {
    $file = str_replace('\','/',$file); // sanitize for Win32 installs
    $file = preg_replace('|/+|','/', $file); // remove any duplicate slash
    $plugin_dir = str_replace('\','/',WP_PLUGIN_DIR); // sanitize for Win32 installs
    $plugin_dir = preg_replace('|/+|','/', $plugin_dir); // remove any duplicate slash
    $mu_plugin_dir = str_replace('\','/',WPMU_PLUGIN_DIR); // sanitize for Win32 installs
    $mu_plugin_dir = preg_replace('|/+|','/', $mu_plugin_dir); // remove any duplicate slash
    $file = preg_replace('#^' . preg_quote($plugin_dir, '#') . '/|^' . preg_quote($mu_plugin_dir, '#') . '/#','',$file); // get relative path from plugins dir
    $file = trim($file, '/');
    return $file;
}

Este método parece un poco corto, y he encontrado varias soluciones que van desde la definición de constantes adicionales en wp-config.php hasta la codificación de la ruta relativa de su complemento. En su lugar, creo que un mejor método de interferencia podría ser usar el siguiente patrón que define previamente la ruta que plugin_basename() está intentando extraer. Esto se puede usar en lugar de __FILE__ como el primer parámetro de register_activation_hook() .

basename( dirname( __FILE__ ) ).'/'.basename( __FILE__ );

Este método solo funcionará si su complemento tiene su propia carpeta en el directorio wp-content/plugins y se llama desde el archivo del complemento base. Ambas condiciones parecen estar generalmente en control del desarrollador del complemento, aunque tengo curiosidad de que alguien tenga pensamientos opuestos.

Enlaces adicionales:

respondido por el davidfrey 23.09.2011 - 09:09
1

He utilizado este método: inserte el siguiente código en el complemento. Luego activarlo.

function save_error()
{
   file_put_contents(ABSPATH. 'wp-content/plugins/error_activation.html', ob_get_contents());
}
add_action('activated_plugin','save_error');

después de la activación, luego abra yoursite.com/wp-content/plugins/error_activation.html para ver qué errores sucedieron.

    
respondido por el T.Todua 12.09.2013 - 00:26

Lea otras preguntas en las etiquetas