*/
private $coreVersion = false;
+ /**
+ * @var array Loaded extensions
+ */
+ private $loaded = [];
+
/**
* @var VersionParser
*/
private $versionParser;
- public function __construct() {
+ /**
+ * @param string $coreVersion Current version of core
+ */
+ public function __construct( $coreVersion ) {
$this->versionParser = new VersionParser();
+ $this->setCoreVersion( $coreVersion );
+ }
+
+ /**
+ * Set an array with credits of all loaded extensions and skins.
+ *
+ * @param array $credits An array of installed extensions with credits of them
+ * @return VersionChecker $this
+ */
+ public function setLoadedExtensionsAndSkins( array $credits ) {
+ $this->loaded = $credits;
+
+ return $this;
}
/**
* Set MediaWiki core version.
*
* @param string $coreVersion Current version of core
- * @return VersionChecker $this
*/
- public function setCoreVersion( $coreVersion ) {
+ private function setCoreVersion( $coreVersion ) {
try {
$this->coreVersion = new Constraint(
'==',
} catch ( UnexpectedValueException $e ) {
// Non-parsable version, don't fatal.
}
-
- return $this;
}
/**
* installed extensions in the $credits array.
*
* Example $extDependencies:
- * {
- * 'GoogleAPIClient' => {
- * 'MediaWiki' => '>= 1.25.0'
- * }
- * }
+ * {
+ * 'FooBar' => {
+ * 'MediaWiki' => '>= 1.25.0',
+ * 'extensions' => {
+ * 'FooBaz' => '>= 1.25.0'
+ * },
+ * 'skins' => {
+ * 'BazBar' => '>= 1.0.0'
+ * }
+ * }
+ * }
*
* @param array $extDependencies All extensions that depend on other ones
* @return array
foreach ( $dependencies as $dependencyType => $values ) {
switch ( $dependencyType ) {
case ExtensionRegistry::MEDIAWIKI_CORE:
- $errors = array_merge(
- $errors,
- $this->handleMediaWikiDependency( $values, $extension )
- );
+ $mwError = $this->handleMediaWikiDependency( $values, $extension );
+ if ( $mwError !== false ) {
+ $errors[] = $mwError;
+ }
+ break;
+ case 'extensions':
+ case 'skin':
+ foreach ( $values as $dependency => $constraint ) {
+ $extError = $this->handleExtensionDependency( $dependency, $constraint, $extension );
+ if ( $extError !== false ) {
+ $errors[] = $extError;
+ }
+ }
break;
default:
throw new UnexpectedValueException( 'Dependency type ' . $dependencyType .
*
* @param string $constraint The required version constraint for this dependency
* @param string $checkedExt The Extension, which depends on this dependency
- * @return array An empty array, if MediaWiki version is compatible with $constraint, an array
- * with an error message, otherwise.
+ * @return bool|string false if no error, or a string with the message
*/
private function handleMediaWikiDependency( $constraint, $checkedExt ) {
if ( $this->coreVersion === false ) {
// Couldn't parse the core version, so we can't check anything
- return [];
+ return false;
}
// if the installed and required version are compatible, return an empty array
if ( $this->versionParser->parseConstraints( $constraint )
->matches( $this->coreVersion ) ) {
- return [];
+ return false;
}
// otherwise mark this as incompatible.
- return [ "{$checkedExt} is not compatible with the current "
- . "MediaWiki core (version {$this->coreVersion->getPrettyString()}), it requires: "
- . $constraint . '.' ];
+ return "{$checkedExt} is not compatible with the current "
+ . "MediaWiki core (version {$this->coreVersion->getPrettyString()}), it requires: "
+ . "$constraint.";
+ }
+
+ /**
+ * Handle a dependency to another extension.
+ *
+ * @param string $dependencyName The name of the dependency
+ * @param string $constraint The required version constraint for this dependency
+ * @param string $checkedExt The Extension, which depends on this dependency
+ * @return bool|string false for no errors, or a string message
+ */
+ private function handleExtensionDependency( $dependencyName, $constraint, $checkedExt ) {
+ // Check if the dependency is even installed
+ if ( !isset( $this->loaded[$dependencyName] ) ) {
+ return "{$checkedExt} requires {$dependencyName} to be installed.";
+ }
+ // Check if the dependency has specified a version
+ if ( !isset( $this->loaded[$dependencyName]['version'] ) ) {
+ // If we depend upon any version, and none is set, that's fine.
+ if ( $constraint === '*' ) {
+ wfDebug( "{$dependencyName} does not expose it's version, but {$checkedExt}
+ mentions it with constraint '*'. Assume it's ok so." );
+ return false;
+ } else {
+ // Otherwise, mark it as incompatible.
+ return "{$dependencyName} does not expose it's version, but {$checkedExt}
+ requires: {$constraint}.";
+ }
+ } else {
+ // Try to get a constraint for the dependency version
+ try {
+ $installedVersion = new Constraint(
+ '==',
+ $this->versionParser->normalize( $this->loaded[$dependencyName]['version'] )
+ );
+ } catch ( UnexpectedValueException $e ) {
+ // Non-parsable version, output an error message that the version
+ // string is invalid
+ return "$dependencyName does not have a valid version string.";
+ }
+ // Check if the constraint actually matches...
+ if (
+ !$this->versionParser->parseConstraints( $constraint )->matches( $installedVersion )
+ ) {
+ return "{$checkedExt} is not compatible with the current "
+ . "installed version of {$dependencyName} "
+ . "({$this->loaded[$dependencyName]['version']}), "
+ . "it requires: " . $constraint . '.';
+ }
+ }
+
+ return false;
}
}