Commit 03aa6703 authored by catch's avatar catch

Issue #2343607 by alexpott, dawehner: Cleanup UrlGenerator.

parent 6398a197
......@@ -886,9 +886,6 @@ function install_display_output($output, $install_state) {
// reached in case of an early installer error.
drupal_maintenance_theme();
// Ensure the URL generator is initialized.
\Drupal::urlGenerator()->updateFromRequest();
drupal_page_header();
// Prevent install.php from being indexed when installed in a sub folder.
......
......@@ -10,6 +10,7 @@
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Symfony\Component\DependencyInjection\Reference;
/**
* Service provider for the early installer environment.
......@@ -43,7 +44,8 @@ public function register(ContainerBuilder $container) {
$container
->register('lock', 'Drupal\Core\Lock\NullLockBackend');
$container
->register('url_generator', 'Drupal\Core\Routing\NullGenerator');
->register('url_generator', 'Drupal\Core\Routing\NullGenerator')
->addArgument(new Reference('request_stack'));
$container
->register('router.dumper', 'Drupal\Core\Routing\NullMatcherDumper');
......
......@@ -7,6 +7,7 @@
namespace Drupal\Core\Routing;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\Route;
......@@ -18,18 +19,12 @@ class NullGenerator extends UrlGenerator {
/**
* Override the parent constructor.
*
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
*/
public function __construct() {
}
/**
* {@inheritdoc}
*/
public function updateFromRequest() {
global $base_url, $base_path, $script_path;
$this->basePath = $base_path;
$this->baseUrl = $base_url . '/';
$this->scriptPath = $script_path;
public function __construct(RequestStack $request_stack) {
$this->requestStack = $request_stack;
}
/**
......
......@@ -48,27 +48,6 @@ class UrlGenerator extends ProviderBasedGenerator implements UrlGeneratorInterfa
*/
protected $routeProcessor;
/**
* The base path to use for urls.
*
* @var string
*/
protected $basePath;
/**
* The base url to use for urls.
*
* @var string
*/
protected $baseUrl;
/**
* The script path to use for urls.
*
* @var string
*/
protected $scriptPath;
/**
* Whether both secure and insecure session cookies can be used simultaneously.
*
......@@ -103,28 +82,6 @@ public function __construct(RouteProviderInterface $provider, OutboundPathProces
$allowed_protocols = $config->get('system.filter')->get('protocols') ?: array('http', 'https');
UrlHelper::setAllowedProtocols($allowed_protocols);
$this->requestStack = $request_stack;
$this->updateFromRequest();
}
/**
* Updates instance properties using the current request from the stack.
*
* @todo This should probably be inline in the constructor as this is only
* useful to get some current tests pass.
*/
public function updateFromRequest() {
$request = $this->requestStack->getCurrentRequest();
// Set some properties, based on the request, that are used during path-based
// url generation.
$this->basePath = $request->getBasePath() . '/';
$this->baseUrl = $request->getSchemeAndHttpHost() . $this->basePath;
$this->scriptPath = '';
$base_path_with_script = $request->getBaseUrl();
$script_name = $request->getScriptName();
if (!empty($base_path_with_script) && strpos($base_path_with_script, $script_name) !== FALSE) {
$length = strlen($this->basePath);
$this->scriptPath = ltrim(substr($script_name, $length), '/') . '/';
}
}
/**
......@@ -243,9 +200,16 @@ public function generateFromRoute($name, $parameters = array(), $options = array
* {@inheritdoc}
*/
public function generateFromPath($path = NULL, $options = array()) {
if (!$this->initialized()) {
throw new GeneratorNotInitializedException();
$request = $this->requestStack->getCurrentRequest();
$current_base_path = $request->getBasePath() . '/';
$current_base_url = $request->getSchemeAndHttpHost() . $current_base_path;
$current_script_path = '';
$base_path_with_script = $request->getBaseUrl();
if (!empty($base_path_with_script)) {
$script_name = $request->getScriptName();
if (strpos($base_path_with_script, $script_name) !== FALSE) {
$current_script_path = ltrim(substr($script_name, strlen($current_base_path)), '/') . '/';
}
}
// Merge in defaults.
......@@ -301,28 +265,28 @@ public function generateFromPath($path = NULL, $options = array()) {
}
if (!isset($options['script'])) {
$options['script'] = $this->scriptPath;
$options['script'] = $current_script_path;
}
// The base_url might be rewritten from the language rewrite in domain mode.
if (!isset($options['base_url'])) {
if (isset($options['https']) && $this->mixedModeSessions) {
if ($options['https'] === TRUE) {
$options['base_url'] = str_replace('http://', 'https://', $this->baseUrl);
$options['base_url'] = str_replace('http://', 'https://', $current_base_url);
$options['absolute'] = TRUE;
}
elseif ($options['https'] === FALSE) {
$options['base_url'] = str_replace('https://', 'http://', $this->baseUrl);
$options['base_url'] = str_replace('https://', 'http://', $current_base_url);
$options['absolute'] = TRUE;
}
}
else {
$options['base_url'] = $this->baseUrl;
$options['base_url'] = $current_base_url;
}
}
elseif (rtrim($options['base_url'], '/') == $options['base_url']) {
$options['base_url'] .= '/';
}
$base = $options['absolute'] ? $options['base_url'] : $this->basePath;
$base = $options['absolute'] ? $options['base_url'] : $current_base_path;
$prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix'];
$path = str_replace('%2F', '/', rawurlencode($prefix . $path));
......@@ -330,27 +294,6 @@ public function generateFromPath($path = NULL, $options = array()) {
return $base . $options['script'] . $path . $query . $options['fragment'];
}
/**
* {@inheritdoc}
*/
public function setBaseUrl($url) {
$this->baseUrl = $url;
}
/**
* {@inheritdoc}
*/
public function setBasePath($path) {
$this->basePath = $path;
}
/**
* {@inheritdoc}
*/
public function setScriptPath($path) {
$this->scriptPath = $path;
}
/**
* Passes the path to a processor manager to allow alterations.
*/
......@@ -384,17 +327,6 @@ protected function processRoute(SymfonyRoute $route, array &$parameters) {
$this->routeProcessor->processOutbound($route, $parameters);
}
/**
* Returns whether or not the url generator has been initialized.
*
* @return bool
* Returns TRUE if the basePath, baseUrl and scriptPath properties have been
* set, FALSE otherwise.
*/
protected function initialized() {
return isset($this->basePath) && isset($this->baseUrl) && isset($this->scriptPath);
}
/**
* Find the route using the provided route name.
*
......
......@@ -143,57 +143,4 @@ public function getPathFromRoute($name, $parameters = array());
*/
public function generateFromRoute($name, $parameters = array(), $options = array());
/**
* Sets the baseUrl property.
*
* This property is made up of scheme, host and base_path, e.g.
* 'http://www.example.com/mydrupalinstall/'
*
* The base url is usually set by the request but we allow it to be set
* independent of the request so that code that calls url() outside the context
* of a request can use the global $base_url variable to set this value.
*
* @todo Remove this once the url() function no longer supports being called
* when there is no request.
*
* @var string $url
* The base url to use for url generation.
*/
public function setBaseUrl($url);
/**
* Sets the basePath property.
*
* This will be either '/' or '[subdir]/', where [subdir] is the name of the
* subdirectory that Drupal is running in.
*
* The base path is usually set by the request but we allow it to be set
* independent of the request so that code that calls url() outside the context
* of a request can use the global $base_url variable to set this value.
*
* @todo Remove this once the url() function no longer supports being called
* when there is no request.
*
* @var string $path
* The base path to use for url generation.
*/
public function setBasePath($path);
/**
* Sets the scriptPath property.
*
* The script path is usually set by the request and is either 'index.php' or
* the empty string, depending on whether the request path actually contains
* the script path or not. We allow it to be set independent of the request so
* that code that calls url() outside the context of a request can use the global
* $script_path variable to set this value.
*
* @todo Remove this once the url() function no longer supports being called
* when there is no request.
*
* @var string $path
* The script path to use for url generation.
*/
public function setScriptPath($path);
}
......@@ -2673,7 +2673,6 @@ protected function verboseEmail($count = 1) {
* The mocked request object.
*/
protected function prepareRequestForGenerator($clean_urls = TRUE, $override_server_vars = array()) {
$generator = $this->container->get('url_generator');
$request = Request::createFromGlobals();
$server = $request->server->all();
if (basename($server['SCRIPT_FILENAME']) != basename($server['SCRIPT_NAME'])) {
......@@ -2697,7 +2696,6 @@ protected function prepareRequestForGenerator($clean_urls = TRUE, $override_serv
$request = Request::create($request_path, 'GET', array(), array(), array(), $server);
$this->container->get('request_stack')->push($request);
$generator->updateFromRequest();
return $request;
}
}
......@@ -172,8 +172,8 @@ protected function testMixedModeSslSession() {
$ssid = $this->cookies[$secure_session_name]['value'];
$this->assertSessionIds($sid, $ssid, 'Session has both secure and insecure SIDs');
$cookies = array(
$insecure_session_name . '=' . $sid,
$secure_session_name . '=' . $ssid,
'http' => $insecure_session_name . '=' . $sid,
'https' => $secure_session_name . '=' . $ssid,
);
// Test that session data saved before login is still available on the
......@@ -182,8 +182,11 @@ protected function testMixedModeSslSession() {
$this->assertText($session_data, 'Session correctly returned the stored data set by the anonymous session.');
foreach ($cookies as $cookie_key => $cookie) {
foreach (array('admin/config', $this->httpsUrl('admin/config')) as $url_key => $url) {
foreach (array('http' => 'admin/config', 'https' => $this->httpsUrl('admin/config')) as $url_key => $url) {
$this->curlClose();
// The HTTPS setting needs to be set correctly on the request for the
// URL generator to work.
$this->request->server->set('HTTPS', $url_key == 'https' ? 'on' : 'off');
$this->drupalGet($url, array(), array('Cookie: ' . $cookie));
if ($cookie_key == $url_key) {
......
......@@ -53,6 +53,13 @@ class UrlGeneratorTest extends UnitTestCase {
*/
protected $routeProcessorManager;
/**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
protected function setUp() {
$routes = new RouteCollection();
......@@ -126,15 +133,15 @@ protected function setUp() {
$config_factory_stub = $this->getConfigFactoryStub(array('system.filter' => array('protocols' => array('http', 'https'))));
$requestStack = new RequestStack();
$requestStack->push($request);
$this->requestStack = new RequestStack();
$this->requestStack->push($request);
$generator = new UrlGenerator($provider, $processor_manager, $this->routeProcessorManager, $config_factory_stub, new Settings(array()), NULL, $requestStack);
$generator = new UrlGenerator($provider, $processor_manager, $this->routeProcessorManager, $config_factory_stub, new Settings(array()), NULL, $this->requestStack);
$generator->setContext($context);
$this->generator = $generator;
// Second generator for mixed-mode sessions.
$generator = new UrlGenerator($provider, $processor_manager, $this->routeProcessorManager, $config_factory_stub, new Settings(array('mixed_mode_sessions' => TRUE)), NULL, $requestStack);
$generator = new UrlGenerator($provider, $processor_manager, $this->routeProcessorManager, $config_factory_stub, new Settings(array('mixed_mode_sessions' => TRUE)), NULL, $this->requestStack);
$generator->setContext($context);
$this->generatorMixedMode = $generator;
}
......@@ -187,8 +194,6 @@ public function testAliasGeneration() {
* Tests URL generation in a subdirectory.
*/
public function testGetPathFromRouteWithSubdirectory() {
$this->generator->setBasePath('/test-base-path');
$this->routeProcessorManager->expects($this->never())
->method('processOutbound');
......@@ -279,11 +284,21 @@ public function testUrlGenerationWithHttpsRequirement() {
public function testPathBasedURLGeneration() {
$base_path = '/subdir';
$base_url = 'http://www.example.com' . $base_path;
$this->generator->setBasePath($base_path . '/');
$this->generator->setBaseUrl($base_url . '/');
foreach (array('', 'index.php/') as $script_path) {
$this->generator->setScriptPath($script_path);
foreach (array(FALSE, TRUE) as $absolute) {
// Setup a fake request which looks like a Drupal installed under the
// subdir "subdir" on the domain www.example.com.
// To reproduce the values install Drupal like that and use a debugger.
$server = [
'SCRIPT_NAME' => '/subdir/index.php',
'SCRIPT_FILENAME' => DRUPAL_ROOT . '/index.php',
'SERVER_NAME' => 'http://www.example.com',
];
$request = Request::create('/subdir/' . $script_path, 'GET', [], [], [], $server);
$request->headers->set('host', ['www.example.com']);
$this->requestStack->push($request);
// Get the expected start of the path string.
$base = ($absolute ? $base_url . '/' : $base_path . '/') . $script_path;
$url = $base . 'node/123';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment