/** * Assigns a list of applications to a group and computes cookie domain and path. */ public function rebuild() { if (empty($this->objects)) { $this->readObjects(); } $sql = "UPDATE wcf".WCF_N."_application SET cookieDomain = ?, cookiePath = ? WHERE packageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); // calculate cookie path $domains = array(); foreach ($this->objects as $application) { if (!isset($domains[$application->domainName])) { $domains[$application->domainName] = array(); } $domains[$application->domainName][$application->packageID] = explode('/', FileUtil::removeLeadingSlash(FileUtil::removeTrailingSlash($application->domainPath))); } WCF::getDB()->beginTransaction(); foreach ($domains as $domainName => $data) { $path = null; foreach ($data as $domainPath) { if ($path === null) { $path = $domainPath; } else { foreach ($path as $i => $part) { if (!isset($domainPath[$i]) || $domainPath[$i] != $part) { // remove all following elements including current one foreach ($path as $j => $innerPart) { if ($j >= $i) { unset($path[$j]); } } // skip to next domain continue 2; } } } } $path = FileUtil::addLeadingSlash(FileUtil::addTrailingSlash(implode('/', $path))); foreach (array_keys($data) as $packageID) { $statement->execute(array( $domainName, $path, $packageID )); } } WCF::getDB()->commitTransaction(); }
/** * Assigns a list of applications to a group and computes cookie domain and path. */ public function rebuild() { if (empty($this->objects)) { $this->readObjects(); } $sql = "UPDATE\twcf" . WCF_N . "_application\n\t\t\tSET\tcookieDomain = ?,\n\t\t\t\tcookiePath = ?\n\t\t\tWHERE\tpackageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); // calculate cookie path $domains = array(); $regex = new Regex(':[0-9]+'); foreach ($this->objects as $application) { $domainName = $application->domainName; if (StringUtil::endsWith($regex->replace($domainName, ''), $application->cookieDomain)) { $domainName = $application->cookieDomain; } if (!isset($domains[$domainName])) { $domains[$domainName] = array(); } $domains[$domainName][$application->packageID] = explode('/', FileUtil::removeLeadingSlash(FileUtil::removeTrailingSlash($application->domainPath))); } WCF::getDB()->beginTransaction(); foreach ($domains as $domainName => $data) { $path = null; foreach ($data as $domainPath) { if ($path === null) { $path = $domainPath; } else { foreach ($path as $i => $part) { if (!isset($domainPath[$i]) || $domainPath[$i] != $part) { // remove all following elements including current one foreach ($path as $j => $innerPart) { if ($j >= $i) { unset($path[$j]); } } // skip to next domain continue 2; } } } } $path = FileUtil::addLeadingSlash(FileUtil::addTrailingSlash(implode('/', $path))); foreach (array_keys($data) as $packageID) { $statement->execute(array($domainName, $path, $packageID)); } } WCF::getDB()->commitTransaction(); // rebuild templates LanguageFactory::getInstance()->deleteLanguageCache(); // reset application cache ApplicationCacheBuilder::getInstance()->reset(); }
/** * 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; } }
/** * @see wcf\form\IForm::validate() */ public function validate() { parent::validate(); if (empty($this->domainName)) { throw new UserInputException('domainName'); } else { $regex = new Regex('^https?\://'); $this->domainName = FileUtil::removeTrailingSlash($regex->replace($this->domainName, '')); $this->cookieDomain = FileUtil::removeTrailingSlash($regex->replace($this->cookieDomain, '')); // domain may not contain path components $regex = new Regex('[/#\?&]'); if ($regex->match($this->domainName)) { throw new UserInputException('domainName', 'containsPath'); } else if ($regex->match($this->cookieDomain)) { throw new UserInputException('cookieDomain', 'containsPath'); } // check if cookie domain shares the same domain (may exclude subdomains) if (!StringUtil::endsWith($this->domainName, $this->cookieDomain)) { throw new UserInputException('cookieDomain', 'notValid'); } } if (empty($this->domainPath)) { $this->cookiePath = ''; } else { // strip first and last slash $this->domainPath = FileUtil::removeLeadingSlash(FileUtil::removeTrailingSlash($this->domainPath)); $this->cookiePath = FileUtil::removeLeadingSlash(FileUtil::removeTrailingSlash($this->cookiePath)); if (!empty($this->cookiePath) && ($this->domainPath != $this->cookiePath)) { // check if cookie path is contained within domain path if (!StringUtil::startsWith($this->domainPath, $this->cookiePath)) { throw new UserInputException('cookiePath', 'notValid'); } } } // add slashes $this->domainPath = FileUtil::addLeadingSlash(FileUtil::addTrailingSlash($this->domainPath)); $this->cookiePath = FileUtil::addLeadingSlash(FileUtil::addTrailingSlash($this->cookiePath)); }
/** * @see \wcf\form\IForm::validate() */ public function validate() { parent::validate(); if (empty($this->domainName)) { throw new UserInputException('domainName'); } else { $regex = new Regex('^https?\\://'); $this->domainName = FileUtil::removeTrailingSlash($regex->replace($this->domainName, '')); $this->cookieDomain = FileUtil::removeTrailingSlash($regex->replace($this->cookieDomain, '')); // domain may not contain path components $regex = new Regex('[/#\\?&]'); if ($regex->match($this->domainName)) { throw new UserInputException('domainName', 'containsPath'); } else { if ($regex->match($this->cookieDomain)) { throw new UserInputException('cookieDomain', 'containsPath'); } } // strip port from cookie domain $regex = new Regex(':[0-9]+$'); $this->cookieDomain = $regex->replace($this->cookieDomain, ''); // check if cookie domain shares the same domain (may exclude subdomains) if (!StringUtil::endsWith($regex->replace($this->domainName, ''), $this->cookieDomain)) { throw new UserInputException('cookieDomain', 'notValid'); } } // add slashes $this->domainPath = FileUtil::addLeadingSlash(FileUtil::addTrailingSlash($this->domainPath)); // search for other applications with the same domain and path $sql = "SELECT\tpackageID\n\t\t\tFROM\twcf" . WCF_N . "_application\n\t\t\tWHERE\tdomainName = ?\n\t\t\t\tAND domainPath = ?\n\t\t\t\tAND packageID <> ?"; $statement = WCF::getDB()->prepareStatement($sql, 1); $statement->execute(array($this->domainName, $this->domainPath, $this->application->packageID)); $row = $statement->fetchArray(); if ($row) { WCF::getTPL()->assign('conflictApplication', PackageCache::getInstance()->getPackage($row['packageID'])); throw new UserInputException('domainPath', 'conflict'); } }