En la anterior entrada, mostré las veinte líneas de que se compone el plugin GbMarkdown para Gesbit. En esta entrada me propongo explicar o describir línea por línea el código fuente susomentado, por si a alguien le resulta de interés. Vamos allá, pues.

Primero, vamos a refrescar la memoria, mostrando completo el código fuente del plugin:

function gbmarkdown($pluginData){
  return new GbMarkdown($pluginData);
}
 
class GbMarkdown extends GbPlugin
{
  const MARKDOWN_SCRIPT='markdown.php';
 
  public function OnActivatePlugin(){}
  public function OnDeactivatePlugin(){}
 
  public function FilterCallback($filterID, $content){
    if(($filterID == GBPLUGINS_FILTER_POST_CONTENT) 
     && is_readable($this->GetDirPath().self::MARKDOWN_SCRIPT)){
       require_once($this->GetDirPath().self::MARKDOWN_SCRIPT);
       return Markdown(html_entity_decode($content));
    }
    return $content;
  }
}

Ahora vamos a echar un vistazo pormenorizado, línea por línea, si te parece bien.

function gbmarkdown($pluginData){
  return new GbMarkdown($pluginData);
}

Lo anterior es la función usada para registrar el plugin. Gesbit se encarga de llamar a esa función, si el plugin está "activado", y, la misma, debe limitarse a retornar una instancia de la clase del plugin, en este caso "GbMarkdown". La función recibe un parámetro, que ha de pasar a su vez al constructor de la clase "GbMarkdown", como puede apreciarse.

class GbMarkdown extends GbPlugin

En esa línea se declara (y se comienza la implementación) de la clase "GbMarkdown", que, como puedes ver, hereda de la clase "GbPlugin". Todos los plugins para Gesbit deben heredar de la clase "GbPlugin", que, a su vez, proporciona métodos útiles para los plugins, entre otras utilidades.

Observa, por ejemplo, que la clase "GbMarkdown" no implementa ningún constructor público ni privado, empero, sí que lo hace la clase "GbPlugin". Este constructor "guarda" los datos del plugin (que se proporcionan en la función "de registro" vista más arriba) y trata de "cargar" el archivo principal para la internacionalización del plugin, siempre que exista uno disponible.

const MARKDOWN_SCRIPT='markdown.php';

Se trata de definir una constante, justamente, el nombre de un "script" necesario para el plugin. Lo hacemos por conveniencia, porque usamos la constante en más de un lugar, y porque nos parece una buena costumbre evitar las cadenas "duras" (tal cual) en el código fuente. Huelga decir las ventajas que aportan las constantes como esta.

public function OnActivatePlugin(){}
public function OnDeactivatePlugin(){}

Los métodos "OnActivatePlugin" y "OnDeactivatePlugin" no se implementan en el plugin que estamos viendo, no son necesarios, pero, dichos métodos son abstractos, y deben declararse, al menos, incluso si no son necesarios. Dichos métodos vendrían a ser los "instaladores" y "desinstaladores" de los plugins.

Por ejemplo, si un plugin necesita guardar opciones en la base de datos de Gesbit, puede aprovechar el primer método para "inicializar" dichas opciones, y, el segundo, para borrarlas, de forma que su instalación no deje rastro en la base de datos de Gesbit. Estos podrían ser sus principales cometidos.

public function FilterCallback($filterID, $content)

El método público "FilterCallback" es opcional en los plugins para Gesbit, y, en caso de existir, Gesbit se encargará de ejecutarlos, precisamente, cuando pueda filtrarse cierto contenido de las bitácoras. El método recibe como parámetro el "ID" del filtro, de modo que el plugin puede decidir actuar o no, dependiendo del filtro en cuestión, y, por otro lado, se recibe el contenido que Gesbit permite filtrar a los plugins.

if(($filterID == GBPLUGINS_FILTER_POST_CONTENT)

La anterior condición, por supuesto, tiene que ver con lo que decíamos antes: el plugin trata de averiguar si el filtro que puede llevarse a cabo es el que está esperando, sobre el que precisa actuar. En el caso del plugin GbMarkdown, que estamos viendo, el filtro que nos interesa es el que permite actuar sobre el contenido de las entradas de las bitácoras.

Esto quiere decir lo siguiente: justo antes de que Gesbit "imprima" (según se conforma la página de la bitácora que está mostrándose) el contenido de las entradas, ejecutará el filtro oportuno en todos los plugins "activos", que, por supuesto, implementen el método "FilterCallback".

&& is_readable($this->GetDirPath().self::MARKDOWN_SCRIPT))

La anterior condición, tiene el objetivo de comprobar que, efectivamente, existe el "script" que el plugin utilizará luego para realizar su trabajo. Es una condición un poco "paranoica", puesto que el plugin incluye el archivo necesario, pero, en fin, tampoco está demás, por lo que a continuación se lleva a cabo, además:

require_once($this->GetDirPath().self::MARKDOWN_SCRIPT);

Efectivamente, sólo si existe el "script" necesario, el plugin lo incluirá, de modo que pueda utilizar la funcionalidad del mismo. Cabe observar el uso del método "GetDirPath". Este método está implementado en la clase "GbPlugin", de la que hereda "GbMarkdown", como hemos visto. El método en cuestión retorna la ruta absoluta del directorio donde se encuentra instalado el plugin.

return Markdown(html_entity_decode($content));

Bien. Hemos llegado a donde queríamos. Las condiciones se cumplen, y el plugin debe hacer su trabajo: en realidad delegar el mismo a otra clase, implementada en el "script" que hemos requerido antes, de modo que nos limitamos a usarla para filtrar el contenido que hemos recibido, para retornarlo, ya filtrado, a continuación. Objetivo cumplido.

return $content;

Pero todavía quedaría la línea anterior por explicar. Y es muy sencillo: el método "FilterCallback" ha de retornar el contenido que se disponga a filtrar, independientemente de que se cumplan ciertas condiciones o de que no se cumplan, haga o no haga el plugin lo que quiera que sea que tenga que hacer con el contenido: tiene que retornar aunque sea el contenido "tal como le llega", para que el resto de plugins puedan aplicar sus propios filtros, y, por fin, Gesbit pueda mostrarlo donde corresponde.

Espero que esta entrada no te resultara pesada. Comenté en la anterior que, según mi parecer, el código fuente del plugin "GbMarkdown" era bastante descriptivo de por sí. Tal vez con estas explicaciones más o menos pormenorizadas, quien esté interesado haya podido acercarse al mismo un poco más.