El sistema Hooks

From Dolibarr ERP CRM Wiki
Jump to navigation Jump to search
]]

Introducción

Hooks es una funcionalidad de desarrollo (con Dolibarr 3.2) que permite a los desarrolladores agregar código personalizado en el código del núcleo de Dolibarr sin necesidad de parchear Dolibarr. Al contrario que los triggers (otra funcionalidad para interactuar con el código de Dolibarr) que están vinculados a una acción de negociado, los hooks pueden producirse en cualquier lugar y en cualquier momento, son un punto de entrada en el programa.

  • Hooks trabaja por contexto (es decir por módulo, ej: "productcard" para productos, "invoicecard" para facturas, etc.). Es fácil de encontrar, solo hay que burcar por "initHooks("
  • Hooks son funciones que pueden ser sobrecargadas por las suyas propias. Usted es el que decide si su código se añade al código estandar de Dolibarr o si reemplaza al código de Dolibarr. Puede encontrar funciones sobrecargables buscando por "executeHooks("

Añadir un hook para permitir la inserción de código

Para implementar un hook en su propio módulo (para que su módulo pueda ser "hookeado" por otros), deberá realizar dos pasos.

Estos pasos deben ser reproducidos para cada script php de su módulo donde quiera implementar los hooks.

1- Inicializar el objeto HookManager (ponga este código al inicio de su script php, justo después o antes de los lincludes):

// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
include_once(DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php');
$hookmanager=new HookManager($db);
$hookmanager->initHooks(array('context'));

$hookmanager->initHooks() acepta un parámetro (un array de contextos) y activa la carga de los hooks para este script:

- 'context' est la cadena que contiene el contexto de ejecución. Es un simple indicador que puede ser usado por las funciones hook para detectar en que caso son llamadas (varias páginas/módulos pueden llamar al mismo hook en diferentes lugares, y una función de hook puede no querer ejecutarse para ciertos contextos).

Nota: Puede posicionar varios contextos al mismo tiempo (por ejemplo si necesita un contexto común para varias páginas pero también quiere un contexto específico para una determinada página).


2- Colocar a continuación la llamada a los hooks que permiten la adición de código:

$parameters=array();
$reshook=$hookmanager->executeHooks('hookname',$parameters,$object,$action); // See description below
// Note that $action and $object may have been modified by hook
if (empty($reshook))
{
   ... // standard code that can be disabled/replaced by hook if return code > 0.
}

$hookmanager->executeHooks() acepta 4 parámetros y añade un hook (que es un punto de entrada a su script para las funciones externas a su script y módulo):

- 'hookname' es el nombre del método que será llamado. Por ejemplo: 'formObjectOptions'

- $parameters es un array para enviar datos al hook (la función hooking function puede procesarlos). Cree todo lo que necesite, puede ser un archivo, un array de strings, cualquier cosa.. Por ejemplo:

$parameters=array('file'=>'my/path/to/a/file', 'customnames'=>array('henry','david','john'));

- $object es el objeto al que hay que pasarle la funcion hooking, principalmente el actual módulo de datos (ej: objeto factura si es el módulo de facturas, etc..). Puede ser lo que quiera, pero recuerde que será el componente principal de las funciones hooking que vaya a usar.

- $action es un string que indica la acción actual (puede ser null o algo más claro como 'create' o 'edit').

Nota: Tendrá que repetir este paso varias veces si desea agregar varios hooks en diferentes lugares en el script.

Ahora su módulo debería poder ser hookeado, puede seguir los pasos de Implementar un hook" para implementar una función a usar (permite también comprobar que funcione).

Implementar un hook

Para usar un hook (sobrecarga de una función), debe de haber definido un módulo antes (vea la wiki para ello), y entonces tiene que hacer 2 cosas:

1- Añadir su módulo a los hooks del contexto que desee. Esto significa que cuando este contexto (módulo) va a suceder, el módulo será llamado. Para ello edite su /htdocs/sumodulo/core/modSuModulo.class.php y edite la variable $this->module_parts con algo como esto:

$this->module_parts = array(
'hooks' => array('hookcontext1','hookcontext2')  // Set here all hooks context managed by module
);

Warning.png Tenga cuidado: No olvide DESACTIVAR y luego ACTIVAR el módulo en el panel de administración para aceptar los nuevos valores de las constantes, ya que estas constantes solo se añaden a la base de datos cuando se activa el módulo.


2- Sobrecargar un hook (una función) con la suya propia.

Cree un archivo /htdocs/sumodulo/class/actions_sumodulo.class.php y luego escriba algo como esto:

class ActionsYourModuleName 
{ 
	/**
	 * Overloading the doActions function : replacing the parent's function with the one below
	 *
	 * @param   array()         $parameters     Hook metadatas (context, etc...)
	 * @param   CommonObject    &$object        The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
	 * @param   string          &$action        Current action (if set). Generally create or edit or null
	 * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
	 * @return  int                             < 0 on error, 0 on success, 1 to replace standard code
	 */
	function doActions($parameters, &$object, &$action, $hookmanager)
	{
		$error = 0; // Error counter
		$myvalue = 'test'; // A result value

		print_r($parameters);
		echo "action: " . $action;
		print_r($object);

		if (in_array('somecontext', explode(':', $parameters['context'])))
		{
		  // do something only for the context 'somecontext'
		}

		if (! $error)
		{
			$this->results = array('myreturn' => $myvalue);
			$this->resprints = 'A text to show';
			return 0; // or return 1 to replace standard code
		}
		else
		{
			$this->errors[] = 'Error message';
			return -1;
		}
	}
}

El método será llamado automáticamente llamado en el momento de la llamada del código que contiene el executeHooks con el paso de los elementos $parameters, $object y $action.

Donde:

  • $parameters es un array de meta-datos acerca de los datos contenidos en el hook (ej: el contexto, siempre accesible mediante $parameters['context']).
  • $object es el objeto con el que va a trabajar. Ej: el producto si se encuentra en el contexto productcard.
  • $action es la acción si se ha enviado alguna (generalmente "create", "edit" o "view").
  • $hookmanager es propagado para permitir a su hook llamar a otros hooks.

Listado de Hooks disponibles en Dolibarr

¿Cómo encontrar hooks disponibles? Realice una búsqueda de "executeHooks(" y le será fácil encontrar las llamadas a los métodos Hook.

Template:ListOfHooks ...

Listado de Contextos disponibles en Dolibarr

Para encontrar los contextos disponibles en Dolibarr, el proceso es similar a los hooks. Haga una búsqueda de "initHooks(" en el código fuente y encontrará fácilmente todos los contextos ya implementados

Viendo este listado (no completo): adherents\card.php(111): membercard
adherents\type.php(73): membertypecard
categories\categorie.php(96): categorycard
comm\card.php(72): commcard
comm\propal.php(99): propalcard
comm\action\card.php(85): actioncard
comm\action\index.php(112): agenda
comm\mailing\card.php(55): mailingcard
commande\card.php(93): ordercard
compta\facture.php(105): invoicecard
compta\paiement.php(70): paiementcard
compta\deplacement\card.php(50): tripsandexpensescard
compta\dons\card.php(53): doncard
compta\localtax\clients.php(172): externalbalance
compta\salaries\card.php(47): salarycard
compta\tva\card.php(45): taxvatcard
contact\card.php(77): contactcard
contrat\card.php(70): contractcard
expedition\card.php(85): expeditioncard
fichinter\card.php(80): interventioncard
fourn\card.php(54): suppliercard
fourn\commande\card.php(80): ordersuppliercard
fourn\commande\orderstoinvoice.php(88): orderstoinvoicesupplier
fourn\facture\card.php(72): invoicesuppliercard
fourn\facture\paiement.php(71): paymentsupplier
livraison\card.php(68): deliverycard
product\card.php(91): productcard
product\composition\card.php(55): productcompositioncard
product\fournisseurs.php(62): pricesuppliercard
product\stats\commande.php(45): productstatsorder
product\stats\commande_fournisseur.php(45): productstatssupplyorder
product\stats\contrat.php(45): productstatscontract
product\stats\facture.php(48): productstatsinvoice
product\stats\facture_fournisseur.php(47): productstatssupplyinvoice
product\stats\propal.php(45): productstatspropal
product\stock\card.php(54): warehousecard
projet\card.php(48): projectcard
projet\tasks.php(67): projecttaskcard
resource\card.php(60): resource_card
resource\element_resource.php(58): element_resource
societe\agenda.php(41): agendathirdparty
societe\commerciaux.php(40): salesrepresentativescard
societe\consumption.php(80): consumptionthirdparty
societe\info.php(41): infothirdparty
societe\soc.php(80): thirdpartycard
user\card.php(93): usercard
user\list.php(72): userlist
user\passwordforgotten.php(56): passwordforgottenpage
...

Nota: Tenga en cuenta que esta lista puede cambiar en cualquier momento en el futuro a medida que los hooks y los contextos se implementen en Dolibarr, así que si realmente quiere saber si un determinado contexto o hook existe, por favor busque directamente en el código fuente con el método indicado anteriormente.

Vea también