Commit | Line | Data |
---|---|---|
158bd3ca TD |
1 | <?php |
2 | namespace wcf\acp\form; | |
158bd3ca TD |
3 | use wcf\data\package\installation\queue\PackageInstallationQueue; |
4 | use wcf\data\package\installation\queue\PackageInstallationQueueEditor; | |
2bc9f31d | 5 | use wcf\data\package\Package; |
264c6eea | 6 | use wcf\form\AbstractForm; |
ec45d5e8 | 7 | use wcf\system\exception\PermissionDeniedException; |
158bd3ca TD |
8 | use wcf\system\exception\SystemException; |
9 | use wcf\system\exception\UserInputException; | |
51654676 | 10 | use wcf\system\package\validation\PackageValidationManager; |
158bd3ca TD |
11 | use wcf\system\package\PackageArchive; |
12 | use wcf\system\package\PackageInstallationDispatcher; | |
2bc9f31d TB |
13 | use wcf\system\WCF; |
14 | use wcf\system\WCFACP; | |
158bd3ca | 15 | use wcf\util\FileUtil; |
158bd3ca TD |
16 | use wcf\util\StringUtil; |
17 | ||
18 | /** | |
19 | * Shows the package install and update form. | |
6e048dca | 20 | * |
158bd3ca | 21 | * @author Marcel Werk |
ca4ba303 | 22 | * @copyright 2001-2014 WoltLab GmbH |
158bd3ca TD |
23 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> |
24 | * @package com.woltlab.wcf | |
25 | * @subpackage acp.form | |
9f959ced | 26 | * @category Community Framework |
158bd3ca | 27 | */ |
264c6eea | 28 | class PackageStartInstallForm extends AbstractForm { |
21489986 | 29 | /** |
0ad90fc3 | 30 | * @see \wcf\page\AbstractPage::$activeMenuItem |
21489986 | 31 | */ |
158bd3ca | 32 | public $activeMenuItem = 'wcf.acp.menu.link.package.install'; |
21489986 | 33 | |
21489986 MS |
34 | /** |
35 | * updated package object | |
0ad90fc3 | 36 | * @var \wcf\system\package\Package |
21489986 | 37 | */ |
158bd3ca | 38 | public $package = null; |
21489986 MS |
39 | |
40 | /** | |
41 | * url to the package to download | |
42 | * @var string | |
43 | */ | |
158bd3ca | 44 | public $downloadPackage = ''; |
21489986 MS |
45 | |
46 | /** | |
47 | * data of the uploaded package | |
48 | * @var array<string> | |
49 | */ | |
158bd3ca | 50 | public $uploadPackage = ''; |
21489986 MS |
51 | |
52 | /** | |
c945dba8 | 53 | * archive of the installation/update package |
0ad90fc3 | 54 | * @var \wcf\system\package\PackageArchive |
21489986 | 55 | */ |
158bd3ca | 56 | public $archive = null; |
21489986 MS |
57 | |
58 | /** | |
59 | * package installation/update queue | |
0ad90fc3 | 60 | * @var \wcf\data\package\installation\queue\PackageInstallationQueue |
21489986 | 61 | */ |
158bd3ca TD |
62 | public $queue = null; |
63 | ||
b168bf95 MS |
64 | /** |
65 | * location of the package uploaded via style import | |
66 | * @var string | |
67 | */ | |
68 | public $stylePackageImportLocation = ''; | |
69 | ||
70 | /** | |
71 | * @see \wcf\page\IPage::readParameters() | |
72 | */ | |
73 | public function readParameters() { | |
74 | parent::readParameters(); | |
75 | ||
76 | $this->stylePackageImportLocation = WCF::getSession()->getVar('stylePackageImportLocation'); | |
77 | if ($this->stylePackageImportLocation) { | |
78 | $_POST['t'] = WCF::getSession()->getSecurityToken(); | |
79 | } | |
80 | } | |
81 | ||
158bd3ca | 82 | /** |
0ad90fc3 | 83 | * @see \wcf\form\IForm::readFormParameters() |
158bd3ca TD |
84 | */ |
85 | public function readFormParameters() { | |
86 | parent::readFormParameters(); | |
87 | ||
b168bf95 MS |
88 | if (!$this->stylePackageImportLocation) { |
89 | if (isset($_POST['downloadPackage'])) $this->downloadPackage = StringUtil::trim($_POST['downloadPackage']); | |
90 | if (isset($_FILES['uploadPackage'])) $this->uploadPackage = $_FILES['uploadPackage']; | |
91 | } | |
158bd3ca TD |
92 | } |
93 | ||
94 | /** | |
0ad90fc3 | 95 | * @see \wcf\form\IForm::validate() |
158bd3ca TD |
96 | */ |
97 | public function validate() { | |
98 | parent::validate(); | |
99 | ||
b168bf95 MS |
100 | if ($this->stylePackageImportLocation) { |
101 | $this->archive = new PackageArchive($this->stylePackageImportLocation, $this->package); | |
102 | ||
103 | try { | |
104 | $this->validateArchive('uploadPackage'); | |
105 | } | |
106 | catch (UserInputException $e) { | |
107 | WCF::getSession()->unregister('stylePackageImportLocation'); | |
108 | ||
109 | throw $e; | |
110 | } | |
111 | } | |
112 | else if (!empty($this->uploadPackage['name'])) { | |
158bd3ca TD |
113 | $this->validateUploadPackage(); |
114 | } | |
115 | else if (!empty($this->downloadPackage)) { | |
116 | $this->validateDownloadPackage(); | |
117 | } | |
118 | else { | |
119 | throw new UserInputException('uploadPackage'); | |
120 | } | |
121 | } | |
122 | ||
123 | /** | |
124 | * Validates the upload package input. | |
125 | */ | |
126 | protected function validateUploadPackage() { | |
e06392e6 AE |
127 | $this->activeTabMenuItem = 'upload'; |
128 | ||
158bd3ca TD |
129 | if (empty($this->uploadPackage['tmp_name'])) { |
130 | throw new UserInputException('uploadPackage', 'uploadFailed'); | |
131 | } | |
132 | ||
133 | // get filename | |
134 | $this->uploadPackage['name'] = FileUtil::getTemporaryFilename('package_', preg_replace('!^.*(?=\.(?:tar\.gz|tgz|tar)$)!i', '', basename($this->uploadPackage['name']))); | |
135 | ||
136 | if (!@move_uploaded_file($this->uploadPackage['tmp_name'], $this->uploadPackage['name'])) { | |
137 | throw new UserInputException('uploadPackage', 'uploadFailed'); | |
138 | } | |
139 | ||
870b0938 AE |
140 | if (!PackageValidationManager::getInstance()->validate($this->uploadPackage['name'], false)) { |
141 | // TODO: do something | |
25c89d0a | 142 | die("validation failed: " . PackageValidationManager::getInstance()->getExceptionMessage()); |
4c5b87fc | 143 | } |
870b0938 AE |
144 | |
145 | $this->package = PackageValidationManager::getInstance()->getPackageValidationArchive()->getPackage(); | |
158bd3ca TD |
146 | } |
147 | ||
148 | /** | |
149 | * Validates the download package input. | |
150 | */ | |
151 | protected function validateDownloadPackage() { | |
b9e47fe0 AE |
152 | $this->activeTabMenuItem = 'upload'; |
153 | ||
158bd3ca TD |
154 | if (FileUtil::isURL($this->downloadPackage)) { |
155 | // download package | |
156 | $this->archive = new PackageArchive($this->downloadPackage, $this->package); | |
157 | ||
158 | try { | |
159 | $this->downloadPackage = $this->archive->downloadArchive(); | |
158bd3ca TD |
160 | } |
161 | catch (SystemException $e) { | |
a30c0984 | 162 | throw new UserInputException('downloadPackage', 'downloadFailed'); |
158bd3ca TD |
163 | } |
164 | } | |
165 | else { | |
166 | // probably local path | |
167 | if (!file_exists($this->downloadPackage)) { | |
a30c0984 | 168 | throw new UserInputException('downloadPackage', 'downloadFailed'); |
158bd3ca TD |
169 | } |
170 | ||
171 | $this->archive = new PackageArchive($this->downloadPackage, $this->package); | |
172 | } | |
173 | ||
174 | $this->validateArchive('downloadPackage'); | |
175 | } | |
176 | ||
177 | /** | |
178 | * Validates the package archive. | |
6e048dca | 179 | * |
158bd3ca TD |
180 | * @param string $type upload or download package |
181 | */ | |
182 | protected function validateArchive($type) { | |
183 | // try to open the archive | |
184 | try { | |
185 | // TODO: Exceptions thrown within openArchive() are discarded, resulting in | |
186 | // the meaningless message 'not a valid package' | |
187 | $this->archive->openArchive(); | |
188 | } | |
189 | catch (SystemException $e) { | |
190 | throw new UserInputException($type, 'noValidPackage'); | |
191 | } | |
192 | ||
193 | // validate php requirements | |
194 | $errors = PackageInstallationDispatcher::validatePHPRequirements($this->archive->getPhpRequirements()); | |
15fa2802 | 195 | if (!empty($errors)) { |
158bd3ca TD |
196 | WCF::getTPL()->assign('phpRequirements', $errors); |
197 | throw new UserInputException($type, 'phpRequirements'); | |
198 | } | |
199 | ||
ec45d5e8 AE |
200 | // try to find existing package |
201 | $sql = "SELECT * | |
202 | FROM wcf".WCF_N."_package | |
203 | WHERE package = ?"; | |
204 | $statement = WCF::getDB()->prepareStatement($sql); | |
205 | $statement->execute(array($this->archive->getPackageInfo('name'))); | |
206 | $row = $statement->fetchArray(); | |
207 | if ($row !== false) { | |
208 | $this->package = new Package(null, $row); | |
209 | } | |
210 | ||
158bd3ca TD |
211 | // check update or install support |
212 | if ($this->package !== null) { | |
ec45d5e8 AE |
213 | WCF::getSession()->checkPermissions(array('admin.system.package.canUpdatePackage')); |
214 | $this->activeMenuItem = 'wcf.acp.menu.link.package'; | |
215 | ||
49ec1439 | 216 | if (!$this->archive->isValidUpdate($this->package)) { |
158bd3ca TD |
217 | throw new UserInputException($type, 'noValidUpdate'); |
218 | } | |
219 | } | |
220 | else { | |
ec45d5e8 AE |
221 | WCF::getSession()->checkPermissions(array('admin.system.package.canInstallPackage')); |
222 | ||
158bd3ca TD |
223 | if (!$this->archive->isValidInstall()) { |
224 | throw new UserInputException($type, 'noValidInstall'); | |
225 | } | |
58e1d71f | 226 | else if ($this->archive->isAlreadyInstalled()) { |
158bd3ca TD |
227 | throw new UserInputException($type, 'uniqueAlreadyInstalled'); |
228 | } | |
549376a4 MS |
229 | else if ($this->archive->getPackageInfo('isApplication') && $this->archive->hasUniqueAbbreviation()) { |
230 | throw new UserInputException($type, 'noUniqueAbbrevation'); | |
231 | } | |
158bd3ca TD |
232 | } |
233 | } | |
234 | ||
235 | /** | |
0ad90fc3 | 236 | * @see \wcf\form\IForm::save() |
158bd3ca TD |
237 | */ |
238 | public function save() { | |
239 | parent::save(); | |
240 | ||
241 | // get new process no | |
242 | $processNo = PackageInstallationQueue::getNewProcessNo(); | |
243 | ||
244 | // obey foreign key | |
ec45d5e8 | 245 | $packageID = ($this->package) ? $this->package->packageID : null; |
158bd3ca | 246 | |
b168bf95 MS |
247 | $archive = $this->downloadPackage; |
248 | if ($this->stylePackageImportLocation) { | |
249 | $archive = $this->stylePackageImportLocation; | |
250 | } | |
251 | else if (!empty($this->uploadPackage['tmp_name'])) { | |
252 | $archive = $this->uploadPackage['name']; | |
253 | } | |
254 | ||
158bd3ca | 255 | // insert queue |
870b0938 | 256 | $isApplication = PackageValidationManager::getInstance()->getPackageValidationArchive()->getArchive()->getPackageInfo('isApplication'); |
158bd3ca TD |
257 | $this->queue = PackageInstallationQueueEditor::create(array( |
258 | 'processNo' => $processNo, | |
259 | 'userID' => WCF::getUser()->userID, | |
870b0938 AE |
260 | 'package' => PackageValidationManager::getInstance()->getPackageValidationArchive()->getArchive()->getPackageInfo('name'), |
261 | 'packageName' => PackageValidationManager::getInstance()->getPackageValidationArchive()->getArchive()->getLocalizedPackageInfo('packageName'), | |
158bd3ca | 262 | 'packageID' => $packageID, |
b168bf95 | 263 | 'archive' => $archive, |
158bd3ca | 264 | 'action' => ($this->package != null ? 'update' : 'install'), |
b33c97d2 | 265 | 'isApplication' => (!$isApplication ? '0' : '1') |
158bd3ca TD |
266 | )); |
267 | ||
268 | $this->saved(); | |
269 | ||
270 | // open queue | |
8059b673 | 271 | PackageInstallationDispatcher::openQueue(0, $processNo); |
158bd3ca TD |
272 | } |
273 | ||
274 | /** | |
0ad90fc3 | 275 | * @see \wcf\page\IPage::assignVariables() |
158bd3ca TD |
276 | */ |
277 | public function assignVariables() { | |
278 | parent::assignVariables(); | |
279 | ||
280 | WCF::getTPL()->assign(array( | |
b168bf95 MS |
281 | 'package' => $this->package, |
282 | 'installingImportedStyle' => $this->stylePackageImportLocation != '' | |
158bd3ca TD |
283 | )); |
284 | } | |
285 | ||
286 | /** | |
0ad90fc3 | 287 | * @see \wcf\page\IPage::show() |
158bd3ca TD |
288 | */ |
289 | public function show() { | |
ec45d5e8 AE |
290 | if (!WCF::getSession()->getPermission('admin.system.package.canInstallPackage') && !WCF::getSession()->getPermission('admin.system.package.canUpdatePackage')) { |
291 | throw new PermissionDeniedException(); | |
7f4589b6 | 292 | } |
158bd3ca TD |
293 | |
294 | // check master password | |
295 | WCFACP::checkMasterPassword(); | |
296 | ||
297 | parent::show(); | |
298 | } | |
299 | } |