280 lines
8.3 KiB
PHP
Executable File
280 lines
8.3 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
/**
|
|
* NetGescon Hook Manager
|
|
*
|
|
* Sistema di hook per permettere ai moduli di interagire
|
|
* tra loro e con il sistema core senza accoppiamento stretto
|
|
*/
|
|
class HookManager
|
|
{
|
|
protected static $hooks = [];
|
|
protected static $instance = null;
|
|
|
|
/**
|
|
* Singleton pattern per garantire una sola istanza
|
|
*/
|
|
public static function getInstance()
|
|
{
|
|
if (self::$instance === null) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
/**
|
|
* Registra un hook
|
|
*
|
|
* @param string $hookName Nome dell'hook
|
|
* @param callable $callback Funzione da eseguire
|
|
* @param int $priority Priorità di esecuzione (più basso = più priorità)
|
|
* @param string $moduleName Nome del modulo che registra l'hook
|
|
*/
|
|
public static function register($hookName, $callback, $priority = 10, $moduleName = 'core')
|
|
{
|
|
if (!isset(self::$hooks[$hookName])) {
|
|
self::$hooks[$hookName] = [];
|
|
}
|
|
|
|
self::$hooks[$hookName][] = [
|
|
'callback' => $callback,
|
|
'priority' => $priority,
|
|
'module' => $moduleName
|
|
];
|
|
|
|
// Ordina per priorità
|
|
usort(self::$hooks[$hookName], function ($a, $b) {
|
|
return $a['priority'] <=> $b['priority'];
|
|
});
|
|
|
|
Log::debug("Hook registrato: {$hookName} da modulo {$moduleName} con priorità {$priority}");
|
|
}
|
|
|
|
/**
|
|
* Esegue tutti gli hook registrati per un evento
|
|
*
|
|
* @param string $hookName Nome dell'hook
|
|
* @param mixed $data Dati da passare agli hook
|
|
* @return mixed Dati modificati dagli hook
|
|
*/
|
|
public static function execute($hookName, $data = null)
|
|
{
|
|
if (!isset(self::$hooks[$hookName])) {
|
|
return $data;
|
|
}
|
|
|
|
Log::debug("Esecuzione hook: {$hookName} con " . count(self::$hooks[$hookName]) . " callback");
|
|
|
|
foreach (self::$hooks[$hookName] as $hook) {
|
|
try {
|
|
$result = call_user_func($hook['callback'], $data);
|
|
|
|
// Se l'hook ritorna un valore, lo usa come nuovo $data
|
|
if ($result !== null) {
|
|
$data = $result;
|
|
}
|
|
} catch (\Exception $e) {
|
|
Log::error("Errore nell'esecuzione hook {$hookName} del modulo {$hook['module']}: " . $e->getMessage());
|
|
|
|
// Continua con gli altri hook anche se uno fallisce
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Rimuove tutti gli hook di un modulo
|
|
*
|
|
* @param string $moduleName Nome del modulo
|
|
*/
|
|
public static function unregisterModule($moduleName)
|
|
{
|
|
foreach (self::$hooks as $hookName => &$hooks) {
|
|
$hooks = array_filter($hooks, function ($hook) use ($moduleName) {
|
|
return $hook['module'] !== $moduleName;
|
|
});
|
|
|
|
// Rimuovi hook vuoti
|
|
if (empty($hooks)) {
|
|
unset(self::$hooks[$hookName]);
|
|
}
|
|
}
|
|
|
|
Log::info("Tutti gli hook del modulo {$moduleName} sono stati rimossi");
|
|
}
|
|
|
|
/**
|
|
* Rimuove un hook specifico
|
|
*
|
|
* @param string $hookName Nome dell'hook
|
|
* @param string $moduleName Nome del modulo (opzionale)
|
|
*/
|
|
public static function unregister($hookName, $moduleName = null)
|
|
{
|
|
if (!isset(self::$hooks[$hookName])) {
|
|
return;
|
|
}
|
|
|
|
if ($moduleName) {
|
|
self::$hooks[$hookName] = array_filter(self::$hooks[$hookName], function ($hook) use ($moduleName) {
|
|
return $hook['module'] !== $moduleName;
|
|
});
|
|
} else {
|
|
unset(self::$hooks[$hookName]);
|
|
}
|
|
|
|
Log::debug("Hook rimosso: {$hookName}" . ($moduleName ? " del modulo {$moduleName}" : ""));
|
|
}
|
|
|
|
/**
|
|
* Ottieni la lista di tutti gli hook registrati
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function getRegisteredHooks()
|
|
{
|
|
return array_map(function ($hooks) {
|
|
return array_map(function ($hook) {
|
|
return [
|
|
'module' => $hook['module'],
|
|
'priority' => $hook['priority']
|
|
];
|
|
}, $hooks);
|
|
}, self::$hooks);
|
|
}
|
|
|
|
/**
|
|
* Verifica se un hook è registrato
|
|
*
|
|
* @param string $hookName Nome dell'hook
|
|
* @return bool
|
|
*/
|
|
public static function hasHook($hookName)
|
|
{
|
|
return isset(self::$hooks[$hookName]) && !empty(self::$hooks[$hookName]);
|
|
}
|
|
|
|
/**
|
|
* Conta il numero di callback registrati per un hook
|
|
*
|
|
* @param string $hookName Nome dell'hook
|
|
* @return int
|
|
*/
|
|
public static function countHooks($hookName)
|
|
{
|
|
return isset(self::$hooks[$hookName]) ? count(self::$hooks[$hookName]) : 0;
|
|
}
|
|
|
|
/**
|
|
* Carica gli hook di tutti i moduli attivi
|
|
*/
|
|
public static function loadModuleHooks()
|
|
{
|
|
$moduleManager = app(ModuleManager::class);
|
|
$activeModules = $moduleManager->getActiveModules();
|
|
|
|
foreach ($activeModules as $module) {
|
|
self::loadModuleHooksFile($module->name);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Carica il file hooks.php di un modulo specifico
|
|
*
|
|
* @param string $moduleName Nome del modulo
|
|
*/
|
|
public static function loadModuleHooksFile($moduleName)
|
|
{
|
|
$hooksFile = app_path("Modules/{$moduleName}/hooks.php");
|
|
|
|
if (file_exists($hooksFile)) {
|
|
include_once $hooksFile;
|
|
Log::debug("Hook file caricato per modulo: {$moduleName}");
|
|
}
|
|
}
|
|
}
|
|
|
|
// ================================================
|
|
// HOOK PREDEFINITI DEL SISTEMA CORE
|
|
// ================================================
|
|
|
|
/**
|
|
* Helper function per registrare hook più facilmente
|
|
*/
|
|
if (!function_exists('hook_register')) {
|
|
function hook_register($hookName, $callback, $priority = 10, $moduleName = 'core')
|
|
{
|
|
HookManager::register($hookName, $callback, $priority, $moduleName);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper function per eseguire hook più facilmente
|
|
*/
|
|
if (!function_exists('hook_execute')) {
|
|
function hook_execute($hookName, $data = null)
|
|
{
|
|
return HookManager::execute($hookName, $data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lista degli hook disponibili nel sistema NetGescon
|
|
*
|
|
* CORE HOOKS:
|
|
* - 'user_login' => Dopo il login di un utente
|
|
* - 'user_logout' => Dopo il logout di un utente
|
|
* - 'user_created' => Dopo la creazione di un utente
|
|
* - 'user_updated' => Dopo l'aggiornamento di un utente
|
|
* - 'user_deleted' => Dopo l'eliminazione di un utente
|
|
*
|
|
* STABILI HOOKS:
|
|
* - 'stabile_created' => Dopo la creazione di uno stabile
|
|
* - 'stabile_updated' => Dopo l'aggiornamento di uno stabile
|
|
* - 'stabile_deleted' => Dopo l'eliminazione di uno stabile
|
|
*
|
|
* UNITA IMMOBILIARI HOOKS:
|
|
* - 'unita_created' => Dopo la creazione di un'unità
|
|
* - 'unita_updated' => Dopo l'aggiornamento di un'unità
|
|
* - 'unita_deleted' => Dopo l'eliminazione di un'unità
|
|
*
|
|
* CONTABILITA HOOKS:
|
|
* - 'movimento_created' => Dopo la creazione di un movimento contabile
|
|
* - 'movimento_updated' => Dopo l'aggiornamento di un movimento
|
|
* - 'bilancio_generated' => Dopo la generazione di un bilancio
|
|
* - 'rate_generated' => Dopo la generazione delle rate
|
|
* - 'rata_created' => Dopo la creazione di una rata singola
|
|
* - 'rata_paid' => Dopo il pagamento di una rata
|
|
*
|
|
* DOCUMENTI HOOKS:
|
|
* - 'document_uploaded' => Dopo l'upload di un documento
|
|
* - 'document_downloaded' => Dopo il download di un documento
|
|
* - 'document_deleted' => Dopo l'eliminazione di un documento
|
|
*
|
|
* MENU HOOKS:
|
|
* - 'menu_building' => Durante la costruzione del menu
|
|
* - 'sidebar_rendering' => Durante il rendering della sidebar
|
|
*
|
|
* DASHBOARD HOOKS:
|
|
* - 'dashboard_stats' => Durante il calcolo delle statistiche dashboard
|
|
* - 'dashboard_widgets' => Durante il caricamento dei widget dashboard
|
|
*
|
|
* STAMPE HOOKS:
|
|
* - 'before_print' => Prima della generazione di una stampa
|
|
* - 'after_print' => Dopo la generazione di una stampa
|
|
* - 'print_template_loading' => Durante il caricamento del template di stampa
|
|
*
|
|
* NOTIFICATIONS HOOKS:
|
|
* - 'notification_sending' => Prima dell'invio di una notifica
|
|
* - 'notification_sent' => Dopo l'invio di una notifica
|
|
* - 'email_sending' => Prima dell'invio di una email
|
|
* - 'email_sent' => Dopo l'invio di una email
|
|
*/
|