2 namespace wcf\acp\form
;
3 use wcf\data\package\installation\queue\PackageInstallationQueue
;
4 use wcf\data\package\installation\queue\PackageInstallationQueueEditor
;
5 use wcf\data\package\Package
;
6 use wcf\form\AbstractForm
;
7 use wcf\system\exception\PermissionDeniedException
;
8 use wcf\system\exception\SystemException
;
9 use wcf\system\exception\UserInputException
;
10 use wcf\system\package\PackageArchive
;
11 use wcf\system\package\PackageInstallationDispatcher
;
13 use wcf\system\WCFACP
;
14 use wcf\util\FileUtil
;
15 use wcf\util\StringUtil
;
18 * Shows the package install and update form.
21 * @copyright 2001-2014 WoltLab GmbH
22 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
23 * @package com.woltlab.wcf
24 * @subpackage acp.form
25 * @category Community Framework
27 class PackageStartInstallForm
extends AbstractForm
{
29 * @see \wcf\page\AbstractPage::$activeMenuItem
31 public $activeMenuItem = 'wcf.acp.menu.link.package.install';
34 * updated package object
35 * @var \wcf\system\package\Package
37 public $package = null;
40 * url to the package to download
43 public $downloadPackage = '';
46 * data of the uploaded package
49 public $uploadPackage = '';
52 * archive of the installation/update package
53 * @var \wcf\system\package\PackageArchive
55 public $archive = null;
58 * package installation/update queue
59 * @var \wcf\data\package\installation\queue\PackageInstallationQueue
64 * @see \wcf\form\IForm::readFormParameters()
66 public function readFormParameters() {
67 parent
::readFormParameters();
69 if (isset($_POST['downloadPackage'])) $this->downloadPackage
= StringUtil
::trim($_POST['downloadPackage']);
70 if (isset($_FILES['uploadPackage'])) $this->uploadPackage
= $_FILES['uploadPackage'];
74 * @see \wcf\form\IForm::validate()
76 public function validate() {
79 if (!empty($this->uploadPackage
['name'])) {
80 $this->validateUploadPackage();
82 else if (!empty($this->downloadPackage
)) {
83 $this->validateDownloadPackage();
86 throw new UserInputException('uploadPackage');
91 * Validates the upload package input.
93 protected function validateUploadPackage() {
94 $this->activeTabMenuItem
= 'upload';
96 if (empty($this->uploadPackage
['tmp_name'])) {
97 throw new UserInputException('uploadPackage', 'uploadFailed');
101 $this->uploadPackage
['name'] = FileUtil
::getTemporaryFilename('package_', preg_replace('!^.*(?=\.(?:tar\.gz|tgz|tar)$)!i', '', basename($this->uploadPackage
['name'])));
103 if (!@move_uploaded_file
($this->uploadPackage
['tmp_name'], $this->uploadPackage
['name'])) {
104 throw new UserInputException('uploadPackage', 'uploadFailed');
107 $this->archive
= new PackageArchive($this->uploadPackage
['name'], $this->package
);
108 $this->validateArchive('uploadPackage');
112 * Validates the download package input.
114 protected function validateDownloadPackage() {
115 $this->activeTabMenuItem
= 'upload';
117 if (FileUtil
::isURL($this->downloadPackage
)) {
119 $this->archive
= new PackageArchive($this->downloadPackage
, $this->package
);
122 $this->downloadPackage
= $this->archive
->downloadArchive();
124 catch (SystemException
$e) {
125 throw new UserInputException('downloadPackage', 'downloadFailed');
129 // probably local path
130 if (!file_exists($this->downloadPackage
)) {
131 throw new UserInputException('downloadPackage', 'downloadFailed');
134 $this->archive
= new PackageArchive($this->downloadPackage
, $this->package
);
137 $this->validateArchive('downloadPackage');
141 * Validates the package archive.
143 * @param string $type upload or download package
145 protected function validateArchive($type) {
146 // try to open the archive
148 // TODO: Exceptions thrown within openArchive() are discarded, resulting in
149 // the meaningless message 'not a valid package'
150 $this->archive
->openArchive();
152 catch (SystemException
$e) {
153 throw new UserInputException($type, 'noValidPackage');
156 // validate php requirements
157 $errors = PackageInstallationDispatcher
::validatePHPRequirements($this->archive
->getPhpRequirements());
158 if (!empty($errors)) {
159 WCF
::getTPL()->assign('phpRequirements', $errors);
160 throw new UserInputException($type, 'phpRequirements');
163 // try to find existing package
165 FROM wcf".WCF_N
."_package
167 $statement = WCF
::getDB()->prepareStatement($sql);
168 $statement->execute(array($this->archive
->getPackageInfo('name')));
169 $row = $statement->fetchArray();
170 if ($row !== false) {
171 $this->package
= new Package(null, $row);
174 // check update or install support
175 if ($this->package
!== null) {
176 WCF
::getSession()->checkPermissions(array('admin.system.package.canUpdatePackage'));
177 $this->activeMenuItem
= 'wcf.acp.menu.link.package';
179 if (!$this->archive
->isValidUpdate($this->package
)) {
180 throw new UserInputException($type, 'noValidUpdate');
184 WCF
::getSession()->checkPermissions(array('admin.system.package.canInstallPackage'));
186 if (!$this->archive
->isValidInstall()) {
187 throw new UserInputException($type, 'noValidInstall');
189 else if ($this->archive
->isAlreadyInstalled()) {
190 throw new UserInputException($type, 'uniqueAlreadyInstalled');
192 else if ($this->archive
->getPackageInfo('isApplication') && $this->archive
->hasUniqueAbbreviation()) {
193 throw new UserInputException($type, 'noUniqueAbbrevation');
199 * @see \wcf\form\IForm::save()
201 public function save() {
204 // get new process no
205 $processNo = PackageInstallationQueue
::getNewProcessNo();
208 $packageID = ($this->package
) ?
$this->package
->packageID
: null;
211 $isApplication = $this->archive
->getPackageInfo('isApplication');
212 $this->queue
= PackageInstallationQueueEditor
::create(array(
213 'processNo' => $processNo,
214 'userID' => WCF
::getUser()->userID
,
215 'package' => $this->archive
->getPackageInfo('name'),
216 'packageName' => $this->archive
->getLocalizedPackageInfo('packageName'),
217 'packageID' => $packageID,
218 'archive' => (!empty($this->uploadPackage
['tmp_name']) ?
$this->uploadPackage
['name'] : $this->downloadPackage
),
219 'action' => ($this->package
!= null ?
'update' : 'install'),
220 'isApplication' => (!$isApplication ?
'0' : '1')
226 PackageInstallationDispatcher
::openQueue(0, $processNo);
230 * @see \wcf\page\IPage::assignVariables()
232 public function assignVariables() {
233 parent
::assignVariables();
235 WCF
::getTPL()->assign(array(
236 'package' => $this->package
241 * @see \wcf\page\IPage::show()
243 public function show() {
244 if (!WCF
::getSession()->getPermission('admin.system.package.canInstallPackage') && !WCF
::getSession()->getPermission('admin.system.package.canUpdatePackage')) {
245 throw new PermissionDeniedException();
248 // check master password
249 WCFACP
::checkMasterPassword();