From 4c5b87fcbf06c0e502fd7aede70226ca35f21e62 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Thu, 10 Apr 2014 13:34:56 +0200 Subject: [PATCH] More work on package validation --- .../form/PackageStartInstallForm.class.php | 7 ++ .../install/files/lib/system/WCF.class.php | 2 +- .../PackageValidationArchive.class.php | 85 ++++++++++++++----- .../PackageValidationException.class.php | 39 +++++++++ .../PackageValidationManager.class.php | 2 +- 5 files changed, 113 insertions(+), 22 deletions(-) diff --git a/wcfsetup/install/files/lib/acp/form/PackageStartInstallForm.class.php b/wcfsetup/install/files/lib/acp/form/PackageStartInstallForm.class.php index 0e793e3ac1..9173777c7a 100755 --- a/wcfsetup/install/files/lib/acp/form/PackageStartInstallForm.class.php +++ b/wcfsetup/install/files/lib/acp/form/PackageStartInstallForm.class.php @@ -13,6 +13,7 @@ use wcf\system\WCF; use wcf\system\WCFACP; use wcf\util\FileUtil; use wcf\util\StringUtil; +use wcf\system\package\validation\PackageValidationManager; /** * Shows the package install and update form. @@ -136,6 +137,12 @@ class PackageStartInstallForm extends AbstractForm { throw new UserInputException('uploadPackage', 'uploadFailed'); } + if (PackageValidationManager::getInstance()->validate($this->uploadPackage['name'])) { + die("win"); + } + else { + die("failed"); + } $this->archive = new PackageArchive($this->uploadPackage['name'], $this->package); $this->validateArchive('uploadPackage'); } diff --git a/wcfsetup/install/files/lib/system/WCF.class.php b/wcfsetup/install/files/lib/system/WCF.class.php index 263d43d842..28cd574b1c 100644 --- a/wcfsetup/install/files/lib/system/WCF.class.php +++ b/wcfsetup/install/files/lib/system/WCF.class.php @@ -37,7 +37,7 @@ if (!@ini_get('date.timezone')) { } // define current wcf version -define('WCF_VERSION', '2.1.0 Alpha 1 (Maelstrom)'); +define('WCF_VERSION', '2.1.0 Alpha 1 (Typhoon)'); // define current unix timestamp define('TIME_NOW', time()); diff --git a/wcfsetup/install/files/lib/system/package/validation/PackageValidationArchive.class.php b/wcfsetup/install/files/lib/system/package/validation/PackageValidationArchive.class.php index 763a64ec25..f1445711a3 100644 --- a/wcfsetup/install/files/lib/system/package/validation/PackageValidationArchive.class.php +++ b/wcfsetup/install/files/lib/system/package/validation/PackageValidationArchive.class.php @@ -2,6 +2,8 @@ namespace wcf\system\package\validation; use wcf\system\package\PackageArchive; use wcf\system\WCF; +use wcf\data\package\Package; +use wcf\data\package\PackageCache; /** * Recursively validates the package archive and it's delivered requirements. @@ -50,38 +52,81 @@ class PackageValidationArchive implements \RecursiveIterator { /** * Validates this package and it's delivered requirements. * + * @param boolean $deepInspection * @return boolean */ - public function validate() { - // - // step 1) try to read archive - // + public function validate($deepInspection = false, $requiredVersion = '') { try { + // try to read archive $this->archive->openArchive(); + + // check if package is installable or suitable for an update + $this->validateInstructions($requiredVersion); } catch (\Exception $e) { $this->exception = $e; + + return false; } - // - // step 2) traverse requirements - // - die("
".print_r($this->archive->getOpenRequirements(), true));
-		
-		//
-		// step 3) check requirements against virtual package table
-		//
-		
-		/* TODO: do something */
+		if ($deepInspection) {
+			try {
+				// check for exclusions
+				$this->validateExclusion();
+				
+				// traverse open requirements
+				foreach ($this->archive->getOpenRequirements() as $requirement) {
+					$archive = $this->archive->extractTar($requirement->file);
+						
+					$index = count($this->children);
+					$this->children[$index] = new PackageValidationArchive($archive);
+					if (!$this->children[$index]->validate(true)) {
+						return false;
+					}
+				}
+			}
+			catch (PackageValidationException $e) {
+				$this->exception = $e;
+				
+				return false;
+			}
+		}
 		
-		//
-		// step 4) check exclusions
-		//
+		return true;
 		
-		/* TODO: do something */
+	}
+	
+	protected function validateInstructions($requiredVersion) {
+		$package = PackageCache::getInstance()->getPackageByIdentifier($this->archive->getPackageInfo('name'));
 		
-		return true;
+		// package is not installed yet
+		if ($package === null) {
+			if (empty($this->archive->getInstallInstructions())) {
+				throw new PackageValidationException(PackageValidationException::NO_INSTALL_PATH, array('packageName' => $this->archive->getPackageInfo('name')));
+			}
+		}
+		else {
+			// package is already installed, check update path
+			if (!$this->archive->isValidUpdate($package)) {
+				throw new PackageValidationException(PackageValidationException::NO_UPDATE_PATH, array(
+					'packageName' => $package->packageName,
+					'packageVersion' => $package->packageVersion,
+					'deliveredPackageVersion' => $this->archive->getPackageInfo('version')
+				));
+			}
+		}
+	}
+	
+	protected function validateExclusion() {
+		$excludingPackages = $this->archive->getConflictedExcludingPackages();
+		if (!empty($excludingPackages)) {
+			throw new PackageValidationException(PackageValidationException::EXCLUDING_PACKAGES, array('packages' => $excludingPackages));
+		}
 		
+		$excludedPackages = $this->archive->getConflictedExcludedPackages();
+		if (!empty($excludingPackages)) {
+			throw new PackageValidationException(PackageValidationException::EXCLUDED_PACKAGES, array('packages' => $excludedPackages));
+		}
 	}
 	
 	/**
@@ -95,7 +140,7 @@ class PackageValidationArchive implements \RecursiveIterator {
 		}
 		
 		if ($this->exception instanceof PackageValidationException) {
-			return WCF::getLanguage()->getDynamicVariable('wcf.package.validation.errorCode.' . $this->exception->getCode(), $this->exception->getDetails());
+			return $this->exception->getErrorMessage();
 		}
 		
 		return $this->exception->getMessage();
diff --git a/wcfsetup/install/files/lib/system/package/validation/PackageValidationException.class.php b/wcfsetup/install/files/lib/system/package/validation/PackageValidationException.class.php
index 554e0c1cc8..e2177c9229 100644
--- a/wcfsetup/install/files/lib/system/package/validation/PackageValidationException.class.php
+++ b/wcfsetup/install/files/lib/system/package/validation/PackageValidationException.class.php
@@ -1,6 +1,8 @@
 details;
 	}
 	
+	/**
+	 * Returns the readable error message.
+	 * 
+	 * @return	string
+	 */
+	public function getErrorMessage() {
+		return WCF::getLanguage()->getDynamicVariable('wcf.package.validation.errorCode.' . $this->getCode(), $this->getDetails());
+	}
+	
 	/**
 	 * Returns legacy error messages to mimic WCF 2.0.x PackageArchive's exceptions.
 	 * 
@@ -91,6 +126,10 @@ class PackageValidationException extends SystemException {
 			case self::INVALID_PACKAGE_VERSION:
 				return "package version '".$this->details['packageVersion']."' is invalid";
 			break;
+			
+			default:
+				return 'Using getMessage() is discouraged, please use getErrorMessage() instead';
+			break;
 		}
 	}
 	
diff --git a/wcfsetup/install/files/lib/system/package/validation/PackageValidationManager.class.php b/wcfsetup/install/files/lib/system/package/validation/PackageValidationManager.class.php
index c9c10459a1..d469bbf4ef 100644
--- a/wcfsetup/install/files/lib/system/package/validation/PackageValidationManager.class.php
+++ b/wcfsetup/install/files/lib/system/package/validation/PackageValidationManager.class.php
@@ -1,7 +1,7 @@