diff --git a/system/src/Grav/Common/GPM/GPM.php b/system/src/Grav/Common/GPM/GPM.php
index 9fce56e5f..997ca4a90 100644
--- a/system/src/Grav/Common/GPM/GPM.php
+++ b/system/src/Grav/Common/GPM/GPM.php
@@ -208,13 +208,13 @@ class GPM extends Iterator
$repository = $this->repository['plugins'];
if (isset($repository[$package_name])) {
- return $repository[$package_name]->version;
+ return $repository[$package_name]->available;
}
//Not a plugin, it's a theme?
$repository = $this->repository['themes'];
if (isset($repository[$package_name])) {
- return $repository[$package_name]->version;
+ return $repository[$package_name]->available;
}
return null;
@@ -483,6 +483,41 @@ class GPM extends Iterator
}
}
+ /**
+ * Check the package identified by $slug can be updated to the version passed as argument.
+ * Thrown an exception if it cannot be updated because another package installed requires it to be at an older version.
+ *
+ * @param string $slug
+ * @param string $versionWithOperator The new version, with operator e.g. '~2.0' or '>=2.0'
+ *
+ * @return bool
+ * @throws \Exception
+ */
+ public function checkNoOtherPackageNeedsThisDependencyInALowerVersion($slug, $versionWithOperator) {
+ // check if any of the currently installed package need this in a lower version than the one we need. In case, abort and tell which package
+ $dependent_packages = $this->getPackagesThatDependOnPackage($slug);
+ $version = $this->calculateVersionNumberFromDependencyVersion($versionWithOperator);
+
+ if (count($dependent_packages)) {
+ foreach($dependent_packages as $dependent_package) {
+ $otherDependencyVersionWithOperator = $this->getVersionOfDependencyRequiredByPackage($dependent_package, $slug);
+ $otherDependencyVersion= $this->calculateVersionNumberFromDependencyVersion($otherDependencyVersionWithOperator);
+
+ // check version is compatible with the one needed by the current package
+ if ($this->versionFormatIsNextSignificantRelease($otherDependencyVersionWithOperator)) {
+ $compatible = $this->checkNextSignificantReleasesAreCompatible($version,
+ $otherDependencyVersion);
+ if (!$compatible) {
+ throw new \Exception("Package $slug is required in an older version by package $dependent_package. This package needs a newer version, and because of this it cannot be installed. The $dependent_package package must be updated to use a newer release of $slug.",
+ 2);
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
/**
* Fetch the dependencies, check the installed packages and return an array with
* the list of packages with associated an information on what to do: install, update or ignore.
@@ -519,28 +554,7 @@ class GPM extends Iterator
2);
}
} else {
-
- // check if any of the currently installed package need this in a lower version than the one we need. In case, abort and tell which package
- $dependent_packages = $this->getPackagesThatDependOnPackage($dependency_slug);
-
- if (count($dependent_packages)) {
- foreach($dependent_packages as $dependent_package) {
-
- $otherDependencyVersionWithOperator = $this->getVersionOfDependencyRequiredByPackage($dependent_package, $dependency_slug);
- $otherDependencyVersion= $this->calculateVersionNumberFromDependencyVersion($otherDependencyVersionWithOperator);
-
- // if requirement is next significant release, check it's compatible with the one needed by the current package
- if ($this->versionFormatIsNextSignificantRelease($dependencyVersionWithOperator)) {
- $compatible = $this->checkNextSignificantReleasesAreCompatible($dependencyVersion,
- $otherDependencyVersion);
-
- if (!$compatible) {
- throw new \Exception("Dependency $dependency_slug is required in an older version by package $dependent_package. This package needs a newer version, and because of this it cannot be installed. The $dependent_package package must be updated to use a newer release of $dependency_slug.",
- 2);
- }
- }
- }
- }
+ $this->checkNoOtherPackageNeedsThisDependencyInALowerVersion($dependency_slug, $dependencyVersionWithOperator);
}
}
@@ -700,25 +714,29 @@ class GPM extends Iterator
* Examples:
* $versionInformation == '~2.0' => returns '2.0'
* $versionInformation == '>=2.0.2' => returns '2.0.2'
+ * $versionInformation == '2.0.2' => returns '2.0.2'
* $versionInformation == '*' => returns null
* $versionInformation == '' => returns null
*
- * @param $versionInformation
+ * @param string $version
*
* @return null|string
*/
- public function calculateVersionNumberFromDependencyVersion($versionInformation)
+ public function calculateVersionNumberFromDependencyVersion($version)
{
- if ($this->versionFormatIsNextSignificantRelease($versionInformation)) {
- return substr($versionInformation, 1);
- } elseif ($this->versionFormatIsEqualOrHigher($versionInformation)) {
- return substr($versionInformation, 2);
+ if ($version == '*') {
+ return null;
+ } elseif ($version == '') {
+ return null;
+ } elseif ($this->versionFormatIsNextSignificantRelease($version)) {
+ return substr($version, 1);
+ } elseif ($this->versionFormatIsEqualOrHigher($version)) {
+ return substr($version, 2);
+ } else {
+ return $version;
}
-
- return null;
}
-
/**
* Check if the passed version information contains next significant release (tilde) operator
*
diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php
index 159d73d8b..b5c6c31f9 100644
--- a/system/src/Grav/Console/Gpm/InstallCommand.php
+++ b/system/src/Grav/Console/Gpm/InstallCommand.php
@@ -189,6 +189,14 @@ class InstallCommand extends ConsoleCommand
$this->processPackage($package, true);
} else {
if (Installer::lastErrorCode() == Installer::EXISTS) {
+
+ try {
+ $this->gpm->checkNoOtherPackageNeedsThisDependencyInALowerVersion($package->slug, $package->available);
+ } catch (\Exception $e) {
+ $this->output->writeln("" . $e->getMessage() . "");
+ return false;
+ }
+
$helper = $this->getHelper('question');
$question = new ConfirmationQuestion("The package $packageName is already installed, overwrite? [y|N] ", false);
diff --git a/system/src/Grav/Console/Gpm/UpdateCommand.php b/system/src/Grav/Console/Gpm/UpdateCommand.php
index f39d5f77e..fa869daed 100644
--- a/system/src/Grav/Console/Gpm/UpdateCommand.php
+++ b/system/src/Grav/Console/Gpm/UpdateCommand.php
@@ -122,7 +122,7 @@ class UpdateCommand extends ConsoleCommand
}
$this->output->writeln(
- // index
+ // index
str_pad($index++ + 1, 2, '0', STR_PAD_LEFT) . ". " .
// name
"" . str_pad($package->name, 15) . " " .