Complementos en directorios enlazados?

20

Cuando desarrollo complementos, los pruebo en varias versiones de WordPress al vincular mi directorio de complementos en los diferentes wp-contentdirectorios. Esto es genial ya que solo tengo que editar los archivos una vez, pero rompe una construcción importante para generar referencias a los recursos en mi complemento: se __FILE__refiere a la ubicación física del complemento, no a la que está dentro wp-content. ¿Cómo debería resolver esto?

La estructura de mi directorio se ve así:

  • /path/to/wordpress/development/dir/
    • plugin-development/
      • monkeyman-rewrite-analyzer/
        • monkeyman-rewrite-analyzer.php
        • js/
          • monkeyman-rewrite-analyzer.js
    • versions/
      • 3.1/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer como un enlace simbólico al complemento anterior
      • 3.1-multi-dir/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer como un enlace simbólico al complemento anterior
      • 3.1-multi-domain/
        • wp-content/
          • plugins/
            • monkeyman-rewrite-analyzer como un enlace simbólico al complemento anterior

Si quiero poner en cola el archivo Javascript, debería usarlo plugins_url( 'monkeyman-rewrite-analyzer.js', [base file] ), pero usarlo __FILE__aquí no funcionará, porque la ruta real del archivo será /path/to/wordpress/development/dir/plugin-development/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.php, no /path/to/wordpress/development/dir/versions/*/wp-content/plugins/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.php, por lo que WordPress no puede quitar la primera parte y generar una URL relativa a la instalación de WordPress.

Jan Fabry
fuente

Respuestas:

6

El problema se puede solucionar parcialmente con un complemento de uso obligatorio que se engancha en el plugins_urlfiltro.

No manejará todos los otros casos donde plugin_basename()se usa, como register_activation_hook()y co.

Más información: http://core.trac.wordpress.org/ticket/16953

scribu
fuente
Creo que WP_PLUGIN_URLno se recomienda el uso porque los administradores deberían poder cambiar el nombre del directorio de este complemento específico, pero ¿hay alguna otra razón para evitarlo? Y, de hecho, su boleto sería una solución simple.
Jan Fabry
De lo contrario. WP_PLUGIN_URL solo contiene la URL que apunta directamente al directorio 'plugins'. Ver respuesta actualizada.
scribu
@scribu: ¿Pero qué pasa si mis complementos viven /external/folder/banana-plugin/pero el administrador se vincula a ese directorio como /httpd-root/wp-content/plugins/apple-plugin/? Entonces intentará ir a /wp-content/plugins/banana-plugin/, ¿no? ¿Y creo que el administrador debería ser libre de elegir los nombres de directorio de complementos individuales?
Jan Fabry
Ya no discutiré contigo sobre eso, porque encontré la solución: el filtro 'plugins_url'. Respuesta actualizada nuevamente.
scribu
FWIW esta solución puede ser propensa a errores y depende de que los desarrolladores de complementos solo usen plugins_url () después de que se hayan cargado todos los complementos, de lo contrario no puede registrar un filtro antes de que se llame a la función. el complemento Akismet y muchos otros tienen ese problema.
jerclarke
3

Actualmente utilizo un truco para obtener la ubicación del archivo relativo a WordPress: wp_get_active_and_valid_plugins()devuelve las rutas de los archivos, las wp_settings.phprecorre e incluye los archivos . Entonces, la $pluginvariable global se referirá a su complemento actual (por supuesto, solo cuando se carga el complemento, así que lo guardo en una variable global prefijada):

$monkeyman_Rewrite_Analyzer_file = $plugin;

Debido a que los complementos también se pueden cargar como complementos obligatorios o de red y estos bucles usan otros nombres de variables , el código completo se ve así:

$monkeyman_Rewrite_Analyzer_file = __FILE__;
if ( isset( $mu_plugin ) ) {
    $monkeyman_Rewrite_Analyzer_file = $mu_plugin;
}
if ( isset( $network_plugin ) ) {
    $monkeyman_Rewrite_Analyzer_file = $network_plugin;
}
if ( isset( $plugin ) ) {
    $monkeyman_Rewrite_Analyzer_file = $plugin;
}

El respaldo sigue siendo __FILE__, por lo que si alguien cambia el nombre de la variable de bucle en el futuro, mi código aún debería funcionar para el 99% de todas las instalaciones, solo mi configuración de desarrollo fallará y puedo lanzar una nueva versión con facilidad.

Jan Fabry
fuente
Gran solución @ Jan. Implementé algo similar al llamar a las funciones y al bucle porque olvidé que esas variables eran accesibles como global. Gracias a tu publicación aquí, me di cuenta de que podría hacerlo mucho más simple. Por cierto, también estoy probando false === strpos( __FILE__, WP_CONTENT_DIR )antes de ejecutar sus sentencias if porque supongo que si el complemento está en el WP_CONTENT_DIRenlace simbólico; Espero que sea una lógica válida.
MikeSchinkel
0

Un comentario en el error 46260 sugiere usar en $_SERVER["SCRIPT_FILENAME"]lugar de __FILE__. ¿Esto funciona?

fuxia
fuente
1
No, esto no cambia en los archivos incluidos. Así que si index.phpincluye library.php, $_SERVER['SCRIPT_FILENAME']en library.phpseguirá siendo index.php. Pero gracias por la referencia al error, ¡lo seguiré de cerca!
Jan Fabry
0

$_SERVER["SCRIPT_FILENAME"]funciona si lo usas bien. Solo tiene que usarlo para establecer una ruta base, y luego incluir sus archivos usando una ruta relativa a esa ruta base.

Algo como:

$plugin_dir = dirname($_SERVER["SCRIPT_FILENAME"]);
$myFile = $plugin_dir."/includes/js/myJavascriptFile.js";

Tenga en cuenta que esto es más útil cuando todavía no tiene acceso a wp-blog-header.php (es decir, al procesar una solicitud de formulario basada en ajax)

Chad Furman
fuente