/** * @see wcf\page\IPage::show() */ public function show() { parent::show(); // check master password WCFACP::checkMasterPassword(); switch ($this->action) { case 'install': case 'update': if ($this->action == 'install') { WCF::getSession()->checkPermissions(array('admin.system.package.canInstallPackage')); } else { WCF::getSession()->checkPermissions(array('admin.system.package.canUpdatePackage')); } $queue = new PackageInstallationQueue($this->queueID); $dispatcher = new PackageInstallationDispatcher($queue); $dispatcher->beginInstallation(); break; case 'rollback': // TODO die('ROLLBACK'); //WCF::getSession()->checkPermissions(array('admin.system.package.canInstallPackage')); break; case 'openQueue': PackageInstallationDispatcher::openQueue($this->parentQueueID, $this->processNo); break; case 'startUninstall': WCF::getSession()->checkPermissions(array('admin.system.package.canUninstallPackage')); PackageUninstallationDispatcher::checkDependencies(); break; } }
/** * Prepares the installation process. */ protected function stepPrepare() { // update package information $this->installation->updatePackage(); // clean-up previously created nodes $this->installation->nodeBuilder->purgeNodes(); // create node tree $this->installation->nodeBuilder->buildNodes(); $nextNode = $this->installation->nodeBuilder->getNextNode(); $queueID = $this->installation->nodeBuilder->getQueueByNode($this->installation->queue->processNo, $nextNode); WCF::getTPL()->assign(array( 'packageName' => $this->installation->queue->packageName )); $this->data = array( 'template' => WCF::getTPL()->fetch($this->templateName), 'step' => 'install', 'node' => $nextNode, 'currentAction' => $this->getCurrentAction($queueID), 'progress' => 0, 'queueID' => $queueID ); }
/** * @see wcf\system\package\plugin\IPackageInstallationPlugin::uninstall() */ public function uninstall() { // call uninstall event EventHandler::getInstance()->fireAction($this, 'uninstall'); $sql = "DELETE FROM\twcf" . WCF_N . "_" . $this->tableName . "\n\t\t\tWHERE\t\tpackageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->installation->getPackageID())); }
/** * @see wcf\page\IPage::assignVariables() */ public function assignVariables() { parent::assignVariables(); WCF::getTPL()->assign(array( 'archive' => $this->packageInstallationDispatcher->getArchive(), 'requiredPackages' => $this->requirements, 'missingPackages' => $this->missingPackages, 'excludingPackages' => $this->packageInstallationDispatcher->getArchive()->getConflictedExcludingPackages(), 'excludedPackages' => $this->packageInstallationDispatcher->getArchive()->getConflictedExcludedPackages(), 'queueID' => $this->queue->queueID )); }
/** * @see \wcf\page\IPage::show() */ public function show() { // check package installation queue if ($this->action == 'WCFSetup') { $queueID = PackageInstallationDispatcher::checkPackageInstallationQueue(); if ($queueID) { WCF::getTPL()->assign(array('queueID' => $queueID)); WCF::getTPL()->display('packageInstallationSetup'); exit; } } // show page parent::show(); }
/** * Recursively build nodes for child queues. */ protected function buildChildQueues() { $queueList = new PackageInstallationQueueList(); $queueList->getConditionBuilder()->add("package_installation_queue.parentQueueID = ?", array($this->installation->queue->queueID)); $queueList->getConditionBuilder()->add("package_installation_queue.queueID NOT IN (SELECT queueID FROM wcf" . WCF_N . "_package_installation_node)"); $queueList->readObjects(); foreach ($queueList as $queue) { $installation = new PackageInstallationDispatcher($queue); // work-around for iterative package updates if ($this->installation->queue->action == 'update' && $queue->package == $this->installation->queue->package) { $installation->setPreviousPackage(array('package' => $this->installation->getArchive()->getPackageInfo('name'), 'packageVersion' => $this->installation->getArchive()->getPackageInfo('version'))); } $installation->nodeBuilder->setParentNode($this->node); $installation->nodeBuilder->buildNodes(); $this->node = $installation->nodeBuilder->getCurrentNode(); } }
/** * Installs the specified package. * * @param string $file */ private function install($file) { // PackageStartInstallForm::validateDownloadPackage() if (FileUtil::isURL($file)) { // download package $archive = new PackageArchive($file, null); try { if (VERBOSITY >= 1) { Log::info("Downloading '" . $file . "'"); } $file = $archive->downloadArchive(); } catch (SystemException $e) { $this->error('notFound', array('file' => $file)); } } else { // probably local path if (!file_exists($file)) { $this->error('notFound', array('file' => $file)); } $archive = new PackageArchive($file, null); } // PackageStartInstallForm::validateArchive() // try to open the archive try { // TODO: Exceptions thrown within openArchive() are discarded, resulting in // the meaningless message 'not a valid package' $archive->openArchive(); } catch (SystemException $e) { $this->error('noValidPackage'); } $errors = PackageInstallationDispatcher::validatePHPRequirements($archive->getPhpRequirements()); if (!empty($errors)) { // TODO: Nice output $this->error('phpRequirements', array('errors' => $errors)); } // try to find existing package $sql = "SELECT\t*\n\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\tWHERE\tpackage = ?"; $statement = CLIWCF::getDB()->prepareStatement($sql); $statement->execute(array($archive->getPackageInfo('name'))); $row = $statement->fetchArray(); $package = null; if ($row !== false) { $package = new Package(null, $row); } // check update or install support if ($package !== null) { CLIWCF::getSession()->checkPermissions(array('admin.system.package.canUpdatePackage')); $archive->setPackage($package); if (!$archive->isValidUpdate()) { $this->error('noValidUpdate'); } } else { CLIWCF::getSession()->checkPermissions(array('admin.system.package.canInstallPackage')); if (!$archive->isValidInstall()) { $this->error('noValidInstall'); } else { if ($archive->getPackageInfo('isApplication')) { // applications cannot be installed via CLI $this->error('cli.installIsApplication'); } else { if ($archive->isAlreadyInstalled()) { $this->error('uniqueAlreadyInstalled'); } else { if ($archive->getPackageInfo('isApplication') && $this->archive->hasUniqueAbbreviation()) { $this->error('noUniqueAbbrevation'); } } } } } // PackageStartInstallForm::save() $processNo = PackageInstallationQueue::getNewProcessNo(); // insert queue $queue = PackageInstallationQueueEditor::create(array('processNo' => $processNo, 'userID' => CLIWCF::getUser()->userID, 'package' => $archive->getPackageInfo('name'), 'packageName' => $archive->getLocalizedPackageInfo('packageName'), 'packageID' => $package !== null ? $package->packageID : null, 'archive' => $file, 'action' => $package !== null ? 'update' : 'install')); // PackageInstallationDispatcher::openQueue() $parentQueueID = 0; $conditions = new PreparedStatementConditionBuilder(); $conditions->add("userID = ?", array(CLIWCF::getUser()->userID)); $conditions->add("parentQueueID = ?", array($parentQueueID)); if ($processNo != 0) { $conditions->add("processNo = ?", array($processNo)); } $conditions->add("done = ?", array(0)); $sql = "SELECT\t\t*\n\t\t\tFROM\t\twcf" . WCF_N . "_package_installation_queue\n\t\t\t" . $conditions . "\n\t\t\tORDER BY\tqueueID ASC"; $statement = CLIWCF::getDB()->prepareStatement($sql); $statement->execute($conditions->getParameters()); $packageInstallation = $statement->fetchArray(); if (!isset($packageInstallation['queueID'])) { $this->error('internalOpenQueue'); return; } else { $queueID = $packageInstallation['queueID']; } // PackageInstallationConfirmPage::readParameters() $queue = new PackageInstallationQueue($queueID); if (!$queue->queueID || $queue->done) { $this->error('internalReadParameters'); return; } // PackageInstallationConfirmPage::readData() $missingPackages = 0; $packageInstallationDispatcher = new PackageInstallationDispatcher($queue); // get requirements $requirements = $packageInstallationDispatcher->getArchive()->getRequirements(); $openRequirements = $packageInstallationDispatcher->getArchive()->getOpenRequirements(); foreach ($requirements as &$requirement) { if (isset($openRequirements[$requirement['name']])) { $requirement['status'] = 'missing'; $requirement['action'] = $openRequirements[$requirement['name']]['action']; if (!isset($requirement['file'])) { if ($requirement['action'] === 'update') { $requirement['status'] = 'missingVersion'; $requirement['existingVersion'] = $openRequirements[$requirement['name']]['existingVersion']; } $missingPackages++; } else { $requirement['status'] = 'delivered'; $packageArchive = new PackageArchive($packageInstallationDispatcher->getArchive()->extractTar($requirement['file'])); $packageArchive->openArchive(); // make sure that the delivered package is correct if ($requirement['name'] != $packageArchive->getPackageInfo('name')) { $requirement['status'] = 'invalidDeliveredPackage'; $requirement['deliveredPackage'] = $packageArchive->getPackageInfo('name'); $missingPackages++; } else { if (isset($requirement['minversion'])) { // make sure that the delivered version is sufficient if (Package::compareVersion($requirement['minversion'], $packageArchive->getPackageInfo('version')) > 0) { $requirement['deliveredVersion'] = $packageArchive->getPackageInfo('version'); $requirement['status'] = 'missingVersion'; $missingPackages++; } } } } } else { $requirement['status'] = 'installed'; } } unset($requirement); // PackageInstallationConfirmPage::assignVariables/show() $excludingPackages = $packageInstallationDispatcher->getArchive()->getConflictedExcludingPackages(); $excludedPackages = $packageInstallationDispatcher->getArchive()->getConflictedExcludedPackages(); if (!($missingPackages == 0 && count($excludingPackages) == 0 && count($excludedPackages) == 0)) { $this->error('missingPackagesOrExclude', array('requirements' => $requirements, 'excludingPackages' => $excludingPackages, 'excludedPackages' => $excludedPackages)); return; } // AbstractDialogAction::readParameters() $step = 'prepare'; $queueID = $queue->queueID; $node = ''; // initialize progressbar $progressbar = new ProgressBar(new ConsoleProgressBar(array('width' => CLIWCF::getTerminal()->getWidth(), 'elements' => array(ConsoleProgressBar::ELEMENT_PERCENT, ConsoleProgressBar::ELEMENT_BAR, ConsoleProgressBar::ELEMENT_TEXT), 'textWidth' => min(floor(CLIWCF::getTerminal()->getWidth() / 2), 50)))); // InstallPackageAction::readParameters() $finished = false; while (!$finished) { $queue = new PackageInstallationQueue($queueID); if (!$queue->queueID) { // todo: what to output? echo "InstallPackageAction::readParameters()"; return; } $installation = new PackageInstallationDispatcher($queue); switch ($step) { case 'prepare': // InstallPackageAction::stepPrepare() // update package information $installation->updatePackage(); // clean-up previously created nodes $installation->nodeBuilder->purgeNodes(); // create node tree $installation->nodeBuilder->buildNodes(); $node = $installation->nodeBuilder->getNextNode(); $queueID = $installation->nodeBuilder->getQueueByNode($installation->queue->processNo, $node); $step = 'install'; $progress = 0; $currentAction = $installation->nodeBuilder->getPackageNameByQueue($queueID); break; case 'install': // InstallPackageAction::stepInstall() $step_ = $installation->install($node); $queueID = $installation->nodeBuilder->getQueueByNode($installation->queue->processNo, $step_->getNode()); if ($step_->hasDocument()) { $innerTemplate = $step_->getTemplate(); $progress = $installation->nodeBuilder->calculateProgress($node); $node = $step_->getNode(); $currentAction = $installation->nodeBuilder->getPackageNameByQueue($queueID); } else { if ($step_->getNode() == '') { // perform final actions $installation->completeSetup(); // InstallPackageAction::finalize() CacheHandler::getInstance()->flushAll(); // /InstallPackageAction::finalize() // show success $progress = 100; $currentAction = CLIWCF::getLanguage()->get('wcf.acp.package.installation.step.install.success'); $finished = true; continue; } else { // continue with next node $progress = $installation->nodeBuilder->calculateProgress($node); $node = $step_->getNode(); $currentAction = $installation->nodeBuilder->getPackageNameByQueue($queueID); } } break; } $progressbar->update($progress, $currentAction); } $progressbar->getAdapter()->finish(); }
/** * @see wcf\form\IForm::save() */ public function save() { parent::save(); // get new process no $processNo = PackageInstallationQueue::getNewProcessNo(); // obey foreign key $packageID = ($this->packageID) ? $this->packageID : null; // insert queue $this->queue = PackageInstallationQueueEditor::create(array( 'processNo' => $processNo, 'userID' => WCF::getUser()->userID, 'package' => $this->archive->getPackageInfo('name'), 'packageName' => $this->archive->getLocalizedPackageInfo('packageName'), 'packageID' => $packageID, 'archive' => (!empty($this->uploadPackage['tmp_name']) ? $this->uploadPackage['name'] : $this->downloadPackage), 'action' => ($this->package != null ? 'update' : 'install'), 'confirmInstallation' => 1 )); $this->saved(); // open queue PackageInstallationDispatcher::openQueue(0, $processNo); }
/** * Validates the package archive. * * @param string $type upload or download package */ protected function validateArchive($type) { // try to open the archive try { // TODO: Exceptions thrown within openArchive() are discarded, resulting in // the meaningless message 'not a valid package' $this->archive->openArchive(); } catch (SystemException $e) { throw new UserInputException($type, 'noValidPackage'); } // validate php requirements $errors = PackageInstallationDispatcher::validatePHPRequirements($this->archive->getPhpRequirements()); if (count($errors)) { WCF::getTPL()->assign('phpRequirements', $errors); throw new UserInputException($type, 'phpRequirements'); } // check update or install support if ($this->package !== null) { if (!$this->archive->isValidUpdate()) { throw new UserInputException($type, 'noValidUpdate'); } } else { if (!$this->archive->isValidInstall()) { throw new UserInputException($type, 'noValidInstall'); } elseif ($this->archive->isAlreadyInstalled()) { throw new UserInputException($type, 'uniqueAlreadyInstalled'); } } }
/** * @see wcf\form\IForm::save() */ public function save() { if (isset($_POST['send'])) { parent::save(); // save stack $processNo = $this->packageUpdate->savePackageInstallationStack(); $this->saved(); // open queue PackageInstallationDispatcher::openQueue(0, $processNo); } }
/** * @see \wcf\form\IForm::save() */ public function save() { parent::save(); // get new process no $processNo = PackageInstallationQueue::getNewProcessNo(); // obey foreign key $packageID = $this->package ? $this->package->packageID : null; $archive = $this->downloadPackage; if ($this->stylePackageImportLocation) { $archive = $this->stylePackageImportLocation; } else { if (!empty($this->uploadPackage['tmp_name'])) { $archive = $this->uploadPackage['name']; } } // insert queue $isApplication = PackageValidationManager::getInstance()->getPackageValidationArchive()->getArchive()->getPackageInfo('isApplication'); $this->queue = PackageInstallationQueueEditor::create(array('processNo' => $processNo, 'userID' => WCF::getUser()->userID, 'package' => PackageValidationManager::getInstance()->getPackageValidationArchive()->getArchive()->getPackageInfo('name'), 'packageName' => PackageValidationManager::getInstance()->getPackageValidationArchive()->getArchive()->getLocalizedPackageInfo('packageName'), 'packageID' => $packageID, 'archive' => $archive, 'action' => $this->package != null ? 'update' : 'install', 'isApplication' => !$isApplication ? '0' : '1')); $this->saved(); // open queue PackageInstallationDispatcher::openQueue(0, $processNo); }
/** * @see \wcf\page\IPage::assignVariables() */ public function assignVariables() { parent::assignVariables(); WCF::getTPL()->assign(array('archive' => $this->packageInstallationDispatcher->getArchive(), 'packageValidationArchives' => PackageValidationManager::getInstance()->getPackageValidationArchiveList(), 'queue' => $this->queue, 'validationPassed' => $this->validationPassed, 'installingImportedStyle' => $this->installingImportedStyle)); }