Cómo activar funciones nativas de WordPress en archivos secundarios de tu plugin

27 de septiembre de 2009 — Darío Ferrer

Cuando desarrollas un plugin, WordPress activa todas sus funciones nativas (etiquetas, hooks, etc.) al archivo de tu plugin que has identificado como principal y se “olvida” de los demás. Es necesario entonces colocar una ruta hacia wp-load.php, cuya función consiste precisamente en habilitar estas funciones al archivo que quieras.

El problema

Muchos son los plugins que necesitan transferir funciones nativas de WordPress a archivos adicionales. Hasta el momento la mayoría ha logrado superar este paso colocando -desde el archivo secundario- una ruta estática hacia wp-load.php de esta manera:

1
<?php require_once('../../wp-load.php') ?>

Esto funciona correctamente siempre y cuando la instalación de WordPress se mantenga intacta pero ¿qué pasaría si el usuario, en su wp-config.php, define una ruta personalizada para el directorio de plugins (PLUGIN_DIR)?. Pues sencillamente el plugin quedará totalmente inutilizado, pues es probable que wp-load.php no se encuentre en el directorio específico apuntado en el require_once. Siendo así, PHP devolverá error y no quedará otro remedio que desactivar el plugin.

En pocas palabras, un plugin con rutas estáticas hacia archivos clave condenará a quien lo usa a mantener las configuraciones predeterminadas de sus directorios, al menos hasta que éste decida descartarlo de su lista de plugins.

La solución: establecer una ruta dinámica hacia wp-load.php

Siempre he dicho que WordPress -sin ovlidar a sus usuarios de siempre- debería enfocar mayor atención en la habilitación de recursos para desarrolladores. No es posible que una tontería de éstas sea la gran culpable de que quienes programen bajo dicha plataforma se priven de implementar mejores recursos a sus scripts.

En fin, todo el lío consiste en lograr que un archivo secundario sea capaz de recibir la instrucción ABSPATH (función de WordPress que imprime la ruta absoluta de un archivo) y con ello lograr imprimir la ruta hacia el script, independientemente del directorio donde se encuentre el archivo. El script en cuestión es éste (Por supuesto lo escribirás en el archivo principal de tu plugin):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?php
/*
  Script para escribir ruta hacia wp-load.php
  en sistemas Wordpress.
  Por: metacortex, okram y abimaelrc
  Participaron también: David y jonatanc

  Documentación:
  http://www.forosdelweb.com/f18/solucionado-problema-con-fwrite-725388/

  Licencia GNU/GPL.
*/


// Estas dos primeras líneas se usan regularmente para definir
// la ubicación del archivo
if ( !defined('WP_PLUGIN_DIR') ) $plugin_dir = str_replace( ABSPATH, '', dirname(__FILE__) );
else $plugin_dir = dirname( plugin_basename(__FILE__) );

// En la variable $texto definiremos la línea que queremos escribir
// en el archivo secundario
$texto = 'require_once(\''. ABSPATH . 'wp-load.php\');';

// Variable vacía en caso de el archivo secundario no sea
// escribible. Más abajo se desarrolla
$texto_error = '';

// La ubicación del archivo secundario en el que vamos a escribir la
// ruta dinámica
$archivo = ABSPATH . '/' . PLUGINDIR . '/' . $plugin_dir .'/wpsi-data.php';

// Línea donde vamos a escribir
$conteo = 1;

// Definimos la variable para leer el archivo secundario
$leer = file($archivo, FILE_IGNORE_NEW_LINES);

