Index: tests/t3lib/matchcondition/t3lib_matchcondition_frontendTest.php =================================================================== --- tests/t3lib/matchcondition/t3lib_matchcondition_frontendTest.php (révision 8932) +++ tests/t3lib/matchcondition/t3lib_matchcondition_frontendTest.php (copie de travail) @@ -620,5 +620,13 @@ '[globalString = ' . $this->testGlobalNamespace . '|second|third = testThird]' )); } + + /** + * Tests whether extension comparison to a specific version matches. + * @test + */ + public function extConditionMatchesVersion() { + $this->assertTrue($this->matchCondition->match('[ext=phpunit:version > 3.4.11]')); + } =================================================================== --- t3lib/class.t3lib_extmgm.php (révision 8932) +++ t3lib/class.t3lib_extmgm.php (copie de travail) @@ -231,6 +231,162 @@ } /** + * Returns version information + * + * @param string Version code, x.x.x + * @param string version part: "", "int", "main", "sub", "dev" + * @return string + * @see renderVersion() + */ + static public function makeVersion ($version, $mode) { + $vDat = self::renderVersion($version); + $rc = $vDat['version_' . $mode]; + return $rc; + } + + /** + * Evaluates differences in version numbers with three parts, x.x.x. Returns TRUE if $v1 is greater than $v2 + * + * @param string Version number 1 + * @param string Version number 2 + * @param string comparator string for the version compare + * @param integer Tolerance factor. For instance, set to 1000 to ignore difference in dev-version (third part) + * @return boolean True if version 1 is greater than version 2 + */ + static public function versionDifference ($version1, $version2, $comparator = '', $tolerance = 1) { + $rc = FALSE; + $leftValue = floor(self::makeVersion($version1, 'int')/$tolerance); + $rightValue = floor(self::makeVersion($version2, 'int')/$tolerance); + if (!$comparator) { + $comparator = '>'; + } + $rc = self::testNumber($comparator . $rightValue, $leftValue); + return $rc; + } + + /** + * Evaluates a $leftValue based on an operator: "<", ">", "<=", ">=", "!=" or "=" + * + * @param string $test: The value to compare with on the form [operator][number]. Eg. "< 123" + * @param integer $leftValue: The value on the left side + * @return boolean If $value is "50" and $test is "< 123" then it will return TRUE. + */ + static public function testNumber ($test, $leftValue) { + $test = trim($test); + + $rc = FALSE; + if (preg_match('/^(!?=+|<=?|>=?)\s*([^\s]*)\s*$/', $test, $matches)) { + $operator = $matches[1]; + $rightValue = $matches[2]; + + switch ($operator) { + case '>=': + $rc = ($leftValue >= doubleval($rightValue)); + break; + case '<=': + $rc = ($leftValue <= doubleval($rightValue)); + break; + case '!=': + $rc = ($leftValue != doubleval($rightValue)); + break; + case '<': + $rc = ($leftValue < doubleval($rightValue)); + break; + case '>': + $rc = ($leftValue > doubleval($rightValue)); + break; + default: + // nothing valid found except '=', use '=' + $rc = ($leftValue == trim($rightValue)); + } + } + + return $rc; + } + + /** + * Parses the version number x.x.x and returns an array with the various parts. + * + * @param string Version code, x.x.x + * @param string Increase version part: "main", "sub", "dev" + * @return string + */ + static public function renderVersion ($version, $raise = '') { + $parts = t3lib_div::intExplode('.', $version . '..'); + $parts[0] = t3lib_div::intInRange($parts[0], 0, 999); + $parts[1] = t3lib_div::intInRange($parts[1], 0, 999); + $parts[2] = t3lib_div::intInRange($parts[2], 0, 999); + + switch((string)$raise) { + case 'main': + $parts[0]++; + $parts[1] = 0; + $parts[2] = 0; + break; + case 'sub': + $parts[1]++; + $parts[2] = 0; + break; + case 'dev': + $parts[2]++; + break; + } + + $res = array(); + $res['version'] = $parts[0] . '.' . $parts[1] . '.' . $parts[2]; + $res['version_int'] = intval($parts[0] * 1000000 + $parts[1] * 1000 + $parts[2]); + $res['version_main'] = $parts[0]; + $res['version_sub'] = $parts[1]; + $res['version_dev'] = $parts[2]; + + return $res; + } + + /** + * Gets information for an extension, eg. version and most-recently-edited-script + * + * @param string Extension key + * @return array Information array (unless an error occured) + */ + static public function getExtensionInfo ($extensionKey) { + $rc = ''; + + if (self::isLoaded($extensionKey)) { + $path = self::extPath($extensionKey); + $file = $path . '/ext_emconf.php'; + if (@is_file($file)) { + $_EXTKEY = $extensionKey; + $EM_CONF = array(); + include($file); + + $info = array(); + // Info from emconf: + $info['title'] = $EM_CONF[$extensionKey]['title']; + $info['author'] = $EM_CONF[$extensionKey]['author']; + $info['author_email'] = $EM_CONF[$extensionKey]['author_email']; + $info['author_company'] = $EM_CONF[$extensionKey]['author_company']; + $info['version'] = $EM_CONF[$extensionKey]['version']; + $info['CGLcompliance'] = $EM_CONF[$extensionKey]['CGLcompliance']; + $info['CGLcompliance_note'] = $EM_CONF[$extensionKey]['CGLcompliance_note']; + if (is_array($EM_CONF[$extensionKey]['constraints']) && is_array($EM_CONF[$extensionKey]['constraints']['depends'])) { + $info['TYPO3_version'] = $EM_CONF[$extensionKey]['constraints']['depends']['typo3']; + } else { + $info['TYPO3_version'] = $EM_CONF[$extensionKey]['TYPO3_version']; + } + $filesHash = unserialize($EM_CONF[$extensionKey]['_md5_values_when_last_written']); + $info['manual'] = @is_file($path . '/doc/manual.sxw'); + $rc = $info; + } else { + $rc = 'ERROR: No emconf.php file: ' . $file; + } + } else { + $rc = 'Error: Extension ' . $extensionKey . ' has not been installed. (patch10011_extMgm::getExtensionInfo)'; + } + + return $rc; + } + + /** * Clears the extension key map. * * @return void Index: t3lib/matchcondition/class.t3lib_matchcondition_abstract.php =================================================================== --- t3lib/matchcondition/class.t3lib_matchcondition_abstract.php (révision 8932) +++ t3lib/matchcondition/class.t3lib_matchcondition_abstract.php (copie de travail) @@ -36,6 +36,9 @@ * @package TYPO3 * @subpackage t3lib */ + +require_once (PATH_t3lib . 'class.t3lib_extmgm.php'); + abstract class t3lib_matchCondition_abstract { /** * Id of the current page. @@ -207,6 +210,7 @@ * @return mixed Returns true or false based on the evaluation */ protected function evaluateConditionCommon($key, $value) { + $rc = NULL; if (t3lib_div::inList('browser,version,system,useragent', strtolower($key))) { $browserInfo = $this->getBrowserInfo(t3lib_div::getIndpEnv('HTTP_USER_AGENT')); } @@ -393,9 +397,53 @@ return true; } break; + case 'ext': + // processing of the condition setup line + $values = t3lib_div::trimExplode(',', $value, TRUE); + $point = strcspn($value, '!=<>'); + $part = substr($value, 0, $point); + $values['0'] = substr($value, $point); + $keyArray = explode(':', $part); + $extensionKey = $keyArray['0']; + $attribute = trim($keyArray['1']); + + foreach($values as $currentValue) { + if (strlen($currentValue) && strlen($extensionKey)) { + $currentValue = trim($currentValue); + $bIsLoaded = t3lib_extMgm::isLoaded($extensionKey); + + if (!strlen($attribute) && $bIsLoaded || ($attribute == 'active' && intval($bIsLoaded) == $currentValue)) { + $rc = TRUE; + break; + } else { + $infoArray = t3lib_extMgm::getExtensionInfo($extensionKey); + + if ( + is_array($infoArray) && + isset($infoArray[$attribute]) + ) { + $test = $infoArray[$attribute] . $currentValue; + + switch ($attribute) { + case 'version': + if (preg_match('/^\s*([^\s]*)\s*(!?=+|<=?|>=?)\s*([^\s]*)\s*$/', $test, $matches)) { + $rc = t3lib_extMgm::versionDifference( + $matches['1'], + $matches['3'], + $matches['2'], + 1 + ); + } + break; + } + } + } + } + } + break; } - return NULL; + return $rc; } protected function getVariableCommon(array $vars) {