xdrm-framework/exporter/Exporter.php

306 lines
7.9 KiB
PHP

<?php if( !defined('__ROOT__') ) define('__ROOT__', dirname(dirname(__FILE__)) );
require_once 'Builder.php';
class Exporter{
private $modules; // will contain modules (config)
public static function config_path(){ return __ROOT__.'/exporter/modules.json'; }
/* CONSTRUCTOR -> LOADS CONFIG
*
*/
public function __construct(){
$this->modules = json_decode( file_get_contents(self::config_path()), true);
}
/* REMOVES ENABLED MODULES
*
*/
public function init(){
$this->modules['enabled'] = [];
$this->store();
return true;
}
/* RETURNS AVAILABLE MODULE LIST
*
* @return modules<Array> Set containing modules and their versions
*
*/
public function available(){
$modules = [];
foreach($this->modules['available'] as $module=>$versions){
$modules[$module] = [];
foreach($versions as $version=>$dependencies)
// if version of module enabled
if( isset($this->modules['enabled'][$module]) && $version == $this->modules['enabled'][$module] )
$modules[$module][] = [ 'version' => $version, 'enabled' => true ];
else
$modules[$module][] = [ 'version' => $version, 'enabled' => false ];
}
return $modules;
}
/* ENABLES A MODULE'S VERSION
*
* @pModule<String> Module's name
* @pVersion<String> Module's version
* @pDep<Boolean> dependency level
*
* @return err_msg<String> Error message | TRUE (if all is ok)
*
*/
public function enable($pModule=null, $pVersion=null, $pDep=0){
/* [1] Module management
=========================================================*/
/* (1) If @module not given, exit */
if( is_null($pModule) )
return "Missing @moduleName.\n";
/* (2) Checking module existence */
if( !isset($this->modules['available'][$pModule]) )
return "Module `$pModule` unknown.\n";
/* (3) Set module name & content */
$mname = $pModule;
$module = $this->modules['available'][$mname];
/* [2] Version management
=========================================================*/
/* (1) Set default version name & content */
$vname = array_slice( array_keys($module), -1 )[0];
$version = $module[$vname];
/* (2) If wrong version given, set to default */
if( is_null($pVersion) || !isset($module[$pVersion]) )
echo "chosing latest version:\n-----------------------\n [x] $mname:$vname (can throw errors)\n\n";
/* (2) Else, we get given @version */
else
$version = $module[( $vname = $pVersion )];
/* [3] Enables module & version
=========================================================*/
/* (1) If module disabled -> enables it */
if( !isset($this->modules['enabled'][$mname]) )
$this->modules['enabled'][$mname] = '0';
/* (3) Checks cross version dependency -> trying to enable lower-than-required version of a module*/
$crossDep = false;
// For each available module
foreach($this->modules['enabled'] as $xModule=>$xVersion){
// Loads each module's dependencies
if( !isset($this->modules['available'][$xModule][$xVersion]) )
continue;
$xDependencies = $this->modules['available'][$xModule][$xVersion];
// if module needs a higher version of current module
if( isset($xDependencies[$mname]) && $this->lower($this->modules['available'][$mname], $vname, $xDependencies[$mname]) ){
$crossDep = true;
break;
}
}
/* (4) If trying to load lower than required version -> error */
if( $crossDep ){
// Update module's version
if( $this->lower($this->modules['available'][$mname], $this->modules['enabled'][$mname], $xDependencies[$mname]) )
$this->modules['enabled'][$mname] = $xDependencies[$mname];
$this->store();
return "module `$xModule:$xVersion` needs `$mname:".$xDependencies[$mname]."`\n\naborted.\n";
}
/* (5) If not a dependency or higher version -> set/update version */
if( $pDep == 0 || $this->lower($module, $this->modules['enabled'][$mname], $vname) ){
// if a dependency, set new params
if( $pDep > 0 )
echo str_repeat(" ", $pDep)."[x] $mname:$vname ($mname:$vname+ required)\n";
else
echo str_repeat(" ", $pDep)."[x] $mname:$vname\n";
// in any case -> store new module's version
$this->modules['enabled'][$mname] = $vname;
}else if( $pDep > 0 )
echo str_repeat(" ", $pDep)."[x] $mname:".$this->modules['enabled'][$mname]." ($mname:$vname+ required)\n";
/* [4] Loading dependencies
=========================================================*/
/* (1) Loading each dependency */
if( count($version) > 0 ){
echo "\n".str_repeat(" ", $pDep);
echo "dependencies:\n";
foreach($version as $depMod=>$depVer)
$enabled = $this->enable($depMod, $depVer, $pDep+1);
}
/* [5] Storing data
=========================================================*/
$this->store();
return true;
}
/* DISABLES A MODULE'S VERSION
*
* @pModule<String> Module's name
*
* @return err_msg<String> Error message || TRUE if success
*
*/
public function disable($pModule=null){
/* [1] Module management (existence)
=========================================================*/
/* (1) If @module not given, exit */
if( is_null($pModule) )
return "Missing @moduleName.\n";
/* (2) Checking if module is enabled */
$enabled_modules = array_keys($this->modules['enabled']);
if( !in_array($pModule, $enabled_modules) )
return "Module `$pModule` not enabled.\n";
/* (3) Set module name & content */
$mname = $pModule;
$module = $this->modules['enabled'][$mname];
/* [2] Dependency verification (not needed)
=========================================================*/
$dependency = false; // if it's a dependency of another enabled module
$callers = []; // list of enabled modules that needs current one
/* (1) For each enabled module (excepted itself) */
foreach($enabled_modules as $module){
// except current module
if( $module == $mname ) continue;
/* (2) For each version of its module (and its dependencies) */
foreach($this->modules['available'][$module] as $version=>$dependencies){
// if not the current enabled module's version
if( $version != $this->modules['enabled'][$module] )
continue;
/* (3) If current module in dependencies -> can't disable */
isset($dependencies[$mname]) && ($dependency = true) && ($callers[] = "`$module`");
}
}
/* (4) If a dependency, explain */
if( $dependency )
return "Cannot disable module $mname because ".implode(',',$callers)." needs it.\n";
/* [3] Disabling module
=========================================================*/
/* (1) Disabling module */
unset($this->modules['enabled'][$mname]);
/* (2) Storing changes */
$this->store();
/* (3) Return success */
return true;
}
/* BUILDS A PROJECT
*
* @pPath<String> Path to project root
*
*/
public function build($pPath){
$builder = new Builder($pPath, $this->modules['enabled']);
$builder->build();
}
/* CHECKS IF @pFirst IS LOWER THAN @pSecond VERSION
*
* @pModule<Array> Module's content
* @pFirst<String> First version
* @pSecond<String> Second version
*
* @return lower<Boolean> Returns if @pFirst is lower
*
* Note: Supposing that @pFirst and @pSecond are keys of @pModule (no check)
*
*/
public function lower($pModule, $pFirst, $pSecond){
/* (1) Get @pModule keys */
$keys = array_keys($pModule);
/* (1) Get @pFirst index */
$pf_index = array_search($pFirst, $keys);
/* (2) Get @pSecond index */
$ps_index = array_search($pSecond, $keys);
if( $pf_index === false )
return true;
return $pf_index < $ps_index;
}
/* STORES DATA
*
*/
public function store(){
file_put_contents(self::config_path(), json_encode($this->modules, JSON_PRETTY_PRINT));
}
}
?>