Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
75.00% covered (warning)
75.00%
6 / 8
CRAP
84.06% covered (warning)
84.06%
58 / 69
ModuleManager
0.00% covered (danger)
0.00%
0 / 1
75.00% covered (warning)
75.00%
6 / 8
27.53
84.06% covered (warning)
84.06%
58 / 69
 __construct
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
15 / 15
 loadModuleFile
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
5 / 5
 loadModule
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
6 / 6
 install
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
22 / 22
 listAvailableModules
0.00% covered (danger)
0.00%
0 / 1
30
0.00% covered (danger)
0.00%
0 / 10
 getModuleFromId
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
5 / 5
 isInstalling
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 __get
0.00% covered (danger)
0.00%
0 / 1
3.07
80.00% covered (warning)
80.00%
4 / 5
<?php 
namespace Tools;
/**
 * Container all modules.
 * Allow module managment
**/
class ModuleManager
{
    /**
     * @var \Tools\Context $context
     * /core/tools/Context.php
     * Contains website's informations
    **/
    private $context;
    /**
     * @var array(\Tool\AModule) $modules
     * /core/tools/AModule.php
     * Contains all loaded modules
     * Can be accessed read-only via $instance->modules
    **/
    private $modules = array();
    /**
     * @var boolean $installing true if a module is currently installing
    **/
    private static $installing = false;
    /**
     * @var _id_{ID}
     * Get the module identified with id ID
     * ex: $context->moduleManager->_id_2 will return module with id 2
    **/
    /**
     * @param \Tool\Context $context
     * Load all active modules from database.
     * Enable hooks for these modules
     * Disable them if the module cannot be loaded
    **/
    public function __construct(&$context)
    {
        $this->context = $context;
        $modulesRoot = $context->router->modulesPath;
        $modules = \Entity\Module::getActivated();
        $ids = array();
        foreach ($modules as $i)
        {
            $modulePath = "{$modulesRoot}{$i->directory}/main.php";
            if (file_exists($modulePath) && $this->loadModule($modulePath, $i))
            {
                $ids[] = $i->id;
            }
            else
            {
                $i->active = false;
                $i->save();
            }
        }
        $context->hookManager->loadHooks(\Entity\ModuleHook::getModules($ids));
    }
    /**
     * @param string $path
     * @return \Tools\AModule loaded module (or false on error)
    **/
    private function loadModuleFile($path)
    {
        $mod = include_once($path);
        if (!$mod || !($mod instanceof \Tools\AModule))
            return false;
        $mod->setContext($this->context);
        return $mod;
    }
    /**
     * @param string $path path to module's main file
     * @param \Entity\Module $module module's database object to load
     * /core/models/Module.php
     * @return TRUE on success
     * Will try to load module located at $path.
     * This function will include the main.php file located in the module's directory
     * The file MUST return an AModule object to be considered as successfull
     * /core/tools/AModule.php
    **/
    private function loadModule($path, $module)
    {
        $mod = $this->loadModuleFile($path);
        if ($mod === false)
            return false;
        $mod->setEntity($module);
        $this->modules[] = $mod;
        return true;
    }
    /**
     * @param string $modulename
     * @return \tools\AModule|false on failure
     * Install the module located in {modulePath}/modulename/modulename.php
    **/
    public function install($modulename)
    {
        $entity = new \Entity\Module();
        $entity->name = $modulename;
        $entity->directory = $modulename;
        $entity->active = true;
        $module = $this->loadModuleFile($this->context->router->modulesPath.$modulename.'/main.php');
        if ($module === false)
            return false;
        $module->setEntity($entity);
        $entity->name = $module->getName();
        $entity->description = $module->getDescription();
        $entity->save();
        self::$installing = true;
        if ($module->install() == false)
        {
            self::$installing = false;
            $hooks = \Entity\ModuleHook::getModules($entity->id);
            foreach ($hooks as $i)
                $i->delete();
            $entity->delete();
            return false;
        }
        self::$installing = false;
        return $module;
    }
    /*
     * TODO revoir tout
     * @return array(AModule)
     * Will load every modules, and return them.
    **/
    public function listAvailableModules()
    {
        $modulesRoot = $context->router->modulesPath;
        $result = array();
        $modules = scandir($modulesRoot, SCANDIR_SORT_NONE);
        foreach ($modules as $i)
        {
            $path = $modulesRoot.$i;
            if ($i == '.' || $i == '..' || !is_dir($path))
                continue;
            $this->loadModule($path);
        }
    }
    /**
     * @param int $id
     * @return AModule on success, FALSE on failure (no such ID / module not loaded)
     * Get the module identified with id ID
    **/
    public function getModuleFromId($id)
    {
        foreach ($this->modules as $i)
        {
            if ($i->entity->id == $id)
                return $i;
        }
        return FALSE;
    }
    /**
     * @return true if a module is currently installing
    **/
    public static function isInstalling()
    { return self::$installing; }
    /**
     * Getter
    **/
    public function __get($key)
    {
        switch ($key)
        {
            case "modules":
                return $this->modules; break;
        }
        if (substr($key, 0, 4) == "_id_")
            return $this->getModuleFromId((int) substr($key, 4));
        throw new \Exception("Cannot access attribute {$key}");
    }
}