Commit 16caf92d authored by catch's avatar catch

Issue #1833010 by Gábor Hojtsy: Fixed Admin user language preference WSOD if...

Issue #1833010 by Gábor Hojtsy: Fixed Admin user language preference WSOD if ahead of path prefixes.
parent 2ecdf8ce
......@@ -7,12 +7,14 @@
namespace Drupal\user\Plugin\LanguageNegotiation;
use Drupal\Core\PathProcessor\PathProcessorManager;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Routing\AdminContext;
use Drupal\language\LanguageNegotiationMethodBase;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
/**
......@@ -50,6 +52,13 @@ class LanguageNegotiationUserAdmin extends LanguageNegotiationMethodBase impleme
*/
protected $router;
/**
* The path processor manager.
*
* @var \Drupal\Core\PathProcessor\PathProcessorManager
*/
protected $pathProcessorManager;
/**
* Constructs a new LanguageNegotiationUserAdmin instance.
*
......@@ -57,10 +66,13 @@ class LanguageNegotiationUserAdmin extends LanguageNegotiationMethodBase impleme
* The admin context.
* @param \Symfony\Component\Routing\Matcher\UrlMatcherInterface $router
* The router.
* @param \Drupal\Core\PathProcessor\PathProcessorManager $path_processor_manager
* The path processor manager.
*/
public function __construct(AdminContext $admin_context, UrlMatcherInterface $router) {
public function __construct(AdminContext $admin_context, UrlMatcherInterface $router, PathProcessorManager $path_processor_manager) {
$this->adminContext = $admin_context;
$this->router = $router;
$this->pathProcessorManager = $path_processor_manager;
}
/**
......@@ -69,7 +81,8 @@ public function __construct(AdminContext $admin_context, UrlMatcherInterface $ro
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$container->get('router.admin_context'),
$container->get('router')
$container->get('router'),
$container->get('path_processor_manager')
);
}
......@@ -105,10 +118,20 @@ public function getLangcode(Request $request = NULL) {
public function isAdminPath(Request $request) {
$result = FALSE;
if ($request && $this->adminContext) {
// If called from an event subscriber, the request may not the route info
// yet, so use the router to look up the path first.
// If called from an event subscriber, the request may not have the route
// object yet (it is still being built), so use the router to look up
// based on the path.
if (!$route_object = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT)) {
$attributes = $this->router->match('/' . urldecode(trim($request->getPathInfo(), '/')));
try {
// Process the path as an inbound path. This will remove any language
// prefixes and other path components that inbound processing would
// clear out, so we can attempt to load the route clearly.
$path = $this->pathProcessorManager->processInbound(urldecode(trim($request->getPathInfo(), '/')), $request);
$attributes = $this->router->match('/' . $path);
}
catch (ResourceNotFoundException $e) {
return FALSE;
}
$route_object = $attributes[RouteObjectInterface::ROUTE_OBJECT];
}
$result = $this->adminContext->isAdminRoute($route_object);
......
......@@ -36,7 +36,7 @@ class UserAdminLanguageTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('user', 'language');
public static $modules = array('user', 'language', 'language_test');
public function setUp() {
parent::setUp();
......@@ -105,17 +105,60 @@ function testUserAdminLanguageConfigurationAvailableIfAdminLanguageNegotiationIs
$this->assertNoFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector not available for regular user.');
}
/**
* Tests the actual language negotiation.
*/
function testActualNegotiation() {
$this->drupalLogin($this->adminUser);
$this->addCustomLanguage();
$this->setLanguageNegotiation();
// Even though we have admin language negotiation, so long as the user has
// no preference set, negotiation will fall back further.
$path = 'user/' . $this->adminUser->id() . '/edit';
$this->drupalGet($path);
$this->assertText('Language negotiation method: language-default');
// Set a preferred language code for the user.
$path = 'user/' . $this->adminUser->id() . '/edit';
$edit = array();
$edit['preferred_admin_langcode'] = 'xx';
$this->drupalPostForm($path, $edit, t('Save'));
// Test negotiation with the URL method first. The admin method will only
// be used if the URL method did not match.
$path = 'user/' . $this->adminUser->id() . '/edit';
$this->drupalGet($path);
$this->assertText('Language negotiation method: language-user-admin');
$path = 'xx/user/' . $this->adminUser->id() . '/edit';
$this->drupalGet($path);
$this->assertText('Language negotiation method: language-url');
// Test negotiation with the admin language method first. The admin method
// will be used at all times.
$this->setLanguageNegotiation(TRUE);
$path = 'user/' . $this->adminUser->id() . '/edit';
$this->drupalGet($path);
$this->assertText('Language negotiation method: language-user-admin');
$path = 'xx/user/' . $this->adminUser->id() . '/edit';
$this->drupalGet($path);
$this->assertText('Language negotiation method: language-user-admin');
}
/**
* Sets the User interface negotiation detection method.
*
* @param bool $admin_first
* Whether the admin negotiation should be first.
*
* Enables the "Account preference for administration pages" language
* detection method for the User interface language negotiation type.
*/
function setLanguageNegotiation() {
function setLanguageNegotiation($admin_first = FALSE) {
$edit = array(
'language_interface[enabled][language-user-admin]' => TRUE,
'language_interface[enabled][language-url]' => TRUE,
'language_interface[weight][language-user-admin]' => -8,
'language_interface[weight][language-user-admin]' => ($admin_first ? -12 : -8),
'language_interface[weight][language-url]' => -10,
);
$this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
......
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