¿Cuál es la mejor forma de obtener la ruta del directorio para wp-config.php?
Soy desarrollador del plugin mapsmarker.com que también ofrece varias APIs accesibles directamente (ej. www.mapsmarker.com/wp-content/plugins/leaflet-maps-marker/leaflet-geojson.php?marker=1). Inicialmente escribí la ruta absoluta del directorio usando esta función durante la instalación del plugin:
file_put_contents(dirname(__FILE__).'/leaflet-wp-path.php', '<?php define(\'WP_PATH\',\''.ABSPATH.'\'); ?>');
En los archivos API, incluía el archivo leaflet-wp-path.php con este código:
include_once(dirname($_SERVER['SCRIPT_FILENAME']).'/leaflet-wp-path.php');
include_once(WP_PATH.'wp-config.php');
include_once(WP_PATH.'wp-includes/wp-db.php');
global $wpdb;
...
Noté que en algunos proveedores de hosting estas operaciones no están permitidas, causando fallos en la instalación. Por eso cambié a otro método para determinar la ruta a wp-config.php:
//info: construye la ruta a wp-config.php con alternativa para instalaciones en subdirectorios
$wp_path = $_SERVER["DOCUMENT_ROOT"];
if ( file_exists($wp_path . '/wp-config.php') ) {
include_once($wp_path.'/wp-config.php');
include_once($wp_path.'/wp-includes/wp-db.php');
} else {
$wp_plugin_path_modified = explode(DIRECTORY_SEPARATOR, dirname(__FILE__),-3);
$wp_path = implode(DIRECTORY_SEPARATOR, $wp_plugin_path_modified);
include_once($wp_path.'/wp-config.php');
include_once($wp_path.'/wp-includes/wp-db.php');
}
if ( !file_exists($wp_path . '/wp-config.php') ) {
echo __('Error: No se pudo construir la ruta a wp-config.php - consulta <a href="http://mapsmarker.com/path-error">http://mapsmarker.com/path-error</a> para más detalles.','lmm') . '<br/>Ruta en tu hosting: ' . $wp_path;
} else {
...
Esto funcionó bien incluso en hosts que no permiten file_put_contents(), determinando la ruta desde el directorio actual del archivo API.
Ahora un usuario reportó que este método no funciona en su host. Escribe:
Ejemplo de un enlace de icono. Parece que todos los enlaces del plugin están incorrectos. Solo funciona el panel de administración. Crea marcadores pero no los muestra en navegadores.
En Windows Web Host http://XXXXX/wordpress/wp-content/plugins/D:/Hosting/5465771/html/wordpress/wp-content/plugins/leaflet-maps-marker/img/logo-mapsmarker.png
En Linux Web Host http://XXXXX/wordpress/wp-content/plugins/D:/inetpub/vhosts/XXXXX/httpdocs/wordpress/wp-content/plugins/leaflet-maps-marker/img/logo-mapsmarker.png
¿Alguien conoce un mejor método para determinar la ruta a wp-config.php que funcione en este tipo de configuraciones de hosting?

Se me ocurrió esta solución.
Esta función verifica en cada nivel de directorio comenzando desde el directorio del archivo actual buscando el archivo wp-config.php.
<?php
function find_wp_config_path() {
$dir = dirname(__FILE__);
do {
if( file_exists($dir."/wp-config.php") ) {
return $dir;
}
} while( $dir = realpath("$dir/..") );
return null;
}
?>
Para incluir realmente el archivo puedes usar esto:
if ( ! function_exists('add_action') ) {
include_once( find_wp_config_path() . '/wp-load.php' );
}
Esto también se puede encontrar aquí: Cómo determinar la ruta base de WordPress cuando el núcleo de WordPress no está cargado

Utilizo este enfoque todo el tiempo. Hace las cosas más limpias, no me gusta la idea de depender de funciones externas para obtener rutas para incluir archivos. Toma mi voto positivo.

Para dejar constancia, la pregunta plantea cómo hacer algo incorrecto, incluso en el momento en que se formuló, no deberías haber accedido directamente a ninguno de los archivos del plugin, sino utilizar probablemente un parámetro de URL único como my_plugin_param
cuyo uso indicaría que el plugin debe realizar lo que sea necesario. Para detectarlo, el plugin debería engancharse a la acción init
y verificar si la URL contiene my_plugin_param
. Una vez hecho de esa manera, no necesitas cargar WordPress, ya que ya se habría hecho.
Si bien wp-config.php
debería estar en la raíz de WordPress o en un directorio superior, los plugins podrían instalarse fuera de los directorios de WordPress. Aunque no es una configuración especialmente popular, es posible hacerlo.

no es mi código, lo encontré en stack, pero prueba esto:
function FindWPConfig($directorio){
global $confroot;
foreach(glob($directorio."/*") as $f){
if (basename($f) == 'wp-config.php' ){
$confroot = str_replace("\\", "/", dirname($f));
return true;
}
if (is_dir($f)){
$nuevodir = dirname(dirname($f));
}
}
if (isset($nuevodir) && $nuevodir != $directorio){
if (FindWPConfig($nuevodir)){
return false;
}
}
return false; }
if (!isset($table_prefix)){
global $confroot;
FindWPConfig(dirname(dirname(__FILE__)));
include_once $confroot."/wp-load.php";
}

Como esta es la misma solución que la de bueltge, solo puedo repetirme: Es un enfoque muy desagradable. La salida se hace con una variable global, lo cual no es nada elegante. El código es realmente confuso e ineficiente. Lo mismo se puede hacer de una manera mucho mejor con la solución que publiqué.

Lo siguiente no responde exactamente lo que se pregunta en el contexto de la pregunta, pero sí responde exactamente lo que dice el título de la pregunta.
Para aquellos que buscan una forma de obtener la ruta a wp-config.php desde dentro de WordPress, lo siguiente funciona bien.
Así es como WP CLI lo hace:
function locate_wp_config() {
static $path;
if ( null === $path ) {
$path = false;
if ( getenv( 'WP_CONFIG_PATH' ) && file_exists( getenv( 'WP_CONFIG_PATH' ) ) {
$path = getenv( 'WP_CONFIG_PATH' );
} elseif ( file_exists( ABSPATH . 'wp-config.php' ) ) {
$path = ABSPATH . 'wp-config.php';
} elseif ( file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) {
$path = dirname( ABSPATH ) . '/wp-config.php';
}
if ( $path ) {
$path = realpath( $path );
}
}
return $path;
}

Pero eso en realidad no busca el archivo, por lo que no sería de mucha utilidad para el caso de la pregunta. Asume que ya has configurado una variable de entorno o que estás ejecutando desde dentro de WordPress o que ya estás en la carpeta correcta.

Bueno, entonces el título de la pregunta no es correcto. Porque en wordpress.stackexchange.com, como alguien que está buscando respuestas como yo, uno esperaría que estamos ejecutando desde dentro de WP. Edité mi respuesta para aquellos que solo leen el título y esperan una respuesta a eso.
