/** * @see wcf\page\IPage::show() */ public function show() { // use detailed view if accessing WCF ACP directly if (PACKAGE_ID == 1) { // base tag is determined on runtime $host = RouteHandler::getHost(); $path = RouteHandler::getPath(); HeaderUtil::redirect($host . $path . 'index.php/PackageListDetailed/' . SID_ARG_1ST, false); exit; } // enable menu item ACPMenu::getInstance()->setActiveMenuItem('wcf.acp.menu.link.package.list'); parent::show(); }
/** * Prompts for a text input for package directory (applies for applications only) * * @return wcf\system\form\FormDocument */ protected function promptPackageDir() { if (!PackageInstallationFormManager::findForm($this->queue, 'packageDir')) { $container = new GroupFormElementContainer(); $packageDir = new TextInputFormElement($container); $packageDir->setName('packageDir'); $packageDir->setLabel(WCF::getLanguage()->get('wcf.acp.package.packageDir.input')); $path = RouteHandler::getPath(array('wcf', 'acp')); $defaultPath = FileUtil::addTrailingSlash(FileUtil::unifyDirSeperator($_SERVER['DOCUMENT_ROOT'] . $path)); $packageDir->setValue($defaultPath); $container->appendChild($packageDir); $document = new FormDocument('packageDir'); $document->appendContainer($container); PackageInstallationFormManager::registerForm($this->queue, $document); return $document; } else { $document = PackageInstallationFormManager::getForm($this->queue, 'packageDir'); $document->handleRequest(); $packageDir = $document->getValue('packageDir'); if ($packageDir !== null) { // validate package dir if (file_exists(FileUtil::addTrailingSlash($packageDir) . 'global.php')) { $document->setError('packageDir', WCF::getLanguage()->get('wcf.acp.package.packageDir.notAvailable')); return $document; } // set package dir $packageEditor = new PackageEditor($this->getPackage()); $packageEditor->update(array( 'packageDir' => FileUtil::getRelativePath(WCF_DIR, $packageDir) )); // parse domain path $domainPath = FileUtil::getRelativePath(FileUtil::unifyDirSeperator($_SERVER['DOCUMENT_ROOT']), FileUtil::unifyDirSeperator($packageDir)); // work-around for applications installed in document root if ($domainPath == './') { $domainPath = ''; } $domainPath = FileUtil::addLeadingSlash(FileUtil::addTrailingSlash($domainPath)); // update application path $application = new Application($this->getPackage()->packageID); $applicationEditor = new ApplicationEditor($application); $applicationEditor->update(array( 'domainPath' => $domainPath, 'cookiePath' => $domainPath )); // create directory and set permissions @mkdir($packageDir, 0777, true); @chmod($packageDir, 0777); } return null; } }
/** * Returns a relative link. * * @param string $controller * @param array $parameters * @param string $url * @return string */ public function getLink($controller = null, array $parameters = array(), $url = '') { $abbreviation = 'wcf'; $anchor = ''; $isACP = $originIsACP = RequestHandler::getInstance()->isACPRequest(); $forceWCF = $isRaw = false; $appendSession = $encodeTitle = true; // enforce a certain level of sanitation and protection for links embedded in emails if (isset($parameters['isEmail']) && (bool) $parameters['isEmail']) { $parameters['forceFrontend'] = true; $parameters['appendSession'] = false; unset($parameters['isEmail']); } if (isset($parameters['application'])) { $abbreviation = $parameters['application']; } if (isset($parameters['isRaw'])) { $isRaw = $parameters['isRaw']; unset($parameters['isRaw']); } if (isset($parameters['appendSession'])) { $appendSession = $parameters['appendSession']; unset($parameters['appendSession']); } if (isset($parameters['isACP'])) { $isACP = (bool) $parameters['isACP']; unset($parameters['isACP']); // drop session id if link leads to ACP from frontend or vice versa if ($originIsACP != $isACP) { $appendSession = false; } } if (isset($parameters['forceFrontend'])) { if ($parameters['forceFrontend'] && $isACP) { $isACP = false; $appendSession = false; } unset($parameters['forceFrontend']); } if (isset($parameters['forceWCF'])) { if ($parameters['forceWCF'] && $isACP) { $forceWCF = true; } unset($parameters['forceWCF']); } if (isset($parameters['encodeTitle'])) { $encodeTitle = $parameters['encodeTitle']; unset($parameters['encodeTitle']); } // remove anchor before parsing if (($pos = strpos($url, '#')) !== false) { $anchor = substr($url, $pos); $url = substr($url, 0, $pos); } // build route if ($controller === null) { if ($isACP) { $controller = 'Index'; } else { return PageMenu::getInstance()->getLandingPage()->getProcessor()->getLink(); } } // handle object if (isset($parameters['object'])) { if (!$parameters['object'] instanceof IRouteController && $parameters['object'] instanceof DatabaseObjectDecorator && $parameters['object']->getDecoratedObject() instanceof IRouteController) { $parameters['object'] = $parameters['object']->getDecoratedObject(); } if ($parameters['object'] instanceof IRouteController) { $parameters['id'] = $parameters['object']->getObjectID(); $parameters['title'] = $parameters['object']->getTitle(); } } unset($parameters['object']); if (isset($parameters['title'])) { // component replacement if (!empty($this->titleSearch)) { $parameters['title'] = str_replace($this->titleSearch, $this->titleReplace, $parameters['title']); } // remove illegal characters $parameters['title'] = trim($this->titleRegex->replace($parameters['title'], '-'), '-'); // trim to 80 characters $parameters['title'] = rtrim(mb_substr($parameters['title'], 0, 80), '-'); if (!URL_LEGACY_MODE) { $parameters['title'] = mb_strtolower($parameters['title']); } // encode title if ($encodeTitle) { $parameters['title'] = rawurlencode($parameters['title']); } } $parameters['controller'] = $controller; $routeURL = RouteHandler::getInstance()->buildRoute($parameters, $isACP); if (!$isRaw && !empty($url)) { $routeURL .= strpos($routeURL, '?') === false ? '?' : '&'; } // encode certain characters if (!empty($url)) { $url = str_replace(array('[', ']'), array('%5B', '%5D'), $url); } $url = $routeURL . $url; // append session id if ($appendSession) { $url .= strpos($url, '?') === false ? SID_ARG_1ST : SID_ARG_2ND_NOT_ENCODED; } // handle applications if (!PACKAGE_ID) { $url = RouteHandler::getHost() . RouteHandler::getPath(array('acp')) . ($isACP ? 'acp/' : '') . $url; } else { if (RequestHandler::getInstance()->inRescueMode()) { $pageURL = RouteHandler::getHost() . str_replace('//', '/', RouteHandler::getPath(array('acp'))); } else { // try to resolve abbreviation $application = null; if ($abbreviation != 'wcf') { $application = ApplicationHandler::getInstance()->getApplication($abbreviation); } // fallback to primary application if abbreviation is 'wcf' or unknown if ($forceWCF) { $application = ApplicationHandler::getInstance()->getWCF(); } else { if ($application === null) { $application = ApplicationHandler::getInstance()->getPrimaryApplication(); } } $pageURL = $application->getPageURL(); } $url = $pageURL . ($isACP ? 'acp/' : '') . $url; } // append previously removed anchor $url .= $anchor; return $url; }
/** * @see wcf\system\WCF::assignDefaultTemplateVariables() */ protected function assignDefaultTemplateVariables() { parent::assignDefaultTemplateVariables(); // base tag is determined on runtime $host = RouteHandler::getHost(); $path = RouteHandler::getPath(); self::getTPL()->assign(array( 'baseHref' => $host . $path, 'quickAccessPackages' => $this->getQuickAccessPackages(), // todo: 'timezone' => \wcf\util\DateUtil::getTimezone() )); }
/** * Builds a new request. * * @param string $application */ protected function buildRequest($application) { try { $routeData = RouteHandler::getInstance()->getRouteData(); // handle landing page for frontend requests if (!$this->isACPRequest()) { $this->handleDefaultController($application, $routeData); // check if accessing from the wrong domain (e.g. "www." omitted but domain was configured with) if (!defined('WCF_RUN_MODE') || WCF_RUN_MODE != 'embedded') { $applicationObject = ApplicationHandler::getInstance()->getApplication($application); if ($applicationObject->domainName != $_SERVER['HTTP_HOST']) { // build URL, e.g. http://example.net/forum/ $url = FileUtil::addTrailingSlash(RouteHandler::getProtocol() . $applicationObject->domainName . RouteHandler::getPath()); if (URL_LEGACY_MODE) { // add path info, e.g. index.php/Board/2/ $pathInfo = RouteHandler::getPathInfo(); if (!empty($pathInfo)) { $url .= 'index.php' . $pathInfo; } } // query string, e.g. ?foo=bar if (!empty($_SERVER['QUERY_STRING'])) { $url .= '?' . $_SERVER['QUERY_STRING']; } HeaderUtil::redirect($url, true); exit; } } // handle controller aliasing if (empty($routeData['isImplicitController']) && !URL_LEGACY_MODE && isset($routeData['controller'])) { $ciController = mb_strtolower($routeData['controller']); // aliased controller, redirect to new URL $alias = $this->getAliasByController($ciController); if ($alias !== null) { $this->redirect($routeData, $application); } $controller = $this->getControllerByAlias($ciController); if ($controller !== null) { // check if controller was provided explicitly as it should $alias = $this->getAliasByController($controller); if ($alias != $routeData['controller']) { $routeData['controller'] = $controller; $this->redirect($routeData, $application); } $routeData['controller'] = $controller; } } } else { if (empty($routeData['controller'])) { $routeData['controller'] = 'Index'; } } $controller = $routeData['controller']; // validate class name if (!preg_match('~^[a-z0-9-]+$~i', $controller)) { throw new SystemException("Illegal class name '" . $controller . "'"); } // work-around for WCFSetup if (!PACKAGE_ID) { $parts = explode('-', $controller); $parts = array_map(function ($part) { return ucfirst($part); }, $parts); $controller = implode('', $parts); } // find class $classData = $this->getClassData($controller, 'page', $application); if ($classData === null) { $classData = $this->getClassData($controller, 'form', $application); } if ($classData === null) { $classData = $this->getClassData($controller, 'action', $application); } if ($classData === null) { throw new SystemException("unable to find class for controller '" . $controller . "'"); } else { if (!class_exists($classData['className'])) { throw new SystemException("unable to find class '" . $classData['className'] . "'"); } } // check if controller was provided exactly as it should if (!URL_LEGACY_MODE && !$this->isACPRequest()) { if (preg_match('~([A-Za-z0-9]+)(?:Action|Form|Page)$~', $classData['className'], $matches)) { $realController = self::getTokenizedController($matches[1]); if ($controller != $realController) { $this->redirect($routeData, $application, $matches[1]); } } } $this->activeRequest = new Request($classData['className'], $classData['controller'], $classData['pageType']); } catch (SystemException $e) { throw new IllegalLinkException(); } }
/** * @see \wcf\form\IForm::save() */ public function save() { parent::save(); // change user WCF::getSession()->changeUser($this->user); $this->saved(); if (!empty($this->url)) { // append session if (mb_strpos($this->url, '?') !== false) { $this->url .= SID_ARG_2ND_NOT_ENCODED; } else { $this->url .= SID_ARG_1ST; } HeaderUtil::redirect($this->url); } else { if (RequestHandler::getInstance()->inRescueMode()) { $path = RouteHandler::getHost() . RouteHandler::getPath() . SID_ARG_1ST; } else { $application = ApplicationHandler::getInstance()->getActiveApplication(); $path = $application->getPageURL() . 'acp/' . SID_ARG_1ST; } HeaderUtil::redirect($path); } exit; }
/** * @see \wcf\system\WCF::assignDefaultTemplateVariables() */ protected function assignDefaultTemplateVariables() { parent::assignDefaultTemplateVariables(); // base tag is determined on runtime $host = RouteHandler::getHost(); $path = RouteHandler::getPath(); self::getTPL()->assign(array('baseHref' => $host . $path)); }
/** * Returns a relative link. * * @param string $controller * @param array $parameters * @param string $url * @return string */ public function getLink($controller = null, array $parameters = array(), $url = '') { $abbreviation = 'wcf'; $anchor = ''; $isACP = $originIsACP = RequestHandler::getInstance()->isACPRequest(); $isRaw = false; $appendSession = true; if (isset($parameters['application'])) { $abbreviation = $parameters['application']; unset($parameters['application']); } if (isset($parameters['isRaw'])) { $isRaw = $parameters['isRaw']; unset($parameters['isRaw']); } if (isset($parameters['appendSession'])) { $appendSession = $parameters['appendSession']; unset($parameters['appendSession']); } if (isset($parameters['isACP'])) { $isACP = (bool) $parameters['isACP']; unset($parameters['isACP']); // drop session id if link leads to ACP from frontend or vice versa if ($originIsACP != $isACP) { $appendSession = false; } } // remove anchor before parsing if (($pos = strpos($url, '#')) !== false) { $anchor = substr($url, $pos); $url = substr($url, 0, $pos); } // build route if ($controller === null) { // build link to landing page $landingPage = PageMenu::getInstance()->getLandingPage(); $controller = $landingPage->getController(); $abbreviation = $landingPage->getApplication(); $url = $landingPage->menuItemLink; } // handle object if (isset($parameters['object'])) { if (!($parameters['object'] instanceof IRouteController) && $parameters['object'] instanceof DatabaseObjectDecorator && $parameters['object']->getDecoratedObject() instanceof IRouteController) { $parameters['object'] = $parameters['object']->getDecoratedObject(); } if ($parameters['object'] instanceof IRouteController) { $parameters['id'] = $parameters['object']->getObjectID(); $parameters['title'] = $parameters['object']->getTitle(); } unset($parameters['object']); } if (isset($parameters['title'])) { // remove illegal characters $parameters['title'] = trim($this->titleRegex->replace($parameters['title'], '-'), '-'); } $parameters['controller'] = $controller; $routeURL = RouteHandler::getInstance()->buildRoute($parameters); if (!$isRaw && !empty($url)) { $routeURL .= (strpos($routeURL, '?') === false) ? '?' : '&'; } $url = $routeURL . $url; // append session id if ($appendSession) { $url .= (strpos($url, '?') === false) ? SID_ARG_1ST : SID_ARG_2ND_NOT_ENCODED; } // handle applications if (!PACKAGE_ID) { $url = RouteHandler::getHost() . RouteHandler::getPath(array('acp')) . ($isACP ? 'acp/' : '') . $url; } else { // try to resolve abbreviation $application = null; if ($abbreviation != 'wcf') { $application = ApplicationHandler::getInstance()->getApplication($abbreviation); } // fallback to primary application if abbreviation is 'wcf' or unknown if ($application === null) { $application = ApplicationHandler::getInstance()->getPrimaryApplication(); } $url = $application->getPageURL() . ($isACP ? 'acp/' : '') . $url; } // append previously removed anchor $url .= $anchor; return $url; }
/** * Installs current package. * * @param array $nodeData */ protected function installPackage(array $nodeData) { $installationStep = new PackageInstallationStep(); // check requirements if (!empty($nodeData['requirements'])) { foreach ($nodeData['requirements'] as $package => $requirementData) { // get existing package if ($requirementData['packageID']) { $sql = "SELECT\tpackageName, packageVersion\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\t\t\tWHERE\tpackageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($requirementData['packageID'])); } else { // try to find matching package $sql = "SELECT\tpackageName, packageVersion\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\t\t\tWHERE\tpackage = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($package)); } $row = $statement->fetchArray(); // package is required but not available if ($row === false) { throw new SystemException("Package '" . $package . "' is required by '" . $nodeData['packageName'] . "', but is neither installed nor shipped."); } // check version requirements if ($requirementData['minVersion']) { if (Package::compareVersion($row['packageVersion'], $requirementData['minVersion']) < 0) { throw new SystemException("Package '" . $nodeData['packageName'] . "' requires package '" . $row['packageName'] . "' in version '" . $requirementData['minVersion'] . "', but only version '" . $row['packageVersion'] . "' is installed"); } } } } unset($nodeData['requirements']); // update package if ($this->queue->packageID) { $packageEditor = new PackageEditor(new Package($this->queue->packageID)); $packageEditor->update($nodeData); // delete old excluded packages $sql = "DELETE FROM\twcf" . WCF_N . "_package_exclusion\n\t\t\t\tWHERE\t\tpackageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->queue->packageID)); // delete old requirements and dependencies $sql = "DELETE FROM\twcf" . WCF_N . "_package_requirement\n\t\t\t\tWHERE\t\tpackageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->queue->packageID)); } else { // create package entry $package = PackageEditor::create($nodeData); // update package id for current queue $queueEditor = new PackageInstallationQueueEditor($this->queue); $queueEditor->update(array('packageID' => $package->packageID)); // reload queue $this->queue = new PackageInstallationQueue($this->queue->queueID); $this->package = null; if ($package->isApplication) { $host = str_replace(RouteHandler::getProtocol(), '', RouteHandler::getHost()); $path = RouteHandler::getPath(array('acp')); // insert as application ApplicationEditor::create(array('domainName' => $host, 'domainPath' => $path, 'cookieDomain' => $host, 'cookiePath' => $path, 'packageID' => $package->packageID)); } } // save excluded packages if (count($this->getArchive()->getExcludedPackages())) { $sql = "INSERT INTO\twcf" . WCF_N . "_package_exclusion\n\t\t\t\t\t\t(packageID, excludedPackage, excludedPackageVersion)\n\t\t\t\tVALUES\t\t(?, ?, ?)"; $statement = WCF::getDB()->prepareStatement($sql); foreach ($this->getArchive()->getExcludedPackages() as $excludedPackage) { $statement->execute(array($this->queue->packageID, $excludedPackage['name'], !empty($excludedPackage['version']) ? $excludedPackage['version'] : '')); } } // insert requirements and dependencies $requirements = $this->getArchive()->getAllExistingRequirements(); if (!empty($requirements)) { $sql = "INSERT INTO\twcf" . WCF_N . "_package_requirement\n\t\t\t\t\t\t(packageID, requirement)\n\t\t\t\tVALUES\t\t(?, ?)"; $statement = WCF::getDB()->prepareStatement($sql); foreach ($requirements as $identifier => $possibleRequirements) { $requirement = array_shift($possibleRequirements); $statement->execute(array($this->queue->packageID, $requirement['packageID'])); } } if ($this->getPackage()->isApplication && $this->getPackage()->package != 'com.woltlab.wcf' && $this->getAction() == 'install') { if (empty($this->getPackage()->packageDir)) { $document = $this->promptPackageDir(); if ($document !== null && $document instanceof FormDocument) { $installationStep->setDocument($document); } $installationStep->setSplitNode(); } } return $installationStep; }