LOADS CONFIG * */ public function __construct(){ $this->packages = json_decode( file_get_contents(self::config_path()), true); } /* REMOVES ENABLED MODULES * */ public function init(){ $this->packages['installed'] = []; $this->store(); return true; } /* RETURNS AVAILABLE MODULE LIST * * @return packages Set containing packages and their versions * */ public function available(){ $packages = []; foreach($this->packages['available'] as $package=>$versions){ $packages[$package] = []; foreach($versions as $version=>$dependencies) // if version of package enabled if( isset($this->packages['installed'][$package]) && $version == $this->packages['installed'][$package] ) $packages[$package][] = [ 'version' => $version, 'enabled' => true ]; else $packages[$package][] = [ 'version' => $version, 'enabled' => false ]; } return $packages; } /* ENABLES A MODULE'S VERSION * * @pPackage Package's name * @pVersion Package's version * @pDep dependency level * * @return err_msg Error message | TRUE (if all is ok) * */ public function install($pPackage=null, $pVersion=null, $pDep=0){ /* [1] Package management =========================================================*/ /* (1) If @package not given, exit */ if( is_null($pPackage) ) return "Missing @packageName.\n"; /* (2) Checking package existence */ if( !isset($this->packages['available'][$pPackage]) ) return "Package `$pPackage` unknown.\n"; /* (3) Set package name & content */ $mname = $pPackage; $package = $this->packages['available'][$mname]; /* [2] Version management =========================================================*/ /* (1) Set default latest version name & content */ $vname = array_slice( array_keys($package), -1 )[0]; $dependencies = $package[$vname]; $flag = '#latest'; /* (2) Existing version set it */ if( !is_null($pVersion) && isset($package[$pVersion]) ){ $dependencies = $package[( $vname = $pVersion )]; $flag = ''; } /* [3] Enables package & version =========================================================*/ /* (1) If package disabled -> enables it */ if( !isset($this->packages['installed'][$mname]) ) $this->packages['installed'][$mname] = '0'; /* (2) Checks cross version dependency -> if another installed package needs another version */ foreach($this->packages['installed'] as $xPackage=>$xVersion){ // {2.1} Loads each installed package's dependencies // $xDependencies = $this->getDependencies($xPackage,$xVersion); // if not found -> next if( $xDependencies === false ) continue; // {2.2} if package can't have version of current package // if( isset($xDependencies[$mname]) && !in_array($vname, $xDependencies[$mname]) ) return str_repeat(" ", $pDep)."$xPackage:$xVersion doesn't support $mname:$vname\n\n** aborted **\n"; } /* (5) If no conflict -> set version */ echo str_repeat(" ", $pDep)."[$mname:$vname] $flag\n"; // in any case -> store new package's version $this->packages['installed'][$mname] = $vname; /* [4] Loading dependencies =========================================================*/ /* (1) Loading each dependency */ if( count($dependencies) > 0 ){ foreach($dependencies as $depMod=>$depVersions){ // Only load last version foreach($depVersions as $version) $installed = $this->install($depMod, $version, $pDep+1); // error propagation if( $installed !== true ) return $installed; } } /* [5] Storing data =========================================================*/ $this->store(); return true; } /* DISABLES A MODULE'S VERSION * * @pPackage Package's name * * @return err_msg Error message || TRUE if success * */ public function remove($pPackage=null){ /* [1] Package management (existence) =========================================================*/ /* (1) If @package not given, exit */ if( is_null($pPackage) ) return "Missing @packageName.\n"; /* (2) Checking if package is enabled */ $enabled_packages = array_keys($this->packages['installed']); if( !in_array($pPackage, $enabled_packages) ) return "Package `$pPackage` not enabled.\n"; /* (3) Set package name & content */ $mname = $pPackage; $package = $this->packages['installed'][$mname]; /* [2] Dependency verification (not needed) =========================================================*/ $dependency = false; // if it's a dependency of another enabled package $callers = []; // list of enabled packages that needs current one /* (1) For each enabled package (excepted itself) */ foreach($enabled_packages as $package){ // except current package if( $package == $mname ) continue; /* (2) For each version of its package (and its dependencies) */ foreach($this->packages['available'][$package] as $version=>$dependencies){ // if not the current enabled package's version if( $version != $this->packages['installed'][$package] ) continue; /* (3) If current package in dependencies -> can't disable */ isset($dependencies[$mname]) && ($dependency = true) && ($callers[] = "`$package`"); } } /* (4) If a dependency, explain */ if( $dependency ) return "Cannot disable package $mname because ".implode(',',$callers)." needs it.\n"; /* [3] Disabling package =========================================================*/ /* (1) Disabling package */ unset($this->packages['installed'][$mname]); /* (2) Storing changes */ $this->store(); /* (3) Return success */ return true; } /* BUILDS A PROJECT * * @pPath Path to project root * */ public function build($pPath){ $builder = new Builder($pPath, $this->packages['installed']); $builder->build(); } /* RETURNS THE LIST OF THE DEPENDENCIES OF A MODULE * * @package Package's label * @version Package's version * * @return dependencies List of dependencies * FALSE if error * */ private function getDependencies($package=null, $version=null){ /* [1] Search for package =========================================================*/ /* (1) Checks package */ if( !isset($this->packages['available'][$package]) ) return false; /* (2) Checks version */ if( !isset($this->packages['available'][$package][$version]) ) return false; /* [2] Returns dependencies =========================================================*/ /* (1) If not an array */ if( !is_array($this->packages['available'][$package][$version]) ) return []; /* (2) If all right */ return $this->packages['available'][$package][$version]; } /* STORES DATA * */ public function store(){ file_put_contents(self::config_path(), json_encode($this->packages, JSON_PRETTY_PRINT)); } } ?>