$pageURL = $application->getPageURL();
}
- $path = $pageURL . 'acp/?Login/' . SID_ARG_2ND . '&url=' . rawurlencode(RouteHandler::getProtocol() . $_SERVER['HTTP_HOST'] . WCF::getSession()->requestURI);
+ // drop session id
+ $redirectURI = preg_replace('~[&\?]s=[a-f0-9]{40}(&|$)~', '', WCF::getSession()->requestURI);
+
+ $path = $pageURL . 'acp/?Login/' . SID_ARG_2ND_NOT_ENCODED . '&url=' . rawurlencode(RouteHandler::getProtocol() . $_SERVER['HTTP_HOST'] . $redirectURI);
HeaderUtil::redirect($path);
exit;
--- /dev/null
+<?php
+namespace wcf\system\cache\builder;
+use wcf\data\package\Package;
+use wcf\data\package\PackageList;
+
+/**
+ * Caches available controllers for case-insensitive lookup.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2014 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.cache.builder
+ * @category Community Framework
+ */
+class ControllerCacheBuilder extends AbstractCacheBuilder {
+ /**
+ * @see \wcf\system\cache\builder\AbstractCacheBuilder::rebuild()
+ */
+ public function rebuild(array $parameters) {
+ $data = array();
+ $isACP = ($parameters['environment'] == 'admin');
+
+ $packageList = new PackageList();
+ $packageList->getConditionBuilder()->add("isApplication = ?", array(1));
+ $packageList->readObjects();
+ foreach ($packageList as $package) {
+ $abbreviation = Package::getAbbreviation($package->package);
+ $path = WCF_DIR . $package->packageDir . 'lib/' . ($isACP ? 'acp/' : '');
+
+ $data[$abbreviation] = array(
+ 'action' => $this->getControllers($path, $abbreviation, 'action', $isACP),
+ 'form' => $this->getControllers($path, $abbreviation, 'form', $isACP),
+ 'page' => $this->getControllers($path, $abbreviation, 'page', $isACP)
+ );
+ }
+
+ return $data;
+ }
+
+ /**
+ * Returns a list of case-insensitive controllers with their fully-qualified namespace grouped by type.
+ *
+ * @param string $path
+ * @param string $abbreviation
+ * @param string $type
+ * @param boolean $isACP
+ * @return array<string>
+ */
+ protected function getControllers($path, $abbreviation, $type, $isACP) {
+ $controllers = array();
+ $path .= $type . '/';
+
+ foreach(glob($path . '*' . ucfirst($type) . '.class.php') as $file) {
+ $file = basename($file);
+ if (preg_match('~^([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(Action|Form|Page)\.class\.php$~', $file, $match)) {
+ if ($match[1] === 'I') {
+ continue;
+ }
+
+ $controller = mb_strtolower($match[1]);
+ $fqn = '\\' . $abbreviation . '\\' . ($isACP ? 'acp\\' : '') . $type . '\\' . $match[1] . $match[2];
+
+ $controllers[$controller] = $fqn;
+ }
+ }
+
+ return $controllers;
+ }
+}
<?php
namespace wcf\system\request;
use wcf\system\application\ApplicationHandler;
+use wcf\system\cache\builder\ControllerCacheBuilder;
use wcf\system\exception\AJAXException;
use wcf\system\exception\IllegalLinkException;
use wcf\system\exception\SystemException;
*/
protected $activeRequest = null;
+ /**
+ * list of known controllers grouped by application and type
+ * @var array<array>
+ */
+ protected $controllers = null;
+
/**
* true, if current domain mismatch any known domain
* @var boolean
// when using cli, no rescue mode is provided
$this->inRescueMode = false;
}
+
+ if (class_exists('wcf\system\WCFACP', false)) {
+ $this->isACPRequest = true;
+ }
+
+ if (PACKAGE_ID) {
+ $this->controllers = ControllerCacheBuilder::getInstance()->getData(array(
+ 'environment' => ($this->isACPRequest ? 'admin' : 'user')
+ ));
+ }
}
/**
* @return array
*/
protected function getClassData($controller, $pageType, $application) {
- $className = $application.'\\'.($this->isACPRequest() ? 'acp\\' : '').$pageType.'\\'.ucfirst($controller).ucfirst($pageType);
- if ($application != 'wcf' && !class_exists($className)) {
- $className = 'wcf\\'.($this->isACPRequest() ? 'acp\\' : '').$pageType.'\\'.ucfirst($controller).ucfirst($pageType);
+ $className = false;
+
+ if ($this->controllers !== null) {
+ $className = $this->lookupController($controller, $pageType, $application);
+ if ($className === false && $application != 'wcf') {
+ $className = $this->lookupController($controller, $pageType, 'wcf');
+ }
+ }
+
+ // controller is either unknown or within WCFSetup
+ if ($className === false) {
+ $className = $application.'\\'.($this->isACPRequest() ? 'acp\\' : '').$pageType.'\\'.ucfirst($controller).ucfirst($pageType);
+ if ($application != 'wcf' && !class_exists($className)) {
+ $className = 'wcf\\'.($this->isACPRequest() ? 'acp\\' : '').$pageType.'\\'.ucfirst($controller).ucfirst($pageType);
+ }
}
+
if (!class_exists($className)) {
return null;
}
);
}
+ /**
+ * Lookups a controller from the list of known controllers using a case-insensitive search.
+ *
+ * @param string $controller
+ * @param string $pageType
+ * @param string $application
+ * @return boolean
+ */
+ protected function lookupController($controller, $pageType, $application) {
+ if (isset($this->controllers[$application]) && isset($this->controllers[$application][$pageType])) {
+ $ciController = mb_strtolower($controller);
+ if (isset($this->controllers[$application][$pageType][$ciController])) {
+ return $this->controllers[$application][$pageType][$ciController];
+ }
+ }
+
+ return false;
+ }
+
/**
* Returns the active request object.
*
if (!empty($components)) {
if (strpos($link, '?') === false) $link .= '?';
+ else $link .= '&';
+
$link .= http_build_query($components, '', '&');
}
self::$pathInfo = '';
// WCF 2.0: index.php/Foo/Bar/
- if (URL_LEGACY_MODE) {
+ if (URL_LEGACY_MODE && !RequestHandler::getInstance()->isACPRequest()) {
if (isset($_SERVER['PATH_INFO'])) {
self::$pathInfo = $_SERVER['PATH_INFO'];
}