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
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.





















Óbidos