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

@Jk en ¿”WatchTower” o “CashPower”?: Hola! Solo queria decirte algo de corazon, no soy testigo, pero muchas veces...

@Glass en ¿Joomla Vs. Wordpress? (1ª parte): Muy interesante post, aunque algo parecido leí en alguna parte pero en inglés, aunque aquí se tocan...

@Ricardo Olivera en ¿Joomla Vs. Wordpress? (1ª parte): Muy interesante el post y los comentarios. Yo quiero poner una tienda tipo carrito de...

@Antonio García en ¿Joomla Vs. Wordpress? (1ª parte): Creo que la comparación no debería tomarse tan literalmente, creo que muchos usuarios no tan...

@Daniel Gonzalez en ¿Joomla Vs. Wordpress? (1ª parte): Sobre la comparación de lo que puede o no puede hacer wordpress y joomla, sería interesante...

@Bandolera en ¿Joomla Vs. Wordpress? (1ª parte): Hola chicos malos: Según he leido el artículo y los comentarios dejados, me doy cuenta que en...

@ABTOP en Construir letras capitulares en Wordpress. Parte I – PHP: Similar, but slightly different approach: http://newrussianamerica.co...

@claudia santiesteban hernandez en Malos consejos: yo tengo una enemiga por mis espaldas y hasta le tengo y me quito a angel eso me da miedo y...

Darío Ferrer — Blog personal

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

60 consultas a la BD en 1.386 segundos. Blog alojado en DreamHost