6.1.10

Creando hooks en Typo3

Una de las grandes carencias de Typo 3 es de documentación. Resulta francamente difícil encontrar algo que te resulte de utilidad ya que como "no te fuerza a hacer las cosas de un modo determinado" simplemente no hay métodos estándar y la comunidad tampoco parece demasiado interesada en hacer literatura.

Y ese ha sido el gran problema (además de su alarmante falta de ergonomía y de tener una estructura de lo más confusa) con el que me he encontrado a la hora de aprender a desarrollar con este CMS/framework.

Entrando en materia, podríamos definir los hooks como una forma de hacer que el núcleo de Typo3 ejecute algunas rutinas creadas por el usuario para realizar una tarea cualquiera.

Vamos a suponer que tenemos que actualizar un campo de la base de datos cada vez que guardemos un registro de una extensión. Para ello, justo en el momento en que vayamos a guardar el registro tenemos que coger el array en el que Typo3 encapsula los datos a guardar, y añadir una nueva posición para el campo que deseamos actualizar.

Supongamos que nuestra tabla se compone de los siguientes campos:
  • dni_persona
  • nombre_persona
  • direccion_persona
  • actualizado_persona
Cada vez que alteremos direccion_persona guardaremos los datos en actualizado_persona.

Este hook va a pertenecer a una extensión llamada pry_datospersona, que será la encargada de gestionar los datos de nuestros usuarios.

Una extensión se compone de varios ficheros, algunos de los cuales se van a llamar siempre que se cargue la extensión. Para hacer el include al archivo donde escribamos nuestro hook vamos a añadir una línea al final de uno de estos archivos, que en el caso de este ejemplo va a ser ext_tables.php, situada en la raíz de la extensión (en typo3conf/ext/pry_datospersona/ext_tables.php)

require_once(t3lib_extMgm::extPath('pry_datospersona').'/pi1/datospersona_hook.php');

En esta línea estamos diciendo a la clase t3lib_extMgm, que se encarga de gestionar las extensiones dónde se encuentra la clase que va a incluir.

Ahora vamos a escribir nuestro fichero datospersona_hook.php en el directorio pi1 de la extensión:


<?php
class tx_persona_hook {

/*
Hay muchas clases de hooks en typo3. Los que se encargan de
actualizar los datos antes de insertarlos en la BD son los
llamados "processDatamap_preProcessFieldArray"
y que son invocados en t3lib/class.t3lib_tcemain.php

Así que nuestro hook tiene que tener como método de entrada
uno con ese nombre, ya que será el que ejecute Typo3 en el
momento apropiado
*/
function processDatamap_preProcessFieldArray (&$incomingFieldArray,
$table, $id, $this) {
//realmente podríamos hacerlo todo aquí, pero me siento más
//cómodo modularizando, por si hay que hacer más de una tarea
$incomingFieldArray=$this->procesar($incomingFieldArray,$id);
//llamadas a otros métodos;
}//processDatamap_preProcessFieldArray

function procesar($datos,$id){
/*comprobamos que lo guardado en la base de datos es diferente
que lo que recibimos. Para ello primero recuperamos de la
base de datos y luego comparamos con lo que acabamos de recibir
*/
$direccion=$datos['direccion_persona'];

//usamos la libreria propia de typo3 para hacer una query
$result=$GLOBALS['TYPO3_DB']->exec_SELECTquery('*',
'tx_persona',
"id_persona=$id","","","");
$row=$GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);

if($row){
//vamos devolver el timestamp actual si las direcciones
//son distintas
//en caso contrario devolvemos el valor que ya está en la BD
if($row['direccion_persona']!=$direccion) {
$return = time();
}
if(!$return) $return=$row['actualizado_persona'];
$datos['actualizado_persona']=$return;
return $datos;
}
}//procesar
}//clase

//esta parte sirve para registrar en la configuracion de Typo3
//nuestro hook
//MUY IMPORTANTE: la parte después de []: tiene que ser algo como
//EXT:ruta/al/fichero.php:nombre_clase

$TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']
['processDatamapClass'][]=
'EXT:pry_persona/pi1/datospersona_hook.php:tx_persona_hook';
if (defined('TYPO3_MODE') &&
$TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']
['ext/pry_persona/pi1/datospersona_hook.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']
['pry_persona/pi1/datospersona_hook.php']);
}//if defined
?>

Pues esto debería ser todo. Con esto nuestro hook debería funcionar.

2 comentarios:

anonimamericana dijo...

Hook no era un pirata? Capitan Hook el malo de Peter Pan, no?
Ayss es que me lio....

Contremo dijo...

Sí, era un pirata que aparecía en las pesadillas de los niños. No sé si tiene algo que ver para que le diesen este nombre, pero me parece extrañamente apropiado :)