/** * Parses a stream containing info from a packages_update.xml. * * @param string $content * @return array $allNewPackages */ protected static function parsePackageUpdateXML($content) { // load xml document $xml = new XML(); $xml->loadXML('packageUpdateServer.xml', $content); $xpath = $xml->xpath(); // loop through <package> tags inside the <section> tag. $allNewPackages = array(); $packages = $xpath->query('/ns:section[@name=\'packages\']/ns:package'); foreach ($packages as $package) { if (!Package::isValidPackageName($package->getAttribute('name'))) { throw new SystemException("'" . $package->getAttribute('name') . "' is not a valid package name."); } $allNewPackages[$package->getAttribute('name')] = self::parsePackageUpdateXMLBlock($xpath, $package); } return $allNewPackages; }
/** * Uninstalls the specified package. * $package may either be the packageID or the package identifier. * * @param mixed $package */ private function uninstall($package) { if (Package::isValidPackageName($package)) { $packageID = PackageCache::getInstance()->getPackageID($package); } else { $packageID = $package; } // UninstallPackageAction::prepare() $package = new Package($packageID); if (!$package->packageID || !$package->canUninstall()) { $this->error('invalidUninstallation'); } // get new process no $processNo = PackageInstallationQueue::getNewProcessNo(); // create queue $queue = PackageInstallationQueueEditor::create(array('processNo' => $processNo, 'userID' => CLIWCF::getUser()->userID, 'packageName' => $package->getName(), 'packageID' => $package->packageID, 'action' => 'uninstall')); // initialize uninstallation $installation = new PackageUninstallationDispatcher($queue); $installation->nodeBuilder->purgeNodes(); $installation->nodeBuilder->buildNodes(); CLIWCF::getTPL()->assign(array('queue' => $queue)); $queueID = $installation->nodeBuilder->getQueueByNode($queue->processNo, $installation->nodeBuilder->getNextNode()); $step = 'uninstall'; $node = $installation->nodeBuilder->getNextNode(); $currentAction = CLIWCF::getLanguage()->get('wcf.package.installation.step.uninstalling'); $progress = 0; // 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); $installation = new PackageUninstallationDispatcher($queue); switch ($step) { case 'uninstall': $_node = $installation->uninstall($node); if ($_node == '') { // remove node data $installation->nodeBuilder->purgeNodes(); // UninstallPackageAction::finalize() CacheHandler::getInstance()->flushAll(); // /UninstallPackageAction::finalize() // show success $currentAction = CLIWCF::getLanguage()->get('wcf.acp.package.uninstallation.step.success'); $progress = 100; $step = 'success'; $finished = true; continue; } // continue with next node $queueID = $installation->nodeBuilder->getQueueByNode($installation->queue->processNo, $installation->nodeBuilder->getNextNode($node)); $step = 'uninstall'; $progress = $installation->nodeBuilder->calculateProgress($node); $node = $_node; } $progressbar->update($progress, $currentAction); } $progressbar->getAdapter()->finish(); }
/** * Registers a deferred message. Returns `true` on any well-formed message and `false` * otherwise. * Deferred messages will be sent on shutdown. This can be useful if your handler depends * on data that may not be written to database yet or to achieve a better performance as the * page is delivered first. * * ATTENTION: Use this method only if your messages are not critical as you cannot check * whether your message was delivered successfully. * ATTENTION: Do NOT (!) send any security related information via sendDeferredMessage. * Not every push service can validate whether the userID given was forged by a malicious client! * * @see \wcf\system\push\PushHandler::sendMessage() */ public function sendDeferredMessage($message, array $userIDs = array(), array $payload = array()) { if (!$this->isEnabled()) { return false; } if (!\wcf\data\package\Package::isValidPackageName($message)) { return false; } $userIDs = array_unique(\wcf\util\ArrayUtil::toIntegerArray($userIDs)); $this->deferred[] = array('message' => $message, 'userIDs' => $userIDs, 'payload' => $payload); return true; }
/** * Parses a stream containing info from a packages_update.xml. * * @param string $content * @return array $allNewPackages */ protected function parsePackageUpdateXML($content) { // load xml document $xml = new XML(); $xml->loadXML('packageUpdateServer.xml', $content); $xpath = $xml->xpath(); $allNewPackages = array(); $packages = $xpath->query('/ns:section/ns:package'); foreach ($packages as $package) { if (!Package::isValidPackageName($package->getAttribute('name'))) { throw new SystemException("'" . $package->getAttribute('name') . "' is not a valid package name."); } $allNewPackages[$package->getAttribute('name')] = $this->parsePackageUpdateXMLBlock($xpath, $package); } return $allNewPackages; }
/** * @see wcf\form\IForm::validate() */ public function validate() { parent::validate(); if ($this->exportAsPackage) { if (empty($this->packageName)) { throw new UserInputException('packageName'); } if (!Package::isValidPackageName($this->packageName)) { throw new UserInputException('packageName', 'notValid'); } // 3rd party packages may never have com.woltlab.* as name if (strpos($this->packageName, 'com.woltlab.') === 0) { throw new UserInputException('packageName', 'reserved'); } } }
/** * Extracts information about this package (parses package.xml). */ protected function readPackageInfo() { // search package.xml in package archive // throw error message if not found if ($this->tar->getIndexByFilename(self::INFO_FILE) === false) { throw new SystemException("package information file '".(self::INFO_FILE)."' not found in '".$this->archive."'"); } // extract package.xml, parse with SimpleXML // and compile an array with XML::getElementTree() $xml = new XML(); try { $xml->loadXML(self::INFO_FILE, $this->tar->extractToString(self::INFO_FILE)); } catch (\Exception $e) { // bugfix to avoid file caching problems $xml->loadXML(self::INFO_FILE, $this->tar->extractToString(self::INFO_FILE)); } // parse xml $xpath = $xml->xpath(); $package = $xpath->query('/ns:package')->item(0); // package name $packageName = $package->getAttribute('name'); if (!Package::isValidPackageName($packageName)) { // package name is not a valid package identifier throw new SystemException("'".$packageName."' is not a valid package name."); } $this->packageInfo['name'] = $packageName; // get package information $packageInformation = $xpath->query('./ns:packageinformation', $package)->item(0); $elements = $xpath->query('child::*', $packageInformation); foreach ($elements as $element) { switch ($element->tagName) { case 'packagename': case 'packagedescription': case 'readme': case 'license': if (!isset($this->packageInfo[$element->tagName])) $this->packageInfo[$element->tagName] = array(); $languageCode = 'default'; if ($element->hasAttribute('language')) { $languageCode = $element->getAttribute('language'); } // fix case-sensitive names $name = $element->tagName; if ($name == 'packagename') $name = 'packageName'; else if ($name == 'packagedescription') $name = 'packageDescription'; $this->packageInfo[$name][$languageCode] = $element->nodeValue; break; case 'isapplication': $this->packageInfo['isApplication'] = intval($element->nodeValue); break; case 'packageurl': $this->packageInfo['packageURL'] = $element->nodeValue; break; case 'version': if (!Package::isValidVersion($element->nodeValue)) { throw new SystemException("package version '".$element->nodeValue."' is invalid"); } $this->packageInfo['version'] = $element->nodeValue; break; case 'date': DateUtil::validateDate($element->nodeValue); $this->packageInfo['date'] = strtotime($element->nodeValue); break; } } // get author information $authorInformation = $xpath->query('./ns:authorinformation', $package)->item(0); $elements = $xpath->query('child::*', $authorInformation); foreach ($elements as $element) { $tagName = ($element->tagName == 'authorurl') ? 'authorURL' : $element->tagName; $this->authorInfo[$tagName] = $element->nodeValue; } // get required packages $elements = $xpath->query('child::ns:requiredpackages/ns:requiredpackage', $package); foreach ($elements as $element) { if (!Package::isValidPackageName($element->nodeValue)) { throw new SystemException("'".$element->nodeValue."' is not a valid package name."); } // read attributes $data = array('name' => $element->nodeValue); $attributes = $xpath->query('attribute::*', $element); foreach ($attributes as $attribute) { $data[$attribute->name] = $attribute->value; } $this->requirements[$element->nodeValue] = $data; } // get optional packages $elements = $xpath->query('child::ns:optionalpackages/ns:optionalpackage', $package); foreach ($elements as $element) { if (!Package::isValidPackageName($element->nodeValue)) { throw new SystemException("'".$element->nodeValue."' is not a valid package name."); } // read attributes $data = array('name' => $element->nodeValue); $attributes = $xpath->query('attribute::*', $element); foreach ($attributes as $attribute) { $data[$attribute->name] = $attribute->value; } $this->optionals[] = $data; } // get excluded packages $elements = $xpath->query('child::ns:excludedpackages/ns:excludedpackage', $package); foreach ($elements as $element) { if (!Package::isValidPackageName($element->nodeValue)) { throw new SystemException("'".$element->nodeValue."' is not a valid package name."); } // read attributes $data = array('name' => $element->nodeValue); $attributes = $xpath->query('attribute::*', $element); foreach ($attributes as $attribute) { $data[$attribute->name] = $attribute->value; } $this->excludedPackages[] = $data; } // get instructions $elements = $xpath->query('./ns:instructions', $package); foreach ($elements as $element) { $instructionData = array(); $instructions = $xpath->query('./ns:instruction', $element); foreach ($instructions as $instruction) { $data = array(); $attributes = $xpath->query('attribute::*', $instruction); foreach ($attributes as $attribute) { $data[$attribute->name] = $attribute->value; } $instructionData[] = array( 'attributes' => $data, 'pip' => $instruction->getAttribute('type'), 'value' => $instruction->nodeValue ); } $fromVersion = $element->getAttribute('fromversion'); $type = $element->getAttribute('type'); if ($type == 'install') { $this->instructions['install'] = $instructionData; } else { $this->instructions['update'][$fromVersion] = $instructionData; } } // get php requirements $requirements = $xpath->query('./ns:phprequirements', $package); foreach ($requirements as $requirement) { $elements = $xpath->query('child::*', $requirement); foreach ($elements as $element) { switch ($element->tagName) { case 'version': $this->phpRequirements['version'] = $element->nodeValue; break; case 'setting': $this->phpRequirements['settings'][$element->getAttribute('name')] = $element->nodeValue; break; case 'extension': $this->phpRequirements['extensions'][] = $element->nodeValue; break; case 'function': $this->phpRequirements['functions'][] = $element->nodeValue; break; case 'class': $this->phpRequirements['classes'][] = $element->nodeValue; break; } } } // add com.woltlab.wcf to package requirements if (!isset($this->requirements['com.woltlab.wcf']) && $this->packageInfo['name'] != 'com.woltlab.wcf') { $this->requirements['com.woltlab.wcf'] = array('name' => 'com.woltlab.wcf'); } if ($this->package != null) { $validFromVersion = null; foreach ($this->instructions['update'] as $fromVersion => $update) { if (Package::checkFromversion($this->package->packageVersion, $fromVersion)) { $validFromVersion = $fromVersion; break; } } if ($validFromVersion === null) { $this->instructions['update'] = array(); } else { $this->instructions['update'] = $this->instructions['update'][$validFromVersion]; } } // set default values if (!isset($this->packageInfo['isApplication'])) $this->packageInfo['isApplication'] = 0; if (!isset($this->packageInfo['packageURL'])) $this->packageInfo['packageURL'] = ''; }