C'est par l'intermédiaire d'un objet que l'on accède aux modules du framework ICanBoogie, il les indexe et permet des les charger, de les démarrer, de vérifier leur disponibilité, de les activer ou de les désactiver le temps d'une session. On qualifie cet objet d'« accesseur » parce qu'on l'utilise principalement pour accéder aux modules.
Dans le cadre d'une utilisation classique du framework
ICanBoogie, l'accesseur est crée lors du
premier accès à la propriété magique modules de l'objet $core :
<?php
$modules = $core->modules;
Obtenir l'instance d'un module
Pour obtenir l'instance d'un module il convient d'utiliser l'accesseur comme un tableau associatif ayant pour clés les identifiants des modules et pour valeurs les instances des modules. Ainsi, pour obtenir l'instance du module « nodes », nous aurions le code suivant :
<?php
$nodes = $modules['nodes'];
Des exceptions sont lancées lorsque l'on essaie d'obtenir l'instance d'un module qui n'est pas disponible (parce qu'il est manquant ou désactivé) ou lorsque la classe qui doit être utilisée pour créer cette instance est introuvable. On pourra facilement réagir à ces situations exceptionnelles grâce au bloc try/catch :
<?php
try
{
$nodes = $modules['nodes'];
}
catch (Exception $e)
{
echo "Unable to get module: " . $e->getMessage();
/* rescue code */
return;
}
/* code continues */
Vérifier la disponibilité d'un module
Bien que le module soit physiquement présent, il peut avoir été désactivé par l'utilisateur.
Lorsque l'absence d'un module n'est pas sensible au bon déroulement de l'application
on préfèrera tester sa présence et sa disponibilité, pour cela il convient d'utiliser
la function isset() :
<?php
$is_available = isset($modules['nodes']); // is the module available ?
Activer et désactiver un module
À tout moment il est possible d'activer ou de désactiver un module. Ainsi, pour un module « nodes », nous aurions le code suivant :
<?php
$modules['nodes'] = false; // the module "nodes" is disabled
$modules['nodes'] = true; // the module is now enabled
unset($modules['nodes']); // the module is disabled again
Attention toute fois, lorsque le framework ICanBoogie
est lancé (sa méthode run() a été appelée) l'opération peut s'avérer périlleuse parce que les
configurations des modules peuvent avoir été traitées, notamment celle des évènements.
Démarrage des modules
Les modules disposent d'une méthode run() qui leur offre des possibilités de démarrage
supplémentaires, si la valeur de la propriété autorun de l'accesseur est vraie
elle est appelée après l'initialisation du module, lors de son premier chargement :
<?php
$modules->autorun = true
La méthode run() de l'accesseur peut être utilisée pour démarrer tous les modules actifs qui
définissent l'attribut T_STARTUP, qui donne le poid du module dans la chaîne de démarrage.
<?php
$modules->run();
Connaître les modules en cours d'exécution
Il est possible de connaitre les modules en cours d'exécution, pour cela il convient d'utiliser l'accesseur comme un itérateur :
<?php
foreach ($modules as $module_id => $module)
{
echo 'The module <em>' . $module[Module\T_TITLE] . '</em> with id <code>' . $module_id . '</code> is running.<br />';
}
Indexation des modules
Chaque module possède un descripteur, il s'agit d'un tableau associatif qui contient les attributs à utiliser pour créer le module ainsi que ses modèles de données. Ce tableau est renvoyé par un fichier « descriptor.php » qui se trouve à la racine du dossier de chacun des modules.
L'indexation des modules consiste à rassembler ces descripteurs afin de référencer les modules disponibles, mais aussi à constituer une liste des dossiers de traductions, une liste des dossiers de configurations, une liste des classes à charger automatiquement ainsi qu'une liste des constructeurs de configurations. Ces informations supplémentaires sont généralement utilisées pour configurer les composants bas niveau du framework.
L'indexation se fait à partir des chemins définis par le paramètre paths fourni lors de l'instanciation
de l'accesseur. Dans le cadre d'une utilisation classique du framework
ICanBoogie, les chemins vers les dossiers contenant les
modules sont définis par la clé modules de la configuration core :
<?php
return array
(
'modules' => array
(
$path . 'modules'
)
);
Les descripteurs de modules
Une fois l'indexation terminée la propriété descriptors contient les descripteurs des modules :
<?php
$descriptors = $modules->descriptors;
if (isset($descriptors['nodes']))
{
echo 'descriptor for module "node": ';
var_dump($descriptors['nodes']);
}
En outre, les propriétés magiques enabled_modules_descriptors et disabled_modules_descriptors
contiennent respectivement les descripteurs des modules actifs et ceux des modules inactifs :
<?php
echo "enabled modules: " . implode(', ', array_keys($modules->enabled_modules_descriptors)) . '.<br />';
echo "disabled modules: " . implode(', ', array_keys($modules->disabled_modules_descriptors)) . '.<br />';
Mise en cache de l'index
Afin de réduire l'impact de l'indexation des modules sur les performances du framework, l'index
des modules peut être mit en cache. Pour cela, il convient de définir le
paramètre use_cache à true lors de l'instanciation de l'accesseur. Dans le cadre d'une
utilisation classique du framework ICanBoogie, la
valeur du paramètre use_cache peut être définie en utilisant la clé cache modules de la
configuration core :
<?php
return array
(
'cache modules' => true
);
Utiliser une autre classe pour l'accesseur
Parce que l'accesseur est obtenu par le getter __get_modules() il est possible de surcharger la
méthode de la classe ICanBoogie\Core pour fournir un accesseur amélioré. Voici par exemple un
extrait de la classe Icybee\Core :
<?php
namespace Icybee;
use ICanBoogie;
class Core extends ICanBoogie\Core
{
...
protected function __get_modules()
{
$config = $this->config;
return new Accessor\Modules($config['modules'], $config['cache modules'], $config['repository.cache'] . '/core');
}
...
}
Ainsi qu'un extrait de son accesseur :
<?php
namespace Icybee\Accessor;
use ICanBoogie;
use ICanBoogie\Module;
class Modules extends ICanBoogie\Accessor\Modules
{
public function run()
{
global $core;
$enableds = (array) json_decode($core->vars['enabled_modules'], true);
foreach ($this->descriptors as $module_id => &$descriptor)
{
if (!empty($descriptor[Module::T_REQUIRED]) || in_array($module_id, $enableds))
{
continue;
}
$descriptor[Module::T_DISABLED] = true;
}
parent::run();
}
protected function index_module($id, $path)
{
$info = parent::index_module($id, $path);
if (file_exists($path . 'manager.php'))
{
$class = 'Icybee\Manager\\' . ICanBoogie\normalize_namespace_part($id);
$info['autoload'][$class] = $path . 'manager.php';
}
return $info;
}
...
Conclusion
Voilà pour notre présentation de l'accesseur « modules », pour les plus curieux son code source est consultable sur Github.