Codice PHP:
$pluginsDipendenze=array();
$pluginsCaricati=array();
function CaricaPlugin($nome,$dipendenze){
global $pluginsCaricati,$pluginsDipendenze;
//se un plugin è già caricato è inutile ricaricarlo
if(!isset($pluginsCaricati[$nome])){
//prima carico i plugin da cui dipende
foreach($dipendenze as $nomePluginDip)
CaricaPlugin($nomePluginDip,$pluginsDipendenze[$nomePluginDip]);
//quindi carico il plugin e aggiorno l'elenco dei pluin già caricati
//sistema il percorso a dovere perchè non so dove piazzi questa funzione
require_once "/plugin/$nome/$nome.plugin";
$pluginsCaricati[$nome]=true;//qui potresti voler assegnare la versione o altri dati più interessanti
}
}
function initialize_plugins(){
global $pluginsDipendenze,$db;
//qui fai le require_one di base del core se ne hai
$sql="select flatname, dependecies from plugins where active=1";
foreach($db->query($sql) as $plugin)
$pluginsDipendenze[$plugin['flatname']] = json_decode($plugin['dependencies']);
//le righe sopra forse vanno bene o forse no. A me serve che ogni
//$pluginsDipendenze[$plugin['flatname']]contenga o array(), ovvero un array php
//vuoto, o un array con i flatname dei plugin da cui dipende
foreach($pluginsDipendenze as $nome=>$dipendenze)
CaricaPlugin($nome,$dipendenze);
}
Cosa fanno le due funzioni? la prima cerca di caricare tutti i plugin attivi. In realtà CaricaPlugin è capace di distinguere tra ciò che è già stato caricato e ciò che non lo è.
Se un plugin va caricato prima carica le dipendenze richiamando se stessa, così se una dipendenza ha ulteriori dipendenze anche vengono caricate prima della dipendenza e ciò ricorsivamente. La ricorsione si interrompe quando raggiungo i plugin senza dipendenze e dando il via alle require_once nell'ordine giusto.
Con buona pace per i plugin e per il topological sorting, dato che abbiamo i riferimenti in senso inverso, ovvero dalla foglia verso la radice (il core), non facciamo altro che ricostruire la sequenza dei caricamenti nello stack delle chiamate della funzione caricaplugin invertendo di fatto tale ordine, dalla radice (plugin senza dipendenze) verso le foglie, ogni folta che la funzione va a concludersi e prescindendo dal nodo (plugin) da cui avviamo l'operazione. I già caricati vengono ignorati.
Attento ai riferimenti ciclici che ti bruciano lo stack facendoti cadere in chiamate ricorsive infinite.
Spero di esser stato chiaro.
Avviamente non ho potuto testare il codice ma dovrebbe essere corretto.