// Si la línea existe y al mismo tiempo $texto es distinto a lo que hay allí...
if( isset($leer[$conteo]) and $texto != trim($leer[$conteo]) ) {
  $leer[$conteo] = $texto;

  // Si se puede escribir en el archivo...
  if (is_writable($archivo)) {

    // Se configura un salto a esa línea
    $nueva_linea = implode( "\n" , $leer );

    // Se configura la apertura del archivo con permisos de escritura
    $abrir = fopen( $archivo , 'w' );

    // Se despliega todo lo configurado anteriormente, es decir,
    // escribir la línea con su salto y guardar el archivo.
    fwrite( $abrir , $nueva_linea , strlen($nueva_linea) );

    // Cerrar el  archivo secundario
    fclose($abrir);

  // De lo contrario, si no se puede escribir
  } else {
    // Aquí le agregamos el valor a $texto_error, indicándole al usuario
    // que escriba manualmente el código en la línea indicada.
    $texto_error .='
    <div id="message" class="updated fade">
      <p>No se puede escribir en el archivo fulano.php. Por favor ábralo con un editor de texto y copie/pegue lo siguiente en la primera línea</p>
      <pre>'
.$archivo.'</pre>
    </div>'
;
  }
}
?>

Qué es lo que hace este script

  • Imprime la ruta absoluta completa al archivo wp-load.php (el que activa las funciones de WordPress en archivos estáticos) independientemente del lugar donde se encuentre el directorio del plugin. Si posteriormente la carpeta es movida, el script localizará automáticamente al archivo.
  • Si el archivo a modificar no es escribible, el script lanzará una advertencia en el panel de que es necesario incluir el código, proporcionando la ruta correcta del mismo en una etiqueta <pre>.
  • Si el código está correctamente en su lugar, el anuncio no saldrá (aunque el archivo no sea escribible).

Complementando: La historia de este lío

Hace algunas semanas comencé a darle vueltas a este asunto y concluí que la solución más sensata era hacer que PHP escribiera la ruta en el archivo secundario. En síntesis, el procedimiento era escribir la función en el archivo principal, quien se encargaría de leer una línea específica en el secundario y escribir la ruta correcta en caso de que no se encotrara allí (o fuera diferente).

Hice un código inicial que técnicamente cumplía con su misión, pero presentaba grandes fallas de implementación, pues la función escribía la línea una y otra vez con cada actualización en el frontend del sitio (la interfaz de usuario). Es decir, en un sitio con 10.000 visitas diarias el PHP tendría que escribir el archivo 10.000 veces, así que ese aspecto me desanimó.

No fue sino hasta que expuse el problema ante los muchachos de Foros del Web cuando el script por fin funcionó.

Si tienes una duda técnica sobre este artículo, por favor formúlala en el foro.

  • Bitacoras.com
  • Meneame
  • Twitter
  • del.icio.us
  • Facebook
  • Digg
  • Technorati
  • BarraPunto

Publicado en Wordpress.

Comentar este artículo

Nombre (Requerido)

Correo (No será publicado) (Requerido)

Sitio web

Secciones

Anteriores

comentarios recientes

@Willy en ¿Joomla Vs. Wordpress? (1ª parte): Era lo que necesitaba leer!!! como programador, aprender como editar un template de cero en joomla y...

@Willy en [Meme] Concepto bizarrón de CSS: Cagadas Siempre Suceden!! XD Counter Strike Server. no es bizarro pero bue!!

@Horacio en ¿Joomla Vs. Wordpress? (1ª parte): Hola, hace tiempo empece a trabajar con joomla y armar mi sitio web en un servidor gratuito para...

@birgitta en ¿”WatchTower” o “CashPower”?: Hilaridad sin H,mis disculpas

@birgitta en ¿”WatchTower” o “CashPower”?: AY AY AY.Cuanto lobotomizado hay por aqui!!!!!! Muchas gracias Dario por tu...

@Darío en ¿Joomla Vs. Wordpress? (1ª parte): Gracias por la sugerencia tocayo, voy a analizarla! Luego de buscar un poco más encontré que la página...

@Juan Vera en Dar acceso a grupos de Joomla (o restringírselo) para cualquier componente: Hola, mira yo quiero algo parecido pero para las personas...

@Emanuel en Dos tips sobre Adobe Reader: Detener AcroRd32Info.exe e impedir actualizaciones automáticas: Para que molestarse instalando acrobat si...

Darío Ferrer — Blog personal

Sitio desarrollado con Wordpress, software libre para un mundo libre.

58 consultas a la BD en 0,736 segundos. Blog alojado en DreamHost