From 0554dab3aee05abd33048f5da6e620184238860d Mon Sep 17 00:00:00 2001 From: Uwe Steinmann Date: Tue, 13 Mar 2018 14:37:55 +0100 Subject: [PATCH] various new methonds move cmpVersion() from inc.Utils.php nach inc.ClassExtensionMgr.php --- inc/inc.ClassExtensionMgr.php | 220 +++++++++++++++++++++++++++++++--- inc/inc.Utils.php | 33 ----- 2 files changed, 206 insertions(+), 47 deletions(-) diff --git a/inc/inc.ClassExtensionMgr.php b/inc/inc.ClassExtensionMgr.php index 2ab452e6e..99310e549 100644 --- a/inc/inc.ClassExtensionMgr.php +++ b/inc/inc.ClassExtensionMgr.php @@ -32,6 +32,12 @@ class SeedDMS_Extension_Mgr { */ protected $extdir; + /** + * @var array[] $extconf configuration of all extensions + * @access protected + */ + protected $extconf; + /** * @var string $cachedir directory where cached extension configuration * is stored @@ -39,25 +45,89 @@ class SeedDMS_Extension_Mgr { */ protected $cachedir; + /** + * @var string[] $errmsg list of error message from last operation + * @access protected + */ + protected $errmsgs; - function __construct($extdir = '', $cachedir = '') { + /** + * Compare two version + * + * This functions compares two version in the format x.x.x + * + * @param string $ver1 + * @param string $ver2 + * @return int -1 if $ver1 < $ver2, 0 if $ver1 == $ver2, 1 if $ver1 > $ver2 + */ + static public function cmpVersion($ver1, $ver2) { /* {{{ */ + $tmp1 = explode('.', $ver1); + $tmp2 = explode('.', $ver2); + if(intval($tmp1[0]) < intval($tmp2[0])) { + return -1; + } elseif(intval($tmp1[0]) > intval($tmp2[0])) { + return 1; + } else { + if(intval($tmp1[1]) < intval($tmp2[1])) { + return -1; + } elseif(intval($tmp1[1]) > intval($tmp2[1])) { + return 1; + } else { + if(intval($tmp1[2]) < intval($tmp2[2])) { + return -1; + } elseif(intval($tmp1[2]) > intval($tmp2[2])) { + return 1; + } else { + return 0; + } + } + } + } /* }}} */ + + /** + * Constructor of extension manager + * + * Reads the configuration of all extensions and creates the + * configuration file if it does not exist and the extension dir + * is given + */ + public function __construct($extdir = '', $cachedir = '') { $this->cachedir = $cachedir; $this->extdir = $extdir; + $this->extconf = array(); + if($extdir) { + if(!file_exists($this->getExtensionsConfFile())) { + $this->createExtensionConf(); + } + include($this->getExtensionsConfFile()); + if($EXT_CONF) { + $this->extconf = $EXT_CONF; + } + } } - function getExtensionsConfFile() { /* {{{ */ + protected function getExtensionsConfFile() { /* {{{ */ return $this->cachedir."/extensions.php"; } /* }}} */ + /** + * Get the configuration of extensions + * + * @return array[] + */ + public function getExtensionConfiguration() { /* {{{ */ + return $this->extconf; + } /* }}} */ + /** * Create the cached file containing extension information * * This function will always create a file, even if no extensions * are installed. */ - function createExtensionConf() { /* {{{ */ + public function createExtensionConf() { /* {{{ */ $extensions = self::getExtensions(); - $fp = fopen(self::getExtensionsConfFile(), "w"); + $fp = @fopen(self::getExtensionsConfFile(), "w"); if($fp) { if($extensions) { foreach($extensions as $_ext) { @@ -74,7 +144,7 @@ class SeedDMS_Extension_Mgr { } } /* }}} */ - function getExtensions() { /* {{{ */ + protected function getExtensions() { /* {{{ */ $extensions = array(); if(file_exists($this->extdir)) { $handle = opendir($this->extdir); @@ -103,6 +173,92 @@ class SeedDMS_Extension_Mgr { return $tmpfile; } /* }}} */ + /** + * Check content of extension directory + * + * @param string $dir full path to extension directory or extension name + * @param boolean $noconstraints set to true if constraints to local seeddms + * installation shall not be checked. + */ + public function checkExtension($dir, $noconstraints=false) { /* {{{ */ + $this->errmsgs = array(); + + if(!file_exists($dir)) { + if(!file_exists($this->extdir.'/'.$dir)) + return false; + else + $dir = $this->extdir.'/'.$dir; + } + if(!file_exists($dir."/conf.php")) { + $this->errmsgs[] = "Missing extension configuration"; + return false; + } + include($dir."/conf.php"); + if(!isset($EXT_CONF)) { + $this->errmsgs[] = "Missing \$EXT_CONF in configuration"; + return false; + } + $extname = key($EXT_CONF); + if(!$extname || !preg_match('/[a-zA-Z_]*/', $extname)) { + return false; + } + + $extconf = $EXT_CONF[$extname]; + if(!isset($extconf['constraints']['depends']['seeddms'])) { + $this->errmsgs[] = "Missing dependency on SeedDMS"; + } + if(!isset($extconf['constraints']['depends']['php'])) { + $this->errmsgs[] = "Missing dependency on PHP"; + } + if(!isset($extconf['version'])) { + $this->errmsgs[] = "Missing version information"; + } + if(!isset($extconf['title'])) { + $this->errmsgs[] = "Missing title"; + } + if(!isset($extconf['author'])) { + $this->errmsgs[] = "Missing author"; + } + if(!empty($extconf['language']['file']) && !file_exists($dir."/".$extconf['language']['file'])) { + $this->errmsgs[] = "Missing language file"; + } + if(!empty($extconf['class']['file']) && !file_exists($dir."/".$extconf['class']['file'])) { + $this->errmsgs[] = "Missing class file"; + } + + if(!$noconstraints && isset($extconf['constraints']['depends'])) { + foreach($extconf['constraints']['depends'] as $dkey=>$dval) { + switch($dkey) { + case 'seeddms': + $version = new SeedDMS_Version; + $tmp = explode('-', $dval, 2); + if(self::cmpVersion($tmp[0], $version->version()) > 0 || ($tmp[1] && self::cmpVersion($tmp[1], $version->version()) < 0)) + $this->errmsgs[] = sprintf("Incorrect SeedDMS version (needs version %s)", $extconf['constraints']['depends']['seeddms']); + break; + case 'php': + $tmp = explode('-', $dval, 2); + if(self::cmpVersion($tmp[0], phpversion()) > 0 || ($tmp[1] && self::cmpVersion($tmp[1], phpversion()) < 0)) + $this->errmsgs[] = sprintf("Incorrect PHP version (needs version %s)", $extconf['constraints']['depends']['php']); + break; + default: + $tmp = explode('-', $dval, 2); + if(isset($GLOBALS['EXT_CONF'][$dkey]['version'])) { + if(self::cmpVersion($tmp[0], $GLOBALS['EXT_CONF'][$dkey]['version']) > 0 || ($tmp[1] && self::cmpVersion($tmp[1], $GLOBALS['EXT_CONF'][$dkey]['version']) < 0)) + $this->errmsgs[] = sprintf("Incorrect version of extension '%s' (needs version '%s' but provides '%s')", $dkey, $dval, $GLOBALS['EXT_CONF'][$dkey]['version']); + } else { + $this->errmsgs[] = sprintf("Missing extension or version for '%s'", $dkey); + } + break; + } + } + } + + if($this->errmsgs) + return false; + + return true; + } /* }}} */ + static protected function rrmdir($dir) { /* {{{ */ if (is_dir($dir)) { $objects = scandir($dir); @@ -116,41 +272,77 @@ class SeedDMS_Extension_Mgr { } } /* }}} */ + /** + * Update an extension + * + * This function will replace an existing extension or add a new extension + * The passed file has to be zipped content of the extension directory not + * including the directory itself. + * + * @param string $file name of extension archive + * @return boolean true on success, othewise false + */ public function updateExtension($file) { /* {{{ */ $newdir = $this->cachedir ."/ext.new"; if(!mkdir($newdir, 0755)) { + $this->errmsgs[] = "Cannot create temp. extension directory"; return false; } $cmd = "cd ".$newdir."; unzip ".$file; exec($cmd); - if(!file_exists($newdir."/conf.php")) { + if(!self::checkExtension($newdir)) { self::rrmdir($newdir); return false; } include($newdir."/conf.php"); - if(!isset($EXT_CONF)) { - self::rrmdir($newdir); - return false; - } $extname = key($EXT_CONF); - if(!$extname || !preg_match('/[a-zA-Z_]*/', $extname)) { - self::rrmdir($newdir); - return false; - } + /* Create the target directory */ if(!is_dir($this->extdir)) { if(!mkdir($this->extdir, 0755)) { + $this->errmsgs[] = "Cannot create extension directory"; self::rrmdir($newdir); return false; } } elseif(is_dir($this->extdir ."/". $extname)) { $this->rrmdir($this->extdir ."/". $extname); } + /* Move the temp. created ext directory to the final location */ rename($newdir, $this->extdir ."/". $extname); return true; } /* }}} */ + /** + * Import list of extension from repository + * + */ + public function importExtensionList($url) { /* {{{ */ + $file = file_get_contents($url."/repository.json"); + file_put_contents($this->cachedir."/repository.json", $file); + return file($this->cachedir."/repository.json"); + } /* }}} */ + + /** + * Return last error message + * + * @return string + */ + public function getErrorMsg() { /* {{{ */ + if($this->errmsgs) + return $this->errmsgs[0]; + else + return ''; + } /* }}} */ + + /** + * Return all error messages + * + * @return string[] + */ + public function getErrorMsgs() { /* {{{ */ + return $this->errmsgs; + } /* }}} */ } diff --git a/inc/inc.Utils.php b/inc/inc.Utils.php index 1532ea793..c2c7829ad 100644 --- a/inc/inc.Utils.php +++ b/inc/inc.Utils.php @@ -79,39 +79,6 @@ function getReadableDurationArray($secs) { /* {{{ */ return $units; } /* }}} */ -/** - * Compare two version - * - * This functions compares two version in the format x.x.x - * - * @param string $ver1 - * @param string $ver2 - * @return int -1 if $ver1 < $ver2, 0 if $ver1 == $ver2, 1 if $ver1 > $ver2 - */ -function cmpVersion($ver1, $ver2) { - $tmp1 = explode('.', $ver1); - $tmp2 = explode('.', $ver2); - if(intval($tmp1[0]) < intval($tmp2[0])) { - return -1; - } elseif(intval($tmp1[0]) > intval($tmp2[0])) { - return 1; - } else { - if(intval($tmp1[1]) < intval($tmp2[1])) { - return -1; - } elseif(intval($tmp1[1]) > intval($tmp2[1])) { - return 1; - } else { - if(intval($tmp1[2]) < intval($tmp2[2])) { - return -1; - } elseif(intval($tmp1[2]) > intval($tmp2[2])) { - return 1; - } else { - return 0; - } - } - } -} - // // The original string sanitizer, kept for reference. //function sanitizeString($string) {