protected function installPackage(array $nodeData) {
$installationStep = new PackageInstallationStep();
+ // check requirements
+ if (!empty($nodeData['requirements'])) {
+ foreach ($nodeData['requirements'] as $package => $requirementData) {
+ // get existing package
+ if ($requirementData['packageID']) {
+ $sql = "SELECT packageName, packageVersion
+ FROM wcf".WCF_N."_package
+ WHERE packageID = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array($requirementData['packageID']));
+ }
+ else {
+ // try to find matching package
+ $sql = "SELECT packageName, packageVersion
+ FROM wcf".WCF_N."_package
+ WHERE package = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array($package));
+ }
+ $row = $statement->fetchArray();
+
+ // package is required but not available
+ if ($row === false) {
+ throw new SystemException("Package '".$package."' is required by '".$nodeData['packageName']."', but is neither installed nor shipped.");
+ }
+
+ // check version requirements
+ if ($requirementData['minVersion']) {
+ if (Package::compareVersion($row['packageVersion'], $requirementData['minVersion']) < 0) {
+ throw new SystemException("Package '".$nodeData['packageName']."' requires the package '".$row['packageName']."' in version '".$requirementData['minVersion']."', but version '".$row['packageVersion']."'");
+ }
+ }
+ }
+ }
+ unset($nodeData['requirements']);
+
if (!$this->queue->packageID) {
// create package entry
$package = PackageEditor::create($nodeData);
*/
public $parentNode = '';
+ /**
+ * list of requirements to be checked before package installation
+ * @var array<array>
+ */
+ public $requirements = array();
+
/**
* current sequence number within one node
*
'author' => $this->installation->getArchive()->getAuthorInfo('author'),
'authorURL' => $this->installation->getArchive()->getAuthorInfo('authorURL') !== null ? $this->installation->getArchive()->getAuthorInfo('authorURL') : '',
'installDate' => TIME_NOW,
- 'updateDate' => TIME_NOW
+ 'updateDate' => TIME_NOW,
+ 'requirements' => $this->requirements
))
));
}
$requiredPackages = $this->installation->getArchive()->getOpenRequirements();
foreach ($requiredPackages as $packageName => $package) {
if (!isset($package['file'])) {
- // package is installed but version does not match
- if ($package['packageID']) {
- // get package version
- $sql = "SELECT packageVersion
- FROM wcf".WCF_N."_package
- WHERE packageID = ?";
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array($package['packageID']));
- $row = $statement->fetchArray();
-
- throw new SystemException("Package '".$this->installation->getArchive()->getPackageInfo('packageName')."' requires the package '".$packageName."' in version '".$package['minversion']."', but '".$row['packageVersion']."' is installed.");
- }
-
- // package is required but not installed
- if (!$package['packageID']) {
- throw new SystemException("Package '".$this->installation->getArchive()->getPackageInfo('packageName')."' requires the package '".$packageName."', but it is neither installed nor shipped.");
- }
+ // requirements will be checked once package is about to be installed
+ $this->requirements[$packageName] = array(
+ 'minVersion' => (isset($package['minversion'])) ?: '',
+ 'packageID' => $package['packageID']
+ );
- // ignore requirements which are not to be installed, but are already available
continue;
